Vue.JS 发出原生 DOM 事件 [英] Vue.JS emit native DOM events

查看:35
本文介绍了Vue.JS 发出原生 DOM 事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义复选框组件,它由一个经典的复选框和一个标签组成.您可以单击复选框或标签来切换状态.

我想发出一个原生的 onchange 事件,所以我可以在遥远的 div 祖父母上做一个 v-on 监听器.我用于实际复选框的输入正确地发出本机 onchange 事件,但我无法在单击标签时手动发出冒泡本机 onchange 事件.我试过 this.$emit('change')this.$emit('onchange'),都没有像原生 DOM 事件那样冒泡.>

这是一个简单的例子:

<div id="form-1";@change="markDirty()"><div class="header"><CustomButton>提交</CustomButton><CustomButton>取消</CustomButton>

<div class="form-b​​ody"><div class="form-region"><CustomCheckBox :checked.sync='tryChecked'>试试看我!</CustomCheckBox>

<模板><div class="custom-checkbox"><输入类型=复选框"v-on:change="selectCheckbox"/><label v-on:click="selectCheckbox"><插槽></插槽>

</模板><脚本>导出默认{name: 'CustomCheckBox',道具: {检查:{类型:布尔型,要求:真实}},方法: {选择复选框(){this.$emit('update:checked', !this.checked)this.$emit('change')}}}

我希望能够通过 onchange 冒泡来判断表单中的任何元素何时发生更改,以便我可以设置一个脏标志.如果我只有本机按钮和复选框,这个例子就可以了,因为它们会发出本机 onchange 事件.使用我的 CustomCheckBox,当我单击实际的本机复选框时它会冒泡,但标签不会.

这在 Vue 中可行吗?如果没有,使用原生 Javascript 执行此操作的最佳方法是什么?

解决方案

Vue 发出的事件不像原生事件那样冒泡.您需要在父组件中处理发出的事件或利用状态,如下所示:如何使用 Vue js 2 在组件子组件链上冒泡事件?

你可以冒泡"在每个后续父组件中使用 v-on 处理程序的事件,在手动"上传递事件,通过 bus 使用状态,如上述来源中所述或通过vuex.

在这里使用 vanilla js 将是一个次优的解决方案,因为您需要直接在祖父组件中设置事件处理程序,这意味着访问在子组件中呈现的 DOM 元素.虽然这是可能的,但它会造成组件之间的相互依赖,因此应尽可能避免.

I have a custom checkbox component, which is composed by a classic checkbox and a label. You are able to click either the checkbox or the label to toggle the state.

I want to emit a native onchange event, so I can do a v-on listener on a distant div grandparent. 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. I've tried this.$emit('change') and this.$emit('onchange'), neither which bubble like the native DOM event would.

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. This example would be fine if I only had native buttons and checkboxes, as they emit native onchange events. With my CustomCheckBox, it bubbles when I click the actual native checkbox, but the label does not.

Is this possible in Vue? If not, what's the best way to do this with native Javascript?

解决方案

Events emitted by Vue do not bubble like native events do. 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?

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.

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. While this is possible, it creates interdependence among the components and should therefore be avoided when possible.

这篇关于Vue.JS 发出原生 DOM 事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆