如何使用 vue-multiselect 的 v-model 值选中复选框

How to make checkbox selected with v-model value for vue-multiselect

问题: 创建的选定选项复选框未被选中,我希望复选框被选中,而不管 checked true/false

注意: 我一直想要的价值模型没有 checked 状态

下图显示了我的问题(请看黄色区域)

这是我试过的:

new Vue({
    components: {
    Multiselect: window.VueMultiselect.default
    },
    data: {
    value: [],
    options: [
        {   language: 'JavaScript', library: 'Vue.js', checked: false },
      { language: 'JavaScript', library: 'Vue-Multiselect', checked: false },
      { language: 'JavaScript', library: 'Vuelidate', checked: false }
    ]
    },
  methods: {
    customLabel (option) {
      return `${option.library} - ${option.language}`
    },
    onSelect (option) {
        console.log("Added");
      let index = this.options.findIndex(item => item.library==option.library);
      this.options[index].checked = true;
      console.log(option.library + "  Clicked!! " + option.checked);
    },
    
    onRemove (option) {
        console.log("Removed");
      let index = this.options.findIndex(item => item.library==option.library);
      this.options[index].checked = false;
      console.log(option.library + "  Removed!! " + option.checked);
    }
  },
  created(){
       this.value = [{  language: 'JavaScript', library: 'Vue.js',checked:true }];
  }
}).$mount('#app')
* {
  font-family: 'Lato', 'Avenir', sans-serif;
}

.checkbox-label {
  display: block;
}

.test {
  position: absolute;
  right: 1vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect@2.0.2/dist/vue-multiselect.min.css" rel="stylesheet"/>
<script src="https://unpkg.com/vue-multiselect@2.0.3/dist/vue-multiselect.min.js"></script>
<div id="app">
  <multiselect 
    select-Label=""
    selected-Label=""
    deselect-Label=""
    v-model="value" 
    :options="options"
    :multiple="true"
    track-by="library"
    :custom-label="customLabel"
    :close-on-select="false"
    @select=onSelect($event)
    @remove=onRemove($event)
    >
    <span class="checkbox-label" slot="option" slot-scope="scope" @click.self="select(scope.option)">
    {{ scope.option.library }}
      <input class="test" type="checkbox" v-model="scope.option.checked" @focus.prevent/>
      
    </span>
  </multiselect>
  <pre>{{ value }}</pre>
</div>

请帮助我提前谢谢!!

该包不是作为复选框使用,而是作为一组选项,您可以 select 或不使用。因此,如果您想要预 select 选项,则必须将它们添加到 v-model 数组(在本例中为“值”)。

此外,options.checked 数据在这里是货物崇拜。它们不用于任何用途。

基于您的代码的示例。 你的数据()应该是

options: [
        {   language: 'JavaScript', library: 'Vue.js'},
      { language: 'JavaScript', library: 'Vue-Multiselect'},
      { language: 'JavaScript', library: 'Vuelidate' }
    ],
value: [
        {   language: 'JavaScript', library: 'Vue.js'},
      { language: 'JavaScript', library: 'Vue-Multiselect'},
      { language: 'JavaScript', library: 'Vuelidate' }
    ]

如果您在数据中使用这两个启动应用程序,所有选项都将被预先select编辑。

您不需要分配 value,因为它在那里失去了反应性。 您只需 select 正确的选项并选中它。作为下面的代码,我更改了 created

new Vue({
  components: {
    Multiselect: window.VueMultiselect.default
  },
  data: {
    value: [],
    options: [{
        language: 'JavaScript',
        library: 'Vue.js',
        checked: false
      },
      {
        language: 'JavaScript',
        library: 'Vue-Multiselect',
        checked: false
      },
      {
        language: 'JavaScript',
        library: 'Vuelidate',
        checked: false
      }
    ]
  },
  methods: {
    customLabel(option) {
      return `${option.library} - ${option.language}`
    },
    onSelect(option) {
      console.log("Added");
      let index = this.options.findIndex(item => item.library == option.library);
      this.options[index].checked = true;
      console.log(option.library + "  Clicked!! " + option.checked);
    },

    onRemove(option) {
      console.log("Removed");
      let index = this.options.findIndex(item => item.library == option.library);
      this.options[index].checked = false;
      console.log(option.library + "  Removed!! " + option.checked);
    }
  },
  created() {
    // this.value = this.options[0];
    //this.value.checked = true;

    this.value.push(this.options[0]);
    this.value.push(this.options[1]);

    for (let i = 0; i < this.value.length; i++) {
      this.value[i].checked = true;
    }

  }
}).$mount('#app')
* {
  font-family: 'Lato', 'Avenir', sans-serif;
}

.checkbox-label {
  display: block;
}

.test {
  position: absolute;
  right: 1vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect@2.0.2/dist/vue-multiselect.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vue-multiselect@2.0.3/dist/vue-multiselect.min.js"></script>
<div id="app">
  <multiselect select-Label="" selected-Label="" deselect-Label="" v-model="value" :options="options" :multiple="true" track-by="library" :custom-label="customLabel" :close-on-select="false" @select=onSelect($event) @remove=onRemove($event)>
    <span class="checkbox-label" slot="option" slot-scope="scope" @click.self="select(scope.option)">
    {{ scope.option.library }}
      <input class="test" type="checkbox" v-model="scope.option.checked" @focus.prevent/>
      
    </span>
  </multiselect>
  <pre>{{ value }}</pre>
</div>

有点难以理解您真正想要什么,但假设:

  1. 您想呈现复选框
  2. 您不需要 v-model 中的 checked 字段(因此添加它只是为了帮助呈现复选框)

您根本不需要 checked 属性,因为可以通过对 v-model 的简单检查轻松替换该值。这样你就可以删除很多不必要的代码。

请参阅下面的示例:

new Vue({
  components: {
    Multiselect: window.VueMultiselect.default
  },
  data: {
    value: [],
    options: [{
        language: 'JavaScript',
        library: 'Vue.js'
      },
      {
        language: 'JavaScript',
        library: 'Vue-Multiselect'
      },
      {
        language: 'JavaScript',
        library: 'Vuelidate'
      }
    ]
  },
  methods: {
    customLabel(option) {
      return `${option.library} - ${option.language}`
    },
    isSelected(option) {
      /* unfortunatelly following line does not work as VueMultiselect for some (strange) reason 
        fills the v-model array with copies instead of original objects contained in options
      */
      // return this.value.includes(option)
      return this.value.some((op) => op.library === option.library)
    }
  },
  created() {
    this.value.push(this.options[0])
  }
}).$mount('#app')
* {
  font-family: 'Lato', 'Avenir', sans-serif;
}

.checkbox-label {
  display: block;
}

.test {
  position: absolute;
  right: 1vw;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://unpkg.com/vue-multiselect@2.0.2/dist/vue-multiselect.min.css" rel="stylesheet" />
<script src="https://unpkg.com/vue-multiselect@2.0.3/dist/vue-multiselect.min.js"></script>
<div id="app">
  <multiselect select-Label="" selected-Label="" deselect-Label="" v-model="value" :options="options" :multiple="true" track-by="library" :custom-label="customLabel" :close-on-select="false">
    <span class="checkbox-label" slot="option" slot-scope="scope">
    {{ scope.option.library }}
      <input class="test" type="checkbox" :checked="isSelected(scope.option)" @focus.prevent :key="scope.option.library" />
    </span>
  </multiselect>
  <pre>{{ value }}</pre>
</div>