【问题标题】:Getting the event source from custom events in Vue?从 Vue 中的自定义事件中获取事件源?
【发布时间】:2017-01-28 11:37:30
【问题描述】:

我正在构建一个 Vue 组件,其中包含未指定数量的子组件。始终只有一个子组件可见,用户只能在当前可见的子组件发出is-valid 事件时在子组件之间切换。

我想保持这种解耦,这样孩子们不知道他们的父母,只能通过发出事件来交流。这也意味着子组件不知道他们在父组件中的位置

因此,父组件必须以某种方式跟踪事件来自哪个子组件。如果事件来自右孩子(当前可见的那个),则激活一些按钮,允许用户转到下一个或上一个孩子。

到目前为止,这是我的代码:

HTML

<div id="app">
    <template id="m-child">
        <div>
            <button v-on:click="setstate(true)">Valid</button>
            <button v-on:click="setstate(false)">Invalid</button>
        </div>
    </template>

    <template id="m-parent">
        <div>
            <m-child v-on:newstate="newchildstate"></m-child>
            <m-child v-on:newstate="newchildstate"></m-child>
            <m-child v-on:newstate="newchildstate"></m-child>
        </div>
    </template>

    <m-parent></m-parent>
</div>

JS

Vue.component('m-child', {
    template: '#m-child',
    data: function() {
        return {};
    },
    methods: {
        setstate: function (valid) {
            this.$emit('newstate', valid);
        }
    }
});

Vue.component('m-parent', {
    template: '#m-parent',
    methods: {
        newchildstate: function (valid) {
            console.log('valid:' + valid + ', but where from?');
        }
    }
});

new Vue({
    el: '#app'
});

当然我可以在子事件绑定上硬编码一个索引:

        <m-child v-on:newstate="newchildstate(0, $event)"></m-child>
        <m-child v-on:newstate="newchildstate(1, $event)"></m-child>
        <m-child v-on:newstate="newchildstate(2, $event)"></m-child>

但这会使整个设置变得不那么模块化,我只是希望能够在 DOM 中插入许多子节点并使其立即工作。

我查看了 Vue 事件的 API,似乎没有办法从事件对象中获取源代码。

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    这取决于你想回什么,我个人的偏好是传入一个prop来设置一个唯一的id,然后传回$emit

    <m-child v-on:newstate="newchildstate" :id="1"></m-child>
    <m-child v-on:newstate="newchildstate" :id="2"></m-child>
    <m-child v-on:newstate="newchildstate" :id="3"></m-child>
    

    然后在您的子组件中,您可以emit 一个状态为id 的对象:

    孩子:

    this.$emit('newstate', {id: this.id, state: valid});
    

    家长:

    newchildstate: function (valid) {
      console.log('valid:' + valid.state + ', from' + valid.id);
    }
    

    我意识到这看起来与您的硬编码示例没有太大不同,但在某些时候您的parent 会想要处理event,因此您可以在data 中设置一个数组使用初始状态,然后使用 v-for:

    data: {
      children: [true, false, false] // setup states
    }
    

    你会这样做:

    <div v-for="(state, index) in states">
      <m-child v-on:newstate="newchildstate" :id="index"></m-child>
    </div>
    

    在你的视图模型中:

      methods: {
        newchildstate: function(valid) {
          this.$set(this.states, valid.id, valid.state);
        }
      }
    

    这是一个 JSFiddle,它通过 prop 动态启动数组并设置子组件:https://jsfiddle.net/2y9727e2/

    【讨论】:

    • 谢谢,我猜在当前的 Vue 状态下,真正的模块化方法是不可能的。也许可以在启动 DOM 时附加事件侦听器,循环通过父级的子级?
    猜你喜欢
    • 1970-01-01
    • 2017-02-25
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2022-12-09
    相关资源
    最近更新 更多