简体   繁体   中英

Vue allow only one element in array be true

I'm creating multiple input fields with checkboxes in vue and I want that only one can be true. So if the user clicks on one the others should be false so that only the last clicked checkbox is true.

My code is like that:

new Vue({
  el: "#app",
  data: {
      selected: null,
      options: [
          {"id": 1, "title": "One", "value": false},
          {"id": 2, "title": "Two", "value": false },
          {"id": 3, "title": "Three", "value": false},
      ]
  },
  watch: {
    selected(selected) {
      this.options.forEach((option, index) => {
        option.id == selected ? option.value = true : option.value = false;
      });
    }
  }

Unfortunately my watcher isn't working properly. I would be really glad if somebody can show me how to correct it. I want that always the last true element is the only true element and the watches sets all other elements in options to false.

If i understood your requirements correctly you can still do it with radio buttons. You can specify the value to be used inside the selected variable, as described here: https://v2.vuejs.org/v2/guide/forms.html#Radio-1 . This means that you can set up a watcher and then mutate the options list accordingly:

selected: function (newVal) {
    this.options.forEach(option => {
      if (option.id === newVal) option.value = true
      else option.value = false
    })
    console.log(this.options)
}

Here is a sandbox to see it in action: https://codesandbox.io/s/heuristic-goldberg-lilsw

Update: Just saw that you want to use the </b-switch> from buefy. You can still do something similar by calling a function from the input event which then mutates the options list according to the just changed element. Something like this:

<div v-for="(option,index) in options" :key="index">
      <div class="box">
        <div class="field">
           <b-switch v-model="option.value" @input="(modelValue) => onSwitchChanged(modelValue, option.id)">
            {{ option.title }}
           </b-switch>
          <label :for="index">{{ option.title }}</label>
        </div>
    </div>
</div>

function onSwitchChanged(modelValue, id) {
    if (!modelValue) return
    this.options.forEach(option => {
      if (option.id === id) option.value = true
      else option.value = false
    })
}

If you want that Only One will be selected then you have to use radio button. Checkbox has options to select all But One by One .

Without watch you can use methods . Pass index to the method.

<input 
   type="checkbox"
   :id="index" 
   :value="option.id" 
   @click="selectAnOption(index)"
>

Method:

methods: {
  selectAnOption(index) {
   this.options[index].value = true
  }
}

Full Code here: https://jsfiddle.net/8ktdp9ew/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM