我正在构建一个由未指定数量的子组件组成的 Vue 组件。只有一个子组件始终可见,并且只有当当前可见的子组件发出事件时,用户才能在子组件之间进行切换is-valid
。
我想保持这种解耦,这样孩子们就不知道他们的父母,只能通过发出事件进行通信。这也意味着子组件不知道他们在父组件中的位置。
因此,父组件必须以某种方式跟踪事件来自哪个子组件。如果事件来自右侧子级(当前可见的),则会激活一些按钮,允许用户转到下一个或上一个子级。
到目前为止,这是我的代码:
超文本标记语言
<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>
Run Code Online (Sandbox Code Playgroud)
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'
});
Run Code Online (Sandbox Code Playgroud)
当然,我可以在子事件绑定上硬编码索引:
<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>
Run Code Online (Sandbox Code Playgroud)
但这会使整个设置的模块化程度降低很多,我只想能够在 DOM 中插入一些子元素并使其立即工作。
我查看了 Vue 事件的 API,似乎没有办法从事件对象获取源。
这取决于您想要收到的内容,我个人的偏好是传入 aprop
来设置唯一的 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>
Run Code Online (Sandbox Code Playgroud)
然后,在您的子组件中,您可以创建emit
一个具有状态和 id 的对象id
:
孩子:
this.$emit('newstate', {id: this.id, state: valid});
Run Code Online (Sandbox Code Playgroud)
家长:
newchildstate: function (valid) {
console.log('valid:' + valid.state + ', from' + valid.id);
}
Run Code Online (Sandbox Code Playgroud)
我意识到这看起来与您的硬编码示例没有太大不同,但在某些时候您parent
会想要处理,因此您可以使用初始状态event
设置一个数组,然后使用:data
v-for
data: {
children: [true, false, false] // setup states
}
Run Code Online (Sandbox Code Playgroud)
然后你会这样做:
<div v-for="(state, index) in states">
<m-child v-on:newstate="newchildstate" :id="index"></m-child>
</div>
Run Code Online (Sandbox Code Playgroud)
在你的视图模型中:
methods: {
newchildstate: function(valid) {
this.$set(this.states, valid.id, valid.state);
}
}
Run Code Online (Sandbox Code Playgroud)
这是一个 JSFiddle,它通过 prop 动态启动数组并设置子组件: https: //jsfiddle.net/2y9727e2/
归档时间: |
|
查看次数: |
4446 次 |
最近记录: |