简体   繁体   English

Vue.JS 发出原生 DOM 事件

[英]Vue.JS emit native DOM events

I have a custom checkbox component, which is composed by a classic checkbox and a label.我有一个自定义复选框组件,它由一个经典复选框和一个 label 组成。 You are able to click either the checkbox or the label to toggle the state.您可以单击复选框或 label 来切换 state。

在此处输入图像描述

I want to emit a native onchange event , so I can do a v-on listener on a distant div grandparent.我想发出一个原生onchange 事件,所以我可以在一个遥远的 div 祖父母上做一个v-on监听器。 The input I use for the actual checkbox is properly emitting a native onchange event, but I'm unable to manually emit a bubbling native onchange event when the label is clicked.我用于实际复选框的输入正确地发出了本机onchange事件,但是当单击 label 时,我无法手动发出冒泡的本机onchange事件。 I've tried this.$emit('change') and this.$emit('onchange') , neither which bubble like the native DOM event would.我已经尝试过this.$emit('change')this.$emit('onchange') ,它们都不像原生 DOM 事件那样冒泡。

Here is a simple example:这是一个简单的例子:

<!-- Form.vue -->

<div id="form-1" @change="markDirty()">
  <div class="header">
    <CustomButton>Submit</CustomButton>
    <CustomButton>Cancel</CustomButton>
  </div>
  <div class="form-body">
    <div class="form-region">
      <CustomCheckBox :checked.sync='tryChecked'>Try checking me!</CustomCheckBox>
    </div>
  </div>
</div>
<!-- CustomCheckBox.vue -->

<template>
  <div class="custom-checkbox">
    <input type="checkbox" v-on:change="selectCheckbox" />
    <label v-on:click="selectCheckbox">
        <slot></slot>
    </label>
  </div>
</template>

<script>
export default {
    name: 'CustomCheckBox',
    props: {
        checked: {
            type: Boolean,
            required: true
        }
    },
    methods: {
        selectCheckbox() {
            this.$emit('update:checked', !this.checked)
            this.$emit('change')
        }
    }
}
</script>

I would like to be able to tell when any element in my form has changed via onchange bubbling, so I can set a dirty flag.我希望能够通过onchange冒泡来判断表单中的任何元素何时发生变化,这样我就可以设置一个脏标志。 This example would be fine if I only had native buttons and checkboxes, as they emit native onchange events.如果我只有原生按钮和复选框,这个例子会很好,因为它们会发出原生onchange事件。 With my CustomCheckBox , it bubbles when I click the actual native checkbox, but the label does not.使用我的CustomCheckBox ,当我单击实际的本机复选框时它会冒泡,但 label 不会。

Is this possible in Vue?这在Vue中可能吗? If not, what's the best way to do this with native Javascript?如果没有,使用本机 Javascript 执行此操作的最佳方法是什么?

Events emitted by Vue do not bubble like native events do. Vue 发出的事件不会像原生事件那样冒泡。 You need to handle the emitted event right in the parent component or utilize state, as shown here: How to bubble events on a component subcomponent chain with Vue js 2?您需要直接在父组件中处理发出的事件或使用 state,如下所示: 如何使用 Vue js 2 在组件子组件链上冒泡事件?

You could either "bubble" the event using v-on handlers in every subsequent parent component, passing the event on "manually", use state via a bus as described in the source mentioned above or via vuex .您可以在每个后续父组件中使用v-on处理程序“冒泡”事件,“手动”传递事件,通过上述源中描述的bus或通过 vuex 使用vuex

Using vanilla js would be a suboptimal solution here as you would need to set the event handler in the grandparent component directly, which would mean accessing a DOM element rendered in a child component.在这里使用 vanilla js 将不是最佳解决方案,因为您需要直接在祖父组件中设置事件处理程序,这意味着访问在子组件中呈现的 DOM 元素。 While this is possible, it creates interdependence among the components and should therefore be avoided when possible.虽然这是可能的,但它会在组件之间造成相互依赖,因此应尽可能避免。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM