最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Vue preselect value with select, v-for, and v-model - Stack Overflow

programmeradmin9浏览0评论

I'm using select with v-model and have options with v-for and object as a value. Options are some elements identified by id. How do I make option preselected based on custom equality (in this case by equal id field)? I'm looking for something similar to angularjs' track by from ng-options.

/

How to make the input preselected with the value with equal id?

template:

<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
    }
  }
});

I'm using select with v-model and have options with v-for and object as a value. Options are some elements identified by id. How do I make option preselected based on custom equality (in this case by equal id field)? I'm looking for something similar to angularjs' track by from ng-options.

https://jsfiddle/79wsf1n4/5/

How to make the input preselected with the value with equal id?

template:

<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
    }
  }
});
Share Improve this question edited Apr 12, 2017 at 10:54 Tuan Pham asked Apr 12, 2017 at 10:17 Tuan PhamTuan Pham 1,1202 gold badges15 silver badges29 bronze badges 2
  • Careful with the ma : :value="item", :key="item.id" (delete it !) – Happyriri Commented Apr 12, 2017 at 10:22
  • @SLYcee Thanks :) – Tuan Pham Commented Apr 12, 2017 at 10:25
Add a ment  | 

3 Answers 3

Reset to default 7

You could add the selected attribute as per Dharmendra's answer.

The issue however is that you're not assigning a valid object to your selected property. Vue will try to look for an identical object in your option list, it will do this by object equality parison.

At this time I'm not aware whether it's possible to tell Vue to base the initial selection on an attribute, however a very simple solution is to assign the selected property based on the ID yourself in the created lifecycle callback:

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);
  }
});

I've updated your Fiddle as well.

You have to change the way you are assigning value to option. change this :value="item" to v-bind:value="item".

HTML part

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

JS part

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

Here is a working fiddle

There is a lot of code you don't need but useful to test the behavior (in your case you need to set initSelect with id or name) :

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
    }
  }
});
<script src="https://cdnjs.cloudflare./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>

发布评论

评论列表(0)

  1. 暂无评论