为兄弟组件的选择设置相同的值

时间:2017-08-11 18:55:05

标签: vue.js vuejs2 vue-component

使用v-for,我循环浏览一个组件。该组件适用于每个客户端。在这个组件中,每个客户端都有相同的表单,当为第一个组件(客户端1)选择一个选择值时,我想为每个客户端选择这个值。

我是否需要将数据传递给根并创建单个真值变量源?

我尝试设置基本版本:

<div id="app">
  <my-comp v-for="x in 2" v-bind:val="x"></my-comp>
</div>


Vue.component('my-comp', {
   props: ['val'],

   template: `
    <div>
        <div>
          <label>Status</label>
          <select :data-client="val" @change="statusChanged">
              <option selected="" disabled="" value="0"></option>
              <option value="xxx">Xxx</option>
              <option value="yyy">Yyy</option>
              <option value="zzz">Zzz</option>
           </select>
        </div>
    </div>
    `,

   methods: {
     statusChanged(e) {
          var client = e.target.getAttribute('data-client')
          if (client == 1) {
            alert('set same value for client 2')
          }
     }
   }
})

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

这是一个小提琴:https://jsfiddle.net/w53164t2/

1 个答案:

答案 0 :(得分:2)

我在原来的答案之后考虑了一点,并提出了一些我认为比原始问题中提供的示例小提琴更真实的东西;具体而言,如果所有选择都使用相同的源值,则很容易使所有选择反映相同的值,但是我希望在现实世界场景中,每个组件将独立地绑定到单个客户端。每个客户都希望他们的个人价值发生变化,但有一点需要注意,如果“主”客户端发生变化,那么所有非主客户端都应该更改为主客户端的价值。

为此,我认为特定于组件的总线是合适的。当它的值发生变化时,主机会发出一个事件,其他客户端会根据主机设置它们的值。

console.clear()

const MyCompBus = new Vue()

Vue.component('my-comp', {
  props: ['val', 'master'],
  computed:{
    selected:{
      get(){return this.val},
      set(v){
      	this.$emit('update:val', v)
     		if (this.master)
        	MyCompBus.$emit("master-updated", v)
     }
    }
  },
  methods:{
  	onMasterUpdated(newMasterValue){
      if (this.master) return
      this.selected = newMasterValue
    }
  },
  created(){
  	MyCompBus.$on('master-updated', this.onMasterUpdated)
  },
  beforeDestroy(){
  	MyCompBus.$off('master-updated', this.onMasterUpdated)
  },
  template: `
		<div>
      <div>
        <label>Status</label>
        <select v-model="selected">
          <option selected="" disabled="" value="0"></option>
          <option value="xxx">Xxx</option>
          <option value="yyy">Yyy</option>
          <option value="zzz">Zzz</option>
        </select>
      </div>
    </div>
  `,
})

new Vue({
  el: '#app',
  data:{
    masterValue: null,
    clients:[
      {id: 1, selectedValue: null, master: true},
      {id: 2, selectedValue: null},
      {id: 3, selectedValue: null},
      {id: 4, selectedValue: null},
    ]
  }
})
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <my-comp v-for="client in clients" 
           :val.sync="client.selectedValue" 
           :master="client.master" 
           :key="client.id">
  </my-comp>
  {{clients}}
</div>

原始答案

使用v-model将它们全部绑定到相同的值。

Vue.component('my-comp', {
  props: ['value'],
  computed:{
    selected:{
      get(){return this.value},
      set(v){this.$emit('input', v)}
    }
  },
  template: `
    <div>
      <div>
        <label>Status</label>
        <select v-model="selected">
          <option selected="" disabled="" value="0"></option>
          <option value="xxx">Xxx</option>
          <option value="yyy">Yyy</option>
          <option value="zzz">Zzz</option>
        </select>
      </div>
    </div>
  `,
})

在模板中:

<my-comp v-for="x in 2" v-model="selectedValue" :key="x"></my-comp>

这是updated fiddle

如果您希望坚持val作为属性,则可以使用.sync代替。

Vue.component('my-comp', {
  props: ['val'],
  computed:{
    selected:{
      get(){return this.val},
      set(v){this.$emit('update:val', v)}
    }
  },
  template: `
    <div>
      <div>
        <label>Status</label>
        <select v-model="selected">
          <option selected="" disabled="" value="0"></option>
          <option value="xxx">Xxx</option>
          <option value="yyy">Yyy</option>
          <option value="zzz">Zzz</option>
        </select>
      </div>
    </div>
  `,
})

在模板中:

<my-comp v-for="x in 2" :val.sync="selectedValue" :key="x"></my-comp>

示例fiddle

如果您只想将其中一个指定为“主”选择,则添加一个属性。

Vue.component('my-comp', {
  props: ['val', 'master'],
  computed:{
    selected:{
      get(){return this.val},
      set(v){if (this.master) this.$emit('update:val', v)}
    }
  },
  template: `
    <div>
      <div>
        <label>Status</label>
        <select v-model="selected">
          <option selected="" disabled="" value="0"></option>
          <option value="xxx">Xxx</option>
          <option value="yyy">Yyy</option>
          <option value="zzz">Zzz</option>
        </select>
      </div>
    </div>
  `,
})

在模板中:

<my-comp v-for="x in 5" :val.sync="selectedValue" :master="1 == x" :key="x"></my-comp>

示例fiddle