Vue.js 如何在vuejs中除当前组件外的所有同级组件中触发事件?
我有一个可重用的组件,可以对数据进行内联编辑 所以一个页面有10个字段可以内联编辑Vue.js 如何在vuejs中除当前组件外的所有同级组件中触发事件?,vue.js,vuejs2,Vue.js,Vuejs2,我有一个可重用的组件,可以对数据进行内联编辑 所以一个页面有10个字段可以内联编辑 <editfield :value="field" v-for="field in fieldslist"></editfield> 我在创建组件时添加了事件侦听器 created(){ EventBus.$on('editing-another-field', ()=>{ this.editing = false;}); } 我面临的问题是,即使在正在编辑的curre
<editfield :value="field" v-for="field in fieldslist"></editfield>
我在创建组件时添加了事件侦听器
created(){
EventBus.$on('editing-another-field', ()=>{ this.editing = false;});
}
我面临的问题是,即使在正在编辑的currennt组件中,它也会触发事件
我如何在除当前组件之外的所有其他同级组件中提到
编辑的更新值。为什么不将当前组件作为事件参数传递,并使用该参数检查事件是否源自此组件或其他组件
edit(){
this.editing=true;
EventBus.$emit('editing-other-field',this);
}
创建(){
EventBus.$on('editing-other-field',source=>{
如果(源!==此){
this.editing=false;
}
});
}
或者您也可以这样做(当组件被销毁时取消注册事件侦听器以避免内存泄漏非常重要):
edit(){
EventBus.$emit('editing-field',this);
}
创建(){
this.editingFieldHandler=vm=>{
this.editing=vm==this;
};
EventBus.$on('editing-field',this.editingFieldHandler);
}
销毁(){
EventBus.$off('editing-field',this.editingFieldHandler);
}
否则,您可以先发出事件,然后将此设置为true。为什么不将当前组件作为事件参数传递,并使用该参数检查事件是否源自此组件或其他组件
edit(){
this.editing=true;
EventBus.$emit('editing-other-field',this);
}
创建(){
EventBus.$on('editing-other-field',source=>{
如果(源!==此){
this.editing=false;
}
});
}
或者您也可以这样做(当组件被销毁时取消注册事件侦听器以避免内存泄漏非常重要):
edit(){
EventBus.$emit('editing-field',this);
}
创建(){
this.editingFieldHandler=vm=>{
this.editing=vm==this;
};
EventBus.$on('editing-field',this.editingFieldHandler);
}
销毁(){
EventBus.$off('editing-field',this.editingFieldHandler);
}
否则,您可以先发出事件,然后将设置为true。您确定要使用事件总线吗?这会给JQuery带来不好的记忆;-)我认为把自己限制在一棵父母和孩子的树上会更干净。考虑到MVVM,formLockedBy
是一个非常有效和合理的属性,可以存储在父级上并传递给子级
下面的解决方案显示了一个包含两个字段的表单。这些字段都是模态组件的实例。父级管理formLockedBy
属性。子字段查看此属性以了解如何禁用它们自己。当用户开始在字段中键入内容时,该字段将发出一个编辑
事件,并设置formLockedBy
。类似地,当一个字段发出保存
或取消
事件时,父项清除formLockedBy
,其他输入恢复正常
注意优点
- 只有父级侦听事件
- 存储在
formLockedBy
中的标识符只是字段的字符串名称。这比传递和存储对Vue组件的引用要安全得多。如果你不喜欢这个,你可以考虑对象PROT.
- 没有意外。父级将响应的事件的完整列表在实例化子级的标记中声明。子对象在
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;
}
}
})
Vue.component('modal-input'{
模板:`
{{name}}:
`,
数据:函数(){
返回{编辑:false};
},
道具:['name','formLockedBy'],
方法:{
活动:功能(事件){
如果(!this.editing){
this.editing=true;
this.$emit('编辑',{field:this.name})
}
返回true;
}
}
});
//创建一个根实例
新Vue({
el:“#示例”,
数据:{
formLockedBy:空
},
方法:{
fieldActive:功能(args){
this.formLockedBy=args.field;
}
}
})
您确定要使用事件总线吗?这会给JQuery带来不好的记忆;-)我认为把自己限制在一棵父母和孩子的树上会更干净。考虑到MVVM,formLockedBy
是一个非常有效和合理的属性,可以存储在父级上并传递给子级
下面的解决方案显示了一个包含两个字段的表单。这些字段都是模态组件的实例。父级管理formLockedBy
属性。子字段查看此属性以了解如何禁用它们自己。当用户开始在字段中键入内容时,该字段将发出一个编辑
事件,并设置formLockedBy
。类似地,当一个字段发出保存
或取消
事件时,父项清除formLockedBy
,其他输入恢复正常
注意优点
- 只有父级侦听事件
- 存储在
formLockedBy
中的标识符只是字段的字符串名称。这比传递和存储对Vue组件的引用要安全得多。如果你不喜欢这个,你可以考虑对象PROT.
- 没有意外。父级将响应的事件的完整列表在实例化子级的标记中声明。子对象在
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;
}
}
})
Vue.component('modal-input'{
模板:`
{{name}}:
`,
数据:函数(){
返回{编辑:false};
},
道具:['name','formLockedBy'],
方法:{
行动