我有一个可重用的组件,可以对数据进行内联编辑。
因此页面有10个可以内联编辑的字段,
<editfield :value="field" v-for="field in fieldslist"></editfield>
每个人都有一个名为&#34;编辑&#34;的数据字段。用户点击时设置为true
或false
。每次将字段设置为编辑时,都会使用事件总线发出事件editing-another-field
。
edit(){
this.editing = true;
EventBus.$emit('editing-another-field');
}
我在创建组件时添加了事件监听器
created(){
EventBus.$on('editing-another-field', ()=>{ this.editing = false;});
}
我面临的问题是它即使在正在编辑的电流组件中也会触发事件。
如何在除当前组件之外的所有其他同级组件中提及editing
的更新值。
答案 0 :(得分:3)
为什么不将当前组件作为事件参数传递,并使用它来检查事件是源自此组件还是来自另一个组件。
edit() {
this.editing = true;
EventBus.$emit('editing-another-field', this);
}
created() {
EventBus.$on('editing-another-field', source => {
if (source !== this) {
this.editing = false;
}
});
}
或者您可以这样做(在销毁组件时取消注册事件侦听器以避免内存泄漏非常重要):
edit() {
EventBus.$emit('editing-field', this);
}
created() {
this.editingFieldHandler = vm => {
this.editing = vm === this;
};
EventBus.$on('editing-field', this.editingFieldHandler);
}
destroyed() {
EventBus.$off('editing-field', this.editingFieldHandler);
}
否则,您可以先发出事件,然后将this.editing
设置为true。
答案 1 :(得分:0)
你确定要一辆活动巴士吗?这给JQuery留下了不好的回忆;-)我认为将自己限制在父母和孩子的树上会更加清晰。思考MVVM,formLockedBy
是一个完全有效且明智的属性,可以存储在父母身上并传递给孩子们。
下面的解决方案running here显示了一个包含两个字段的表单。这些字段都是modal-component
的实例。父管理formLockedBy
属性。子字段查看此属性以了解禁用自身。当用户开始键入字段时,该字段会发出editing
个事件并设置formLockedBy
。同样,当字段发出save
或cancel
事件时,父级会清除formLockedBy
,其他输入会恢复生命。
注意优点......
formLockedBy
中存储的标识符只是字段的字符串名称。这比传递和存储对Vue组件的引用更安全。如果您不喜欢这样,可以考虑adding a safe id到对象proto。props
中指定父母需要的一切。<强> HTML 强>
<div id="example">
<modal-input name='First Name'
:form-locked-by='this.formLockedBy'
v-on:save='formLockedBy = null'
v-on:cancel='formLockedBy = null'
v-on:editing='fieldActive'
></modal-input>
<modal-input name='Address'
:form-locked-by='this.formLockedBy'
v-on:save='formLockedBy = null'
v-on:cancel='formLockedBy = null'
v-on:editing='fieldActive'
></modal-input>
</div>
<强> JS 强>
Vue.component('modal-input', {
template: `<div>
{{name}} :
<input :name='name' type="text" v-on:keydown="active" :disabled="formLockedBy && formLockedBy != name"/>
<span v-if="editing && formLockedBy == name">
<input type="button" value="Save" v-on:click="$emit('save');editing=false;"></input>
<input type="button" value="Cancel" v-on:click="$emit('cancel');editing=false;"></input>
</span>
</div>`,
data : function(){
return {editing:false};
},
props: ['name','formLockedBy'],
methods : {
active : function(event){
if(!this.editing){
this.editing = true;
this.$emit('editing',{field:this.name})
}
return true;
}
}
});
// create a root instance
new Vue({
el: '#example',
data: {
formLockedBy : null
},
methods : {
fieldActive : function(args){
this.formLockedBy = args.field;
}
}
})