对象数组模型绑定中的复选框组件

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

我有一周的天数,就像下面的可切换按钮一样:

单击该按钮将在ONOFF之间切换(复选框为checked

注意:下面的代码不起作用,单击按钮时会显示undefined

enter image description here

<template>
  <label 
    v-for="(day, index) in days"
    :key="index"
    class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2"
    :class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'"
    :for="`checked-${day.index}`"
  >
    <input
      :id="`checked-${ day.index }`"
      type="checkbox"
      class="absolute opacity-0 w-0 h-0"
      @click="check"
      v-model="selectedDays"
      :value="index"
    />
      {{ day.label }}
    </label> 
</template>

<script>
export default {
  inheritAttrs: false,
    data() {
    return {
      days: {
        Sunday: {
          label: 'Sun',
          state: true
        },
        Monday:  {
          label: 'Mon',
          state: false
        },
        Tuesday:  {
          label: 'Tue',
          state: false
        },
        Wednesday:  {
          label: 'Wed',
          state: false
        },
        Thursday:  {
          label: 'Thu',
          state: false
        },
        Friday:  {
          label: 'Fri',
          state: false
        },
        Saturday:  {
          label: 'Sat',
          state: false
        }
      },
      selectedDays: []
    }
  },
  methods: {
    clickToggle() {
      this.toggle(!this.state)
    },
    toggle(state) {
      this.state = state
    },
    check() {
      console.log(this.selectedDays);
    }
  }
}
</script>

我的问题:

  • 如何将复选框绑定到一个或多个模型,以便单击复选框时可以切换模型状态?
  • 我应该使用selectedDays方法还是days可以自行处理?
vue.js vuejs2 vue-component
3个回答
0
投票

没有任何必要。参见我的示例,我仅工作于v-model指令。

对于selectedDays,更好的方法是计算属性。这是最佳做法,更容易。

<template>
  <div>
    <label
      v-for="(day, index) in days"
      :key="index"
      class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2"
      :class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'"
    >
      <input type="checkbox" v-model="day.state" />
      {{ day.label }}
    </label>
    <div>{{ selectedDays }}</div>
  </div>
</template>

<script>
export default {
  inheritAttrs: false,
  data() {
    return {
      days: {
        Sunday: { label: 'Sun', state: true },
        Monday: { label: 'Mon', state: false },
        Tuesday: { label: 'Tue', state: false },
        Wednesday: { label: 'Wed', state: false },
        Thursday: { label: 'Thu', state: false },
        Friday: { label: 'Fri', state: false },
        Saturday: { label: 'Sat', state: false },
      },
    };
  },
  computed: {
    selectedDays() {
      let result = [];
      for (let key in this.days) {
        if (this.days[key].state) {
          result.push(this.days[key]);
        }
      }
      return result;
    },
  },
};
</script>

0
投票

您应该使用@nput事件而不是@click,在事件处理程序中传递索引并按days的方式更改this.days[index].state=!this.days[index].state; this.$set(this.days,index,this.days[index])数组,并将复选框绑定到days[index].state

new Vue({
  el: '#app',

  data() {
    return {
      days: {
        Sunday: {
          label: 'Sun',
          state: true
        },
        Monday: {
          label: 'Mon',
          state: false
        },
        Tuesday: {
          label: 'Tue',
          state: false
        },
        Wednesday: {
          label: 'Wed',
          state: false
        },
        Thursday: {
          label: 'Thu',
          state: false
        },
        Friday: {
          label: 'Fri',
          state: false
        },
        Saturday: {
          label: 'Sat',
          state: false
        }
      },
      selectedDays: []
    }
  },
  methods: {
    clickToggle() {
      this.toggle(!this.state)
    },
    toggle(state) {
      this.state = state
    },
    check(index) {
    this.days[index].state=!this.days[index].state;
    this.$set(this.days,index,this.days[index])
      console.log(this.selectedDays);
    }
  }
})
<body>
  <div id="app">

    <label v-for="(day, index) in days" :key="index" class="flex items-center justify-center border border-gray-500 rounded cursor-pointer py-2" :class="day.state ? 'text-white bg-gray-500' : 'text-gray-500 bg-white'" :for="`checked-${day.index}`">
    <input
      :id="`checked-${ day.index }`"
      type="checkbox"
      class="absolute opacity-0 w-0 h-0"
      @input="check(index)"
      v-model="days[index].state"
     
      :value="day"
    />
      {{ day.label }}
    </label>

  </div>

  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>

0
投票

我建议另一种方法(我删除了不必要的逻辑/样式):

<template>
    <div v-for="(day, index) in days"
    key="index">

        <label>
            {{days[index].label}}
        </label>
        <input
        type="checkbox"           
        v-model="days[index].state"        
        />
        {{ day.label }}
    </div>
</template>

<script>
export default {
    data() {
    return {
      days: [
        Sunday: {
          label: 'Sun',
          state: true
        },
        Monday:  {
          label: 'Mon',
          state: false
        },
        Tuesday:  {
          label: 'Tue',
          state: false
        },
        Wednesday:  {
          label: 'Wed',
          state: false
        },
        Thursday:  {
          label: 'Thu',
          state: false
        },
        Friday:  {
          label: 'Fri',
          state: false
        },
        Saturday:  {
          label: 'Sat',
          state: false
        }
      }
    }
  }
}
</script>
© www.soinside.com 2019 - 2024. All rights reserved.