Vue.js 如何在vuejs中除当前组件外的所有同级组件中触发事件?

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

我有一个可重用的组件,可以对数据进行内联编辑

所以一个页面有10个字段可以内联编辑

<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'],
方法:{
行动