防止Vue多重选择以存储空数组

问题描述 投票:0回答:1

我希望此选择多个选项以预先选择一个选项,而不能取消选择所有选项。

无论何时取消选择最后选择的选项,都应重新选择它。换句话说,当用户尝试取消选择最后选择的选项时,从视觉上不应取消选择它。

<template>
  <b-select
    if="Object.keys(doc).length !== 0 /* wait until firebase has loaded */"
    :options="computedOptions"
    v-model="model"
    multiple
    @input="onChange"
  />
</template>

<script>
//import Vue from 'vue'
import { fb } from "../fbconf";

export default {
  name: "MyMultiSelect",
  props: {
    doc: Object, // firestore document
  },
  data() {
    return {
      options: []
    };
  },

  firestore() {
    var options = fb.db.collection("options");
    return {
      options: options
    };
  },

  computed: {
    computedOptions: function() {
      return this.options.map(function(option) {
        return {
          text: option.name,
          value: option.id
        };
      });
    },

    // to make sure mySelectedOptions is an array, before this.doc is loaded
    // I use the following custom model
    // because not using 'get' below causes a warning:
    // [Vue warn]: <select multiple v-model="localValue"> expects an Array value for its binding, but got Undefined
    model: {
      get: function() {
        if (!this.doc.hasOwnProperty('mySelectedOptions')) return []; // empty array before this.doc is loaded
        else return this.doc['mySelectedOptions'];
      },
      set: function(newValue) {
         // here I can prevent the empty array from being stored
         // but visually the user can deselect all options, which is bad UX
         //if (Array.isArray(newValue) && newValue.length > 0) this.doc['mySelectedOptions'] = newValue;
      }
    },
  },

  methods: {
    onChange: function(newValue){
      // I can manually store the array as I want here
      // but I cannot in any way prevent the user from deselecting all options
      if (Array.isArray(newValue) && newValue.length > 0) this.doc['mySelectedOptions'] = newValue;
      else {
        // none of these reselects the last selected option
        var oldValue = this.doc['mySelectedOptions'];
        this.doc['mySelectedOptions'] = this.doc['mySelectedOptions'];
        //this.$forceUpdate();
        //this.$emit("change", newValue);
        //Vue.set(this.doc, 'mySelectedOptions', this.doc['mySelectedOptions']);
      }
    }
  }
};
</script>
vue.js google-cloud-firestore bootstrap-vue
1个回答
0
投票

您可以添加观察者,并且当长度变为0时,只需添加上一个值即可。

  watch: {
    model(val, oldVal) {
      if(val.length == 0 && oldVal.length > 0) {
        // take only one item in case there's clear button or etc.
        this.model = [oldval[0]];
      }
    }
  }
© www.soinside.com 2019 - 2024. All rights reserved.