IT이야기

Vue.js의 커스텀 디렉티브에서 클릭 이벤트를 캡처하려면 어떻게 해야 합니까?

cyworld 2022. 5. 30. 22:04
반응형

Vue.js의 커스텀 디렉티브에서 클릭 이벤트를 캡처하려면 어떻게 해야 합니까?

저는 Vue.js를 배우려고 하고 있는데, 이 'v-on'을 사용하는 커스텀 디렉티브를 실장해야 하는 프랙티스의 예를 들었습니다.즉, 커스텀 디렉티브에서 클릭이벤트를 캡처하여 메서드를 호출해야 합니다.

내가 생각하고 있던 템플릿.

<template>
    <h1 v-my-on:click="alertMe">Click</h1>
</template>

문제는 클릭 이벤트를 커스텀 디렉티브에 캡처하는 방법을 모른다는 것입니다.아래의 서투른 코드를 양해해 주십시오.

<script>
    export default {
        methods: {
            alertMe() {
                alert('The Alert!');
            }
        },
        directives: {
            'my-on': {
                bind(el, binding, vnode) {
                    console.log('bind');

                    el.addEventListener('click',()=>{
                        console.log('bind');
                        vnode.context.$emit('click');
                    });
                },

            }
        }
    }
</script>

이게 어떻게 작동하는지 아는 사람 있나요?나는 비슷한 것의 예를 찾을 수 없었다.

몇 번 더 찾아본 결과, 다음과 같은 해결책을 찾았습니다.


<template>
  <h1 v-my-on:click="alertMe">Click me!</h1>
</template>

<script>

  export default {

    methods: {

      alertMe() {

        alert('The Alert!');

      }

    },

    directives: {

      'my-on': {

        // Add Event Listener on mounted.
        bind(el, binding) {
          el.addEventListener(binding.arg, binding.value);
        },

        // Remove Event Listener on destroy.
        unbind(el, binding) {
          el.removeEventListener(binding.arg, binding.value);
        }

      }

    }

  }
</script>

찾으시는 솔루션은 제가 알기로는 가장 적합한 솔루션입니다.하지만 Vue에 대해 잘 모르시는 분들을 위해서.JS 제가 간단하게 설명을 해드릴게요.또한 Custom Directives 공식 Vue 설명서 또는 개념에 대한 My Medium 문서를 참조하십시오.

이것은 Vlad가 온 코드이며, 저는 다음과 같이 지원합니다.

<template>
    <h1 v-my-on:click="alertMe">Click me!</h1>
</template>

<script>
    export default {
        methods: {
            alertMe() {
                alert('The Alert!');
            }
        },
        directives: {
            'my-on': {
                bind(el, binding) {
                    let type = binding.arg;
                    let myFunction = binding.value;
                    el.addEventListener(type, myFunction);
                }
            }
        }
    }
</script>

즉, Vue Directives는 지시적 객체 정의에 따라 연결된 요소의 라이프사이클에 호출됩니다.이 예에서 정의된 함수는 "바인드"라고 불리기 때문에 요소가 DOM에 바인딩되면 디렉티브가 해당 함수를 호출합니다.

이 함수는 "el"에 연결된 요소와 "binding" 템플릿의 지시어 사용의 다른 내용을 수신합니다.템플릿의 바인딩 사용에서 콜론 ":" 뒤의 값은 "arg"이며, 이 예에서는 문자열 리터럴 "click"입니다.따옴표 '"' 안에 있는 값은 "값"이며, 이 경우 "alertMe" 함수에 대한 객체 참조입니다.

binding.arg 및 binding.value(각각의 내용 포함)를 취득하여 정의된 값을 사용하여 디렉티브가 사용되는 요소 "el" 내에 포함된 이벤트청취자를 작성할 수 있습니다(el은 수정 가능).요소가 생성되어 바인딩되면 이 새로운 이벤트청취자는 "arg"에 의해 정의된 "click" 이벤트에 생성되고 "value"에 의해 정의된 "alertMe" 함수를 호출합니다.

수정은 요소 내부에 포함되어 있기 때문에 요소가 파괴되면 청취자가 파괴되므로 언바인드 시 청소할 필요가 없습니다.

그리고 그것이 제안된 코드에서 일어나고 있는 일의 기본적인 설명입니다.지침 및 사용 방법에 대한 자세한 내용은 권장 링크를 참조하십시오.그게 도움이 됐으면 좋겠네요!

지시문 내에서 발신되는 이벤트에 대해 청취자를 등록해야 합니다.

// emit a custom event
// binding.expression is alertMe
vnode.context.$emit(binding.expression);

// listen for the event 
export default {
    created(){
        this.$on('alertMe', event => { 
            this.alertMe()
        })
    },
    ....
}

메서드를 호출하지 않습니다.alertMe, 다소 지나치다alertMe바인딩 표현으로서 디렉티브를 통과시킵니다.

<h1 v-my-on:click="alertMe">Click</h1>

@Vlad는 뛰어난 솔루션을 가지고 있다!

또한 중요한 점을 추가해도 될까요?콜백에 파라미터를 전달하고 싶은 경우 Vue가 식을 처리하는 방법에 따라 혼란이 생깁니다.즉, 사용자 지정 디렉티브의 경우 따옴표 사이의 내용이 평가되고 결과 값이 전달됩니다(따라서 binding.value(duh!)를 통해 얻을 수 있음). 기본 제공 디렉티브의 경우 적어도 v-on의 경우 따옴표 사이의 내용이 나중에 이벤트가 발생할 때 평가됩니다.

사용자 지정 지시문과 기본 제공 v-on 지시문을 비교하여 가장 잘 설명할 수 있습니다. @Vlad가 수행하는 것과 동일하게 "my-on" 지시문이 작성되어 v-on과 함께 사용한다고 가정해 보십시오.

내장:<h1 v-on:click="myAlert('haha')"> Click me!</h1>

예상대로 작동하며 버튼을 클릭하면 알림 창이 나타납니다.

커스터마이즈:<h1 v-my-on:click="myAlert('haha')">Click me!</h1>

버튼이 표시되자마자 경보창이 뜨고 클릭하면 이벤트가 발생하지만 아무것도 표시되지 않습니다.이는 "myAlert('haha')"가 바인딩(?)과 동시에 평가되기 때문에 경보창이 열리고 그 값이 디렉티브(정의되지 않았거나)로 전달되기 때문입니다.이 값은 함수가 아니기 때문에 아무 일도 일어나지 않는 것 같습니다.이 문제를 해결하려면 따옴표 사이에 있는 모든 항목이 평가 시 함수를 반환하도록 해야 합니다(예: v-my-on:click="() => {myAlert('haha'}"

도움이 됐으면 좋겠다.

참고 자료:

https://stackoverflow.com/a/61734142/1356473

https://github.com/vuejs/vue/issues/5588

@Vlad가 나에게 효과가 있었다고 말한 것처럼:

                    el.addEventListener('click',()=>{
                    console.log('bind');
                    vnode.context.$emit('click');

제 지시는 다음과 같습니다.

Vue.directive('showMenu', {
    bind: function (el, binding, vnode) {
        el.addEventListener('click', () => {
            console.log('bind')
            setTimeout(() => {
                this.$emit('toggleDrawer')
            }, 1000)
        })
    }
})

고마워, 친구!

언급URL : https://stackoverflow.com/questions/48486116/how-can-i-capture-click-event-on-custom-directive-on-vue-js

반응형