【问题标题】:How to catch events across multiple child Vue components如何跨多个子 Vue 组件捕获事件
【发布时间】:2017-01-16 15:05:22
【问题描述】:

我正在vue中构建一个表单框架。我有每个字段类型的组件。每个字段类型组件都使用 this.$emit 与父组件通信更改。

我可以使用 v-on 指令在父组件中触发事件,如下所示:

<template>
<div v-if="fieldsLoaded">
    <form-select :field="fields.title" v-on:updated="validate" ></form-select>
    <form-input :field="fields.first_name" v-on:updated="validate" ></form-input>
</div>
</template>

但是,我不想手动指定每个组件都应该单独触发validate 方法。

如何让父组件在其所有子组件中监听 updated 发射?

编辑:我正在寻找类似下面的内容,尽管 $on 仅捕获发生在同一组件内的发射,而不是其子组件

created: function(){
    this.$on('updated',validate)
}

【问题讨论】:

    标签: vue.js


    【解决方案1】:

    最好的方法是使用event bus,或者在我看来更好的vuex

    第一种情况看here

    第二个here

    使用event bus,您可以发出一个事件,并在您想要的任何时候收听该事件(在父级、子级,甚至在同一个组件中)

    Vuex It serves as a centralized store for all the components in an application 你可以在那个 store 中拥有属性,你可以使用和操作它们。

    事件总线示例:

    ma​​in.js:

    import Vue from 'vue'
    import App from './App.vue'
    
    export const eventBus = new Vue();
    
    new Vue({
      el: '#app',
      render: h => h(App)
    })
    

    用户组件

    <template>
      <button @click="clicked">Click me to create event</button>
    </template>
    <script>
        import { eventBus } from './main'
        export default {
        name: 'User',
        methods: {
            clicked() {
            eventBus.$emit('customEvent', 'a text to pass')
          }
        }
      }
    </script>
    

    管理组件

    <template>
     <p>The message from event is: {{message}}</p>
    </template>
    <script>
        import { eventBus } from './main'
        export default {
        name: 'Admin',
        data: () => ({
            message: ''
        })
        created() {
            eventBus.$on('customEvent', dataPassed => {
            this.message = dataPassed
          }
        }
      }
    </script>
    

    this教程学习Vuex

    【讨论】:

      【解决方案2】:

      对于您的情况,您可以使用 v-model,如下所示:

      <template>
      <div v-if="fieldsLoaded">
          <form-select v-model="fields.title" :validate="validate" ></form-select>
          <form-input v-model="fields.first_name" :validate="validate" ></form-input>
      </div>
      </template>
      

      v-model 本质上是用于更新用户输入事件数据的语法糖。

      <input v-model="something">
      

      只是语法糖:

      <input v-bind:value="something" v-on:input="something = $event.target.value">
      

      您可以在子组件中传递一个 prop : value,并在更改输入字段之前调用一个函数来验证它也作为一个 prop 传递。

      Vue.component('form-select', {
        props: ['options', 'value', 'onChange', 'validate'],  //Added one more prop
        template: '#your-template',
        mounted: function () {
        },
        methods: {
          change (opt) {
            if (this.validate !== undefined) {
              var isValid = this.validate(this.value)
              if(!isValid) return;
            }
            this.$emit('input', opt)
          },
        },
      })
      

      【讨论】:

      • 您正在引用 this.validate() 但这不需要在此子组件中定义 validate 方法吗?我的意图是将验证逻辑保留在父组件中,以便在各个子组件之间共享。
      • 对不起,我刚刚明白你的意思——你是说我可以从父级传递验证方法。我想这会起作用,但它不会减少我的代码。我已经让它像我原来的例子一样工作了,我在每个字段的父级中显式地触发了 validate 方法。我的目标是通用的东西,它可以捕获 所有 来自其子级的 validate 发射,而无需逐个字段地使其显式。
      • @rhoward 通过我的方法,您可以在这些组件中移动与错误消息等相关的显示代码。关于你关于重用代码的观点,你可以看mixins,在那里你可以尝试把通用功能放在组件中重用。
      猜你喜欢
      • 2018-07-03
      • 2022-11-23
      • 2022-12-05
      • 2021-07-18
      • 1970-01-01
      • 2015-06-23
      • 2019-03-01
      • 2019-02-20
      • 1970-01-01
      相关资源
      最近更新 更多