首页 > 解决方案 > How do I preselect a vue-multiselect option when options is an array of objects?

问题描述

我想在由vue-multiselect.
如果我有一个简单的字符串数组,如下所示,我可以让它正常工作:

['Test 1', 'Test 2', 'Test 3']

但是,当我使用对象数组时,我无法让它工作。例如,如果我有以下内容:

<v-multiselect :options="[{id: 1, name: 'Test 1'}, {id: 2, name: 'Test 2'}, {id: 3, name: 'Test 3'}]"
               label="name"
               track-by="id"
               v-model="test">
</v-multiselect>

无论我如何设置testv-model 连接的数据属性,它都不会预选值。我试过1, 2, 3, '1', '2'and '3'for testwhen track-byis idand'Test 1'等 when track-byisname但似乎没有任何效果。

我在这里做错了什么?我查看了https://vue-multiselect.js.org/#sub-single-select-object上的文档,但是当您要为对象数组预设值时,它们似乎没有提供示例选项。谷歌搜索也没有返回我正在寻找的东西。

在一个相关主题上,一旦我得到这个工作,当我将组件设置为时,我需要改变什么来选择多个值multiple?谢谢你。

标签: arraysvue.jsvuejs2presetvue-multiselect

解决方案


track-by用法

文档表明这track-by“用于比较对象。仅在选项是对象时使用。

也就是说,它指定了在比较 中的对象值时要使用的对象键options。文档实际上应声明选项为对象track-by所需的需要,因为<vue-multiselect>用于track-by 确定选中中的哪个选项的用途并从多选择中正确删除所选选项

如果没有track-by,您会看到 object-options 的两个错误行为:(1) 用户将能够重新选择已选择的选项,以及 (2) 尝试删除选定的选项会导致重新插入所有选项。

设置初始值

<vue-multiselect>不支持自动翻译值数组,但您可以轻松地从父组件中做到这一点。

  1. 创建一个本地数据属性来指定track-by和初始多选值(例如,分别命名trackByinitialValues):

    export default {
      data() {
        return {
          //...
          trackBy: 'id',
          initialValues: [2, 5],
        }
      }
    }
    
  2. 绑定<vue-multiselect>.track-bythis.trackBy<vue-multiselect>.v-modelthis.value

    <vue-multiselect :track-by="trackBy" v-model="value">
    
  3. 创建一个观察者this.initialValues将这些值映射到一个基于 的对象数组this.trackBy,设置this.value为结果:

    export default {
      watch: {
        initialValues: {
          immediate: true,
          handler(values) {
            this.value = this.options.filter(x => values.includes(x[this.trackBy]));
          }
        }
      }
    }
    

Vue.component('v-multiselect', window.VueMultiselect.default);

new Vue({
  el: '#app',
  data () {
    return {
      trackBy: 'id',
      initialValues: [5,2],
      value: null,
      options: [
        { id: 1, name: 'Vue.js', language: 'JavaScript' },
        { id: 2, name: 'Rails', language: 'Ruby' },
        { id: 3, name: 'Sinatra', language: 'Ruby' },
        { id: 4, name: 'Laravel', language: 'PHP' },
        { id: 5, name: 'Phoenix', language: 'Elixir' }
      ]
    }
  },
  watch: {
    initialValues: {
      immediate: true,
      handler(values) {
        this.value = this.options.filter(x => values.includes(x[this.trackBy]));
      }
    }
  }
})
<script src="https://unpkg.com/vue@2.6.6/dist/vue.min.js"></script>
<script src="https://unpkg.com/vue-multiselect@2.1.0"></script>
<link rel="stylesheet" href="https://unpkg.com/vue-multiselect@2.1.0/dist/vue-multiselect.min.css">

<div id="app">
  <v-multiselect :track-by="trackBy"
                 :options="options"
                 v-model="value"
                 label="name"
                 multiple>
  </v-multiselect>
  <pre>{{ value }}</pre>
</div>


推荐阅读