요소 외부 클릭 감지


121

요소 외부에서 클릭을 감지하려면 어떻게해야합니까? Vue.js를 사용하고 있으므로 템플릿 요소 외부에 있습니다. Vanilla JS에서 수행하는 방법을 알고 있지만 Vue.js를 사용할 때 더 적절한 방법이 있는지 잘 모르겠습니다.

이것은 Vanilla JS의 솔루션 입니다. div 외부의 Javascript Detect Click 이벤트

요소에 액세스하는 더 나은 방법을 사용할 수 있습니까?


Vue 구성 요소는 격리되어 있습니다. 따라서 외부 변화를 감지하는 것은 의문의 여지가 없으며 안티 패턴이 사용됩니다.
— 라즈 카말

감사. Vue 구성 요소에서 구현하는 방법을 잘 모르겠습니다. 안티 패턴에 대한 몇 가지 모범 사례가 여전히 있어야합니까?

Vue.js 구성 요소는 격리되어 있습니다. 사실이지만 부모-자식 통신에는 다른 방법이 있습니다. 그래서 그 대신 요소의 이벤트 외부를 감지 묻는 당신은 어떤 아이에서 상위 구성 요소에서 구성 요소의 내부 요소를 감지하려는 경우, 당신은 지정해야합니다, 또는 어떤 관계가 구성 요소 사이
— Yerko 팔마

피드백 감사드립니다. 후속 조치를 취할 수있는 몇 가지 예나 링크가 있습니까?

github.com/simplesmiler/vue-clickaway는 작업 단순화 할 수 있습니다
— 라즈 카말

답변:


97

사용자 지정 지시문을 한 번 설정하면 멋지게 해결할 수 있습니다.

Vue.directive('click-outside', {
  bind () {
      this.event = event => this.vm.$emit(this.expression, event)
      this.el.addEventListener('click', this.stopProp)
      document.body.addEventListener('click', this.event)
  },   
  unbind() {
    this.el.removeEventListener('click', this.stopProp)
    document.body.removeEventListener('click', this.event)
  },

  stopProp(event) { event.stopPropagation() }
})

용법:

<div v-click-outside="nameOfCustomEventToCall">
  Some content
</div>

구성 요소에서 :

events: {
  nameOfCustomEventToCall: function (event) {
    // do something - probably hide the dropdown menu / modal etc.
  }
}

경고에 대한 추가 정보가 포함 된 JSFiddle의 작업 데모 :

https://jsfiddle.net/Linusborg/yzm8t8jq/


3
나는 vue clickaway를 사용했지만 귀하의 솔루션은 다소 동일하다고 생각합니다. 감사.

56
이 접근 방식은 Vue.js 2에서 더 이상 작동하지 않습니다. self.vm. $ emit 호출은 오류 메시지를 제공합니다.
— northernman

3
@blur를 사용하는 것도 옵션이며 동일한 결과를 더 쉽게 제공 할 수 있습니다. <input @ blur = "hide"> where hide : function () {this.isActive = false; }
— Craws

1
대답은 Vue.js 1
— Stéphane Gerber

167

Linus Borg 답변을 기반으로하고 vue.js 2.0에서 잘 작동하는 내가 사용한 솔루션이 있습니다.

Vue.directive('click-outside', {
  bind: function (el, binding, vnode) {
    el.clickOutsideEvent = function (event) {
      // here I check that click was outside the el and his children
      if (!(el == event.target || el.contains(event.target))) {
        // and if it did, call method provided in attribute value
        vnode.context[binding.expression](event);
      }
    };
    document.body.addEventListener('click', el.clickOutsideEvent)
  },
  unbind: function (el) {
    document.body.removeEventListener('click', el.clickOutsideEvent)
  },
});

다음을 사용하여 바인딩합니다 v-click-outside.

<div v-click-outside="doStuff">

다음은 작은 데모입니다.

https://vuejs.org/v2/guide/custom-directive.html#Directive-Hook-Arguments 에서 사용자 지정 지시문과 el, binding, vnode의 의미에 대한 자세한 정보를 찾을 수 있습니다.


8
작동했지만 Vue 2.0 지시문에는 더 이상 인스턴스가 없으므로 정의되지 않았습니다. vuejs.org/v2/guide/migration.html#Custom-Directives-simplified . 이 바이올린이 작동하는 이유 또는 단순화가 언제 완료되었는지 전혀 알 수 없습니다. (해결하려면 "this"를 "el"로
— 바꾸어

1
창이 "this"로 전달 되었기 때문에 작동합니다. 나는 답을 고쳤다. 이 버그를 지적 해 주셔서 감사합니다.
— MadisonTrash

8
외부에서 특정 요소를 제외하는 방법이 있습니까? 예를 들어 외부에이 요소를 열어야하는 버튼이 하나 있는데 두 메서드를 모두 트리거하기 때문에 아무 일도 일어나지 않습니다.
— Žilvinas

5
vnode.context [binding.expression] (event); 설명해 주시겠습니까? ?
— Sainath SR

1
v-click-outside 내에서 메서드 대신 표현식을 사용할 수 있도록 변경하는 방법은 무엇입니까?
— raphadko

50

tabindex집중할 수 있도록 구성 요소에 속성을 추가 하고 다음을 수행합니다.

<template>
    <div
        @focus="handleFocus"
        @focusout="handleFocusOut"
        tabindex="0"
    >
      SOME CONTENT HERE
    </div>
</template>

<script>
export default {    
    methods: {
        handleFocus() {
            // do something here
        },
        handleFocusOut() {
            // do something here
        }
    }
}
</script>

4
우와! 나는 이것이 가장 짧고 가장 깨끗한 해결책이라고 생각합니다. 또한 내 경우에 일한 유일한 사람입니다.
— Matt Komarnicki

3
여기에 추가하기 위해 tabindex를 -1로 설정하면 요소를 클릭 할 때 강조 상자가 나타나지 않지만 div에 초점을 맞출 수 있습니다.
— Colin

1
어떤 이유로 -1의 tabindex는 윤곽선을 숨기지 않으므로 outline: none;요소에 초점을 추가 했습니다.
— Art3mix

1
화면에 슬라이드하는 오프 캔버스 측면 탐색에 이것을 어떻게 적용 할 수 있습니까? 그것을 클릭하지 않는 한 나는 sidenav 포커스를 드릴 수 없습니다,
— 찰스 Okwuagwu

1
이것은 절대적으로 가장 강력한 방법입니다. 감사합니다! :)
— Canet Robern

23

이 작업을 위해 커뮤니티에서 두 가지 패키지를 사용할 수 있습니다 (둘 다 유지 관리 됨).


8
vue-clickaway패키지가 내 문제를 완벽하게 해결했습니다. 감사합니다
— Abdalla Arbab

1
많은 항목은 어떻습니까? 외부 클릭 이벤트가있는 모든 항목은 클릭 할 때마다 이벤트를 발생시킵니다. 대화를 할 때 좋고 갤러리를 만들 때 끔찍합니다. 비 컴포넌트 시대에 우리는 문서에서 클릭을 듣고 어떤 요소가 클릭되었는지 확인합니다. 하지만 지금은 고통 스럽습니다.
— br.

@Julien Le Coupanec 저는이 솔루션이 지금까지 최고임을 발견했습니다! 공유 해주셔서 감사합니다!
— Manuel Abascal

7

이것은 Vue.js 2.5.2에서 나를 위해 일했습니다.

/**
 * Call a function when a click is detected outside of the
 * current DOM node ( AND its children )
 *
 * Example :
 *
 * <template>
 *   <div v-click-outside="onClickOutside">Hello</div>
 * </template>
 *
 * <script>
 * import clickOutside from '../../../../directives/clickOutside'
 * export default {
 *   directives: {
 *     clickOutside
 *   },
 *   data () {
 *     return {
         showDatePicker: false
 *     }
 *   },
 *   methods: {
 *     onClickOutside (event) {
 *       this.showDatePicker = false
 *     }
 *   }
 * }
 * </script>
 */
export default {
  bind: function (el, binding, vNode) {
    el.__vueClickOutside__ = event => {
      if (!el.contains(event.target)) {
        // call method provided in v-click-outside value
        vNode.context[binding.expression](event)
        event.stopPropagation()
      }
    }
    document.body.addEventListener('click', el.__vueClickOutside__)
  },
  unbind: function (el, binding, vNode) {
    // Remove Event Listeners
    document.removeEventListener('click', el.__vueClickOutside__)
    el.__vueClickOutside__ = null
  }
}

이 예에 감사드립니다. vue 2.6에서 이것을 확인했습니다. unbind 메서드에서 몇 가지 문제를 해결해야합니다 (unbind 메서드에서 body 속성을 잊어 버렸습니다). document.body.removeEventListener ( 'click', el .__ vueClickOutside__); 그렇지 않은 경우-모든 구성 요소 재생성 (페이지 새로 고침) 후에 여러 이벤트 리스너가 생성됩니다.
— Alexey Shabramov

7
export default {
  bind: function (el, binding, vNode) {
    // Provided expression must evaluate to a function.
    if (typeof binding.value !== 'function') {
      const compName = vNode.context.name
      let warn = `[Vue-click-outside:] provided expression '${binding.expression}' is not a function, but has to be`
      if (compName) { warn += `Found in component '${compName}'` }

      console.warn(warn)
    }
    // Define Handler and cache it on the element
    const bubble = binding.modifiers.bubble
    const handler = (e) => {
      if (bubble || (!el.contains(e.target) && el !== e.target)) {
        binding.value(e)
      }
    }
    el.__vueClickOutside__ = handler

    // add Event Listeners
    document.addEventListener('click', handler)
  },

  unbind: function (el, binding) {
    // Remove Event Listeners
    document.removeEventListener('click', el.__vueClickOutside__)
    el.__vueClickOutside__ = null

  }
}

5

나는 모든 답변 (vue-clickaway의 라인 포함)을 결합하고 나를 위해 작동하는이 솔루션을 생각해 냈습니다.

Vue.directive('click-outside', {
    bind(el, binding, vnode) {
        var vm = vnode.context;
        var callback = binding.value;

        el.clickOutsideEvent = function (event) {
            if (!(el == event.target || el.contains(event.target))) {
                return callback.call(vm, event);
            }
        };
        document.body.addEventListener('click', el.clickOutsideEvent);
    },
    unbind(el) {
        document.body.removeEventListener('click', el.clickOutsideEvent);
    }
});

구성 요소에서 사용 :

<li v-click-outside="closeSearch">
  <!-- your component here -->
</li>

아래 @MadisonTrash 답변으로 거의 같은
— retrovertigo

3

Mobile Safari를 지원하기 위해 MadisonTrash의 답변을 업데이트했습니다 ( click이벤트 가 없으므로 touchend대신 사용해야 함). 또한 모바일 장치에서 드래그하여 이벤트가 트리거되지 않도록하는 검사도 포함됩니다.

Vue.directive('click-outside', {
    bind: function (el, binding, vnode) {
        el.eventSetDrag = function () {
            el.setAttribute('data-dragging', 'yes');
        }
        el.eventClearDrag = function () {
            el.removeAttribute('data-dragging');
        }
        el.eventOnClick = function (event) {
            var dragging = el.getAttribute('data-dragging');
            // Check that the click was outside the el and its children, and wasn't a drag
            if (!(el == event.target || el.contains(event.target)) && !dragging) {
                // call method provided in attribute value
                vnode.context[binding.expression](event);
            }
        };
        document.addEventListener('touchstart', el.eventClearDrag);
        document.addEventListener('touchmove', el.eventSetDrag);
        document.addEventListener('click', el.eventOnClick);
        document.addEventListener('touchend', el.eventOnClick);
    }, unbind: function (el) {
        document.removeEventListener('touchstart', el.eventClearDrag);
        document.removeEventListener('touchmove', el.eventSetDrag);
        document.removeEventListener('click', el.eventOnClick);
        document.removeEventListener('touchend', el.eventOnClick);
        el.removeAttribute('data-dragging');
    },
});

3

이 코드를 사용합니다.

숨기기 표시 버튼

 <a @click.stop="visualSwitch()"> show hide </a>

표시 숨기기 요소

<div class="dialog-popup" v-if="visualState" @click.stop=""></div>

스크립트

data () { return {
    visualState: false,
}},
methods: {
    visualSwitch() {
        this.visualState = !this.visualState;
        if (this.visualState)
            document.addEventListener('click', this.visualState);
        else
            document.removeEventListener('click', this.visualState);
    },
},

업데이트 : 시계 제거; 전파 중지 추가


2

나는 추가 기능이 싫어서 ... 추가 vue 메서드가없는 멋진 vue 솔루션이 있습니다.

  1. HTML 요소 생성, 컨트롤 및 지시문 설정
    <p @click="popup = !popup" v-out="popup">

    <div v-if="popup">
       My awesome popup
    </div>
  1. 다음과 같은 데이터에서 변수를 만듭니다.
data:{
   popup: false,
}
  1. vue 지시문을 추가하십시오. 이것의
Vue.directive('out', {

    bind: function (el, binding, vNode) {
        const handler = (e) => {
            if (!el.contains(e.target) && el !== e.target) {
                //and here is you toggle var. thats it
                vNode.context[binding.expression] = false
            }
        }
        el.out = handler
        document.addEventListener('click', handler)
    },

    unbind: function (el, binding) {
        document.removeEventListener('click', el.out)
        el.out = null
    }
})

2

요소 외부의 클릭을 찾고 있지만 여전히 상위 요소 내에있는 경우 다음을 사용할 수 있습니다.

<div class="parent" @click.self="onParentClick">
  <div class="child"></div>
</div>

나는 이것을 모달에 사용합니다.


1

다음과 같이 클릭 이벤트에 대해 두 개의 이벤트 리스너를 등록 할 수 있습니다.

document.getElementById("some-area")
        .addEventListener("click", function(e){
        alert("You clicked on the area!");
        e.stopPropagation();// this will stop propagation of this event to upper level
     }
);

document.body.addEventListener("click", 
   function(e) {
           alert("You clicked outside the area!");
         }
);

감사. 나는 이것을 알고 있지만 Vue.js에서 이것을 수행하는 더 좋은 방법이 있어야한다고 생각합니까?

확인! :) 대답 일부 vue.js 천재하자
— saravanakumar

1
  <button 
    class="dropdown"
    @click.prevent="toggle"
    ref="toggle"
    :class="{'is-active': isActiveEl}"
  >
    Click me
  </button>

  data() {
   return {
     isActiveEl: false
   }
  }, 
  created() {
    window.addEventListener('click', this.close);
  },
  beforeDestroy() {
    window.removeEventListener('click', this.close);
  },
  methods: {
    toggle: function() {
      this.isActiveEl = !this.isActiveEl;
    },
    close(e) {
      if (!this.$refs.toggle.contains(e.target)) {
        this.isActiveEl = false;
      }
    },
  },

감사합니다. 완벽하게 작동하며 한 번만 필요한 경우 추가 라이브러리가 필요하지 않습니다
— Marian Klühspies

1

짧은 대답 : 이것은 Custom Directives로 해야합니다 .

여기에도 이것을 말하는 훌륭한 답변이 많이 있지만 내가 본 대부분의 답변은 외부 클릭을 광범위하게 사용하기 시작할 때 (특히 계층화되거나 여러 제외가있는 경우) 분해됩니다. 나는 기사를 썼다Custom Directives의 뉘앙스와 구체적으로 이것의 구현에 대해 이야기하는 매체에 를 . 모든 엣지 케이스를 포함하지는 않지만 내가 생각한 모든 것을 다룹니다.

이렇게하면 여러 바인딩, 여러 수준의 기타 요소 제외가 고려되며 처리기가 "비즈니스 논리"만 관리 할 수 ​​있습니다.

여기에 적어도 정의 부분에 대한 코드가 있습니다. 전체 설명은 기사를 확인하십시오.

var handleOutsideClick={}
const OutsideClick = {
  // this directive is run on the bind and unbind hooks
  bind (el, binding, vnode) {
    // Define the function to be called on click, filter the excludes and call the handler
    handleOutsideClick[el.id] = e => {
      e.stopPropagation()
      // extract the handler and exclude from the binding value
      const { handler, exclude } = binding.value
      // set variable to keep track of if the clicked element is in the exclude list
      let clickedOnExcludedEl = false
      // if the target element has no classes, it won't be in the exclude list skip the check
      if (e.target._prevClass !== undefined) {
        // for each exclude name check if it matches any of the target element's classes
        for (const className of exclude) {
          clickedOnExcludedEl = e.target._prevClass.includes(className)
          if (clickedOnExcludedEl) {
            break // once we have found one match, stop looking
          }
        }
      }
      // don't call the handler if our directive element contains the target element
      // or if the element was in the exclude list
      if (!(el.contains(e.target) || clickedOnExcludedEl)) {
        handler()
      }
    }
    // Register our outsideClick handler on the click/touchstart listeners
    document.addEventListener('click', handleOutsideClick[el.id])
    document.addEventListener('touchstart', handleOutsideClick[el.id])
    document.onkeydown = e => {
      //this is an option but may not work right with multiple handlers
      if (e.keyCode === 27) {
        // TODO: there are minor issues when escape is clicked right after open keeping the old target
        handleOutsideClick[el.id](e)
      }
    }
  },
  unbind () {
    // If the element that has v-outside-click is removed, unbind it from listeners
    document.removeEventListener('click', handleOutsideClick[el.id])
    document.removeEventListener('touchstart', handleOutsideClick[el.id])
    document.onkeydown = null //Note that this may not work with multiple listeners
  }
}
export default OutsideClick

1

created () 내에서 함수를 사용하여 약간 다른 방식으로 수행했습니다.

  created() {
      window.addEventListener('click', (e) => {
        if (!this.$el.contains(e.target)){
          this.showMobileNav = false
        }
      })
  },

이렇게하면 누군가가 요소 외부를 클릭하면 제 경우에는 모바일 탐색이 숨겨집니다.

도움이 되었기를 바랍니다!


1

이 질문에 대한 답변은 이미 많으며 대부분은 유사한 사용자 지정 지침 아이디어를 기반으로합니다. 이 접근 방식의 문제점은 메소드 함수를 지시문에 전달해야하고 다른 이벤트 에서처럼 코드를 직접 작성할 수 없다는 것입니다.

vue-on-clickout다른 새 패키지 를 만들었습니다 . 다음에서 확인하세요.

v-on:clickout다른 이벤트와 마찬가지로 쓸 수 있습니다. 예를 들어 다음과 같이 작성할 수 있습니다.

<div v-on:clickout="myField=value" v-on:click="myField=otherValue">...</div>

그리고 그것은 작동합니다.

최신 정보

vue-on-clickout 이제 Vue 3를 지원합니다!


0

누군가 모달 외부를 클릭 할 때 모달을 숨기는 방법을 찾고 있다면. 모달에는 일반적으로 클래스 modal-wrap또는 이름 @click="closeModal"을 지정한 래퍼가 있으므로 래퍼에 넣을 수 있습니다 . vuejs 문서에 명시된 이벤트 처리를 사용 하여 클릭 한 대상이 래퍼 또는 모달에 있는지 확인할 수 있습니다.

methods: {
  closeModal(e) {
    this.event = function(event) {
      if (event.target.className == 'modal-wrap') {
        // close modal here
        this.$store.commit("catalog/hideModal");
        document.body.removeEventListener("click", this.event);
      }
    }.bind(this);
    document.body.addEventListener("click", this.event);
  },
}
<div class="modal-wrap" @click="closeModal">
  <div class="modal">
    ...
  </div>
<div>


0

@Denis Danilenko 솔루션이 저에게 효과적입니다. 여기 제가 한 일이 있습니다. 그런데 여기서 VueJS CLI3 및 NuxtJS를 Bootstrap4와 함께 사용하고 있지만 NuxtJS없이 VueJS에서도 작동합니다.

<div
    class="dropdown ml-auto"
    :class="showDropdown ? null : 'show'">
    <a 
        href="#" 
        class="nav-link" 
        role="button" 
        id="dropdownMenuLink" 
        data-toggle="dropdown" 
        aria-haspopup="true" 
        aria-expanded="false"
        @click="showDropdown = !showDropdown"
        @blur="unfocused">
        <i class="fas fa-bars"></i>
    </a>
    <div 
        class="dropdown-menu dropdown-menu-right" 
        aria-labelledby="dropdownMenuLink"
        :class="showDropdown ? null : 'show'">
        <nuxt-link class="dropdown-item" to="/contact">Contact</nuxt-link>
        <nuxt-link class="dropdown-item" to="/faq">FAQ</nuxt-link>
    </div>
</div>
export default {
    data() {
        return {
            showDropdown: true
        }
    },
    methods: {
    unfocused() {
        this.showDropdown = !this.showDropdown;
    }
  }
}

0

지시문에서 사용자 정의 네이티브 자바 스크립트 이벤트를 생성 할 수 있습니다. node.dispatchEvent를 사용하여 노드에서 이벤트를 전달하는 지시문을 만듭니다.

let handleOutsideClick;
Vue.directive('out-click', {
    bind (el, binding, vnode) {

        handleOutsideClick = (e) => {
            e.stopPropagation()
            const handler = binding.value

            if (el.contains(e.target)) {
                el.dispatchEvent(new Event('out-click')) <-- HERE
            }
        }

        document.addEventListener('click', handleOutsideClick)
        document.addEventListener('touchstart', handleOutsideClick)
    },
    unbind () {
        document.removeEventListener('click', handleOutsideClick)
        document.removeEventListener('touchstart', handleOutsideClick)
    }
})

이렇게 사용할 수있는

h3( v-out-click @click="$emit('show')" @out-click="$emit('hide')" )

0

다음과 같이 본문 끝에 div를 만듭니다.

<div v-if="isPopup" class="outside" v-on:click="away()"></div>

.outside는 다음과 같습니다.

.outside {
  width: 100vw;
  height: 100vh;
  position: fixed;
  top: 0px;
  left: 0px;
}

그리고 away ()는 Vue 인스턴스의 메소드입니다.

away() {
 this.isPopup = false;
}

쉽고 잘 작동합니다.


0

루트 요소 내부에 여러 요소가있는 구성 요소가있는 경우 부울과 함께이 It just works ™ 솔루션을 사용할 수 있습니다 .

<template>
  <div @click="clickInside"></div>
<template>
<script>
export default {
  name: "MyComponent",
  methods: {
    clickInside() {
      this.inside = true;
      setTimeout(() => (this.inside = false), 0);
    },
    clickOutside() {
      if (this.inside) return;
      // handle outside state from here
    }
  },
  created() {
    this.__handlerRef__ = this.clickOutside.bind(this);
    document.body.addEventListener("click", this.__handlerRef__);
  },
  destroyed() {
    document.body.removeEventListener("click", this.__handlerRef__);
  },
};
</script>

0

이 패키지 사용 vue-click-outside

간단하고 신뢰할 수 있으며 현재 다른 많은 패키지에서 사용됩니다. 필요한 구성 요소에서만 패키지를 호출하여 자바 스크립트 번들 크기를 줄일 수도 있습니다 (아래 예 참조).

npm install vue-click-outside

사용법 :

<template>
  <div>
    <div v-click-outside="hide" @click="toggle">Toggle</div>
    <div v-show="opened">Popup item</div>
  </div>
</template>

<script>
import ClickOutside from 'vue-click-outside'

export default {
  data () {
    return {
      opened: false
    }
  },

  methods: {
    toggle () {
      this.opened = true
    },

    hide () {
      this.opened = false
    }
  },

  mounted () {
    // prevent click outside event with popupItem.
    this.popupItem = this.$el
  },

  // do not forget this section
  directives: {
    ClickOutside
  }
}
</script>


0

외부 클릭을 처리하는 새 구성 요소를 만들 수 있습니다.

Vue.component('click-outside', {
  created: function () {
    document.body.addEventListener('click', (e) => {
       if (!this.$el.contains(e.target)) {
            this.$emit('clickOutside');
           
        })
  },
  template: `
    <template>
        <div>
            <slot/>
        </div>
    </template>
`
})

이 구성 요소를 사용하십시오.

<template>
    <click-outside @clickOutside="console.log('Click outside Worked!')">
      <div> Your code...</div>
    </click-outside>
</template>

-1

자주 사람들은 사용자가 루트 구성 요소를 떠 났는지 알고 싶어합니다 (모든 수준 구성 요소에서 작동).

Vue({
  data: {},
  methods: {
    unfocused : function() {
      alert('good bye');
    }
  }
})
<template>
  <div tabindex="1" @blur="unfocused">Content inside</div>
</template>


-1

토글 드롭 다운 메뉴를 처리하는 솔루션이 있습니다.

export default {
data() {
  return {
    dropdownOpen: false,
  }
},
methods: {
      showDropdown() {
        console.log('clicked...')
        this.dropdownOpen = !this.dropdownOpen
        // this will control show or hide the menu
        $(document).one('click.status', (e)=> {
          this.dropdownOpen = false
        })
      },
}

-1

이 패키지를 사용하고 있습니다 : https://www.npmjs.com/package/vue-click-outside

그것은 나를 위해 잘 작동합니다

HTML :

<div class="__card-content" v-click-outside="hide" v-if="cardContentVisible">
    <div class="card-header">
        <input class="subject-input" placeholder="Subject" name=""/>
    </div>
    <div class="card-body">
        <textarea class="conversation-textarea" placeholder="Start a conversation"></textarea>
    </div>
</div>

내 스크립트 코드 :

import ClickOutside from 'vue-click-outside'
export default
{
    data(){
        return {
            cardContentVisible:false
        }
    },
    created()
    {
    },
    methods:
        {
            openCardContent()
            {
                this.cardContentVisible = true;
            }, hide () {
            this.cardContentVisible = false
                }
        },
    directives: {
            ClickOutside
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.