Vue使用select,v-for和v-model预选值

时间:2017-04-12 10:17:22

标签: javascript vue.js vuejs2

我将selectv-model一起使用,并选择v-for和对象作为值。选项是由id标识的一些元素。如何根据自定义相等性(在本例中为相等的id字段)预先选择选项?我正在寻找类似于track by的angularjs'ng-options的内容。

https://jsfiddle.net/79wsf1n4/5/

如何使用具有相同ID的值预先选择输入?

模板:

<div id="vue-instance">
  <select v-model="selected">
    <option v-for="item in inventory" :value="item" :key="item.id">
      {{ item.name }}
    </option>
  </select>
  <p>
    {{ selected.id }}
  </p>
</div>

JS:

var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', id: 1},
      {name: 'MacBook Pro', id: 2},
      {name: 'Lenovo W530', id: 3},
      {name: 'Acer Aspire One', id: 4}
    ],
    selected: {
        id: 2
    }
  }
});

3 个答案:

答案 0 :(得分:3)

您可以根据Dharmendra的答案添加所选属性。

但问题是您没有为所选属性分配有效对象。 Vue将尝试在选项列表中查找相同的对象,它将通过对象相等比较来完成此操作。

此时我不知道是否可以告诉Vue基于属性的初始选择,但是一个非常简单的解决方案是根据自己在ID中分配所选属性。创建了生命周期回调:

var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', id: 1},
      {name: 'MacBook Pro', id: 2},
      {name: 'Lenovo W530', id: 3},
      {name: 'Acer Aspire One', id: 4}
    ],
    selected: 2
  },
  created: function() {
        this.selected = this.inventory.find(i => i.id === this.selected);
  }
});

我已经更新了您的Fiddle

答案 1 :(得分:1)

您必须更改为选项分配值的方式。将此:value="item"更改为v-bind:value="item"

HTML部分

<select class="form-control" name="template" v-model="selected">
    <option v-for="item in inventory" v-bind:value="item">
       {{ item.name }}
    </option>
</select>

JS部分

new Vue({
  el: '#selector',
  data: {
    ...
    selected: {name: 'MacBook Pro', id: 2}
  }
})

这是一个有效的fiddle

答案 2 :(得分:1)

您需要很多代码才能测试行为(在您的情况下,您需要使用initSelectid设置name):< / p>

&#13;
&#13;
var vm = new Vue({
  el: '#vue-instance',
  data: {
    inventory: [
      {name: 'MacBook Air', id: 1},
      {name: 'MacBook Pro', id: 2},
      {name: 'Lenovo W530', id: 3},
      {name: 'Acer Aspire One', id: 4}
    ],
    initSelect : {
    	id: 2
    },
    selected: {},
  },
  created: function() {
    this.setSelectedWithInit();
  },
  methods: {
    setSelectedWithInit: function() {
      var firstKey = Object.keys(this.initSelect)[0],
      	  value = this.initSelect[firstKey];
      
      for( var i = 0, length = this.inventory.length; i < length; i++ ) {
      	if( (this.inventory[i].hasOwnProperty(firstKey))
         && (this.inventory[i][firstKey] === value) )
        {
          this.selected = this.inventory[i];
          return;
        }
      }
    },
    toggle: function() {//you don't need this method
      if( this.initSelect.hasOwnProperty('id') ) {
        this.initSelect = { name: 'Lenovo W530' };
      } else {
        this.initSelect = { id: 2 };
      }
    }
  },
  watch: {
    'initSelect': {
      handler: function (val, oldVal) {
        this.setSelectedWithInit();
      },
      deep: true
    }
  }
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.5/vue.js"></script>

<div id="vue-instance">
  <select v-model="selected">
    <option v-for="item in inventory" :value="item" :key="item.id">
      {{ item.name }}
    </option>
  </select>
  <p>
    {{ initSelect.id }}
    {{ initSelect.name }}
  </p>
  
  <!-- You don't need the rest of the html below -->
  <button @click="toggle">Toggle id/name</button>
  
  <div v-if="initSelect.hasOwnProperty('id')">
    Id: <input v-model.number="initSelect.id" type="number">
  </div>
  
  <div v-else>
    Name: <input v-model="initSelect.name" type="text">
  </div>
  
  <br><br>
  {{ initSelect }}
</div>
&#13;
&#13;
&#13;