Vue.js根据两个复选框值的结果切换按钮?

时间:2018-02-26 15:16:40

标签: html vue.js vuejs2

我正在尝试实现切换功能,用户可以启用一天,然后选中带有复选框的AM或PM。

如果用户取消选中AM和PM,我遇到的问题是尝试取消切换按钮。

屏幕截图:

enter image description here

标记

<div class="form-group-checkboxes col-xs-1 pt14">
          <toggle v-model="availability.monday.active" theme="custom" color="blue"></toggle>
        </div>
        <div class="form-group-checkboxes col-xs-2">
          <h4>Mon</h4>
        </div>
        <div class="form-group-checkboxes col-xs-1 mt10">
          <label class="checkbox-inline"><input type="checkbox" name="mondayAM"
                                                class="pull-left"
                                                :disabled="availability.monday.active ===false"
                                                v-model="availability.monday.am">AM</label>
        </div>
        <div class="form-group-checkboxes col-xs-1 ml20 mt10">
          <label class="checkbox-inline"><input type="checkbox" name="mondayPM"
                                                class="pull-left"
                                                :disabled="availability.monday.active ===false"
                                                v-model="availability.monday.pm">PM</label>

数据:

      monday: {
        active: true,
        am: true,
        pm: true,
      },
      tuesday: {
        active: true,
        am: true,
        pm: true,
      },
      wednesday: {
        active: true,
        am: true,
        pm: true,
      },

我尝试创建一个计算属性来检查AMPM属性值。

toggleMonday() {
    return this.availability.monday.am === true && this.availability.monday.pm === true;
  },

然而,这并没有提供所需的切换经验。

TLDR,如何允许具有自己的绑定值的不同元素相互影响

e.g。

  1. 用户切换周一关闭,上午和下午取消选中
  2. 用户在星期二打开,取消选中上午和下午,然后星期二变为无遮挡。

2 个答案:

答案 0 :(得分:3)

active设为computed with a setter。如果选择了AM PM,则getter应返回true。如果this是日期数据:

get() { return this.am || this.pm; }

setter应将AM PM设置为其新值:

set(newValue) { this.am = newValue; this.pm = newValue; }

由于你有多天具有相同的结构,你应该把它作为一个组件,所以你只需要写一次。这是一个最小的例子:

new Vue({
  el: '#app',
  data: {
    days: ['Monday', 'Tuesday', 'Wednesday']
  },
  components: {
    daySelector: {
      template: '#day-selector-template',
      props: ['day'],
      data() {
        return {
          am: false,
          pm: false
        };
      },
      computed: {
        active: {
          get() {
            return this.am || this.pm;
          },
          set(newValue) {
            this.am = this.pm = newValue;
          }
        }
      }
    }
  }
});
<script src="//unpkg.com/vue@latest/dist/vue.js"></script>
<div id="app">
  <day-selector v-for="day in days" :day="day" :key="day">
  </day-selector>
</div>

<template id="day-selector-template">
  <div>
    {{day}}
    <input type="checkbox" v-model="active">
    <input type="checkbox" v-model="am">
    <input type="checkbox" v-model="pm">
  </div>
</template>

答案 1 :(得分:2)

我认为这可能是.sync modifier的用例。我将假设您希望“day”对象的属性对父作用域可见。在这种情况下,您应该将它们附加到day组件,以便所有属性在更改时同步。

考虑这个例子:

Vue.component("daytoggle", {
  props: ["dayname", "dayo"],
  watch: {
    "dayo.enabled": function(newVal) {
      if (!newVal) {
        this.$emit("update:dayo", {
          enabled: false,
          times: {
            am: false,
            pm: false
          }
        });
      } else {
        this.$emit("update:dayo", {
          enabled: true,
          times: {
            am: true,
            pm: true
          }
        });
      }
    },
    "dayo.times.am": function(newVal) {
      if (!newVal && !this.dayo.times.pm) {
        this.$emit("update:dayo", {
          enabled: false,
          times: {
            am: false,
            pm: false
          }
        })
      }
    },
    "dayo.times.pm": function(newVal) {
      if (!newVal && !this.dayo.times.am) {
        this.$emit("update:dayo", {
          enabled: false,
          times: {
            am: false,
            pm: false
          }
        })
      }
    }
  }
});


const app = new Vue({
  el: "#app",
  data() {
    return {
      days: [{
          weekday: "Monday",
          props: {
            enabled: true,
            times: {
              am: true,
              pm: true
            }
          }
        },
        {
          weekday: "Tuesday",
          props: {
            enabled: true,
            times: {
              am: true,
              pm: true
            }
          }
        },
        {
          weekday: "Wednesday",
          props: {
            enabled: true,
            times: {
              am: true,
              pm: true
            }
          }
        }
      ]
    }
  }
});
.day {
  color: red;
}

.day.enabled {
  color: green;
}
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.13/dist/vue.min.js"></script>
<main id="app">
  <section>
    <p>This data is populated in such a way that each day creates a "daytoggle" component and gives each instance a "day".</p>
    <daytoggle v-for="(day, idx) in days" :dayname="day.weekday" :dayo.sync="day.props" :key="idx" inline-template>
      <div>
        <label><span>{{dayname}}</span> <input type="checkbox" v-model="dayo.enabled"></label>
        <label><span>AM</span> <input type="checkbox" v-model="dayo.times.am" :disabled="!dayo.enabled"></label>
        <label><span>PM</span> <input type="checkbox" v-model="dayo.times.pm" :disabled="!dayo.enabled"></label>
      </div>
    </daytoggle>
  </section>
  <section>
    <p>This portion is populated by data pulled from the app level scope.</p>
    <ul>
      <li v-for="day in days">
        <div><span class="day" :class="{'enabled': day.props.enabled}">{{day.weekday}}</span> <span v-if="day.props.times.am">AM</span> <span v-if="day.props.times.pm">PM</span></div>
      </li>
    </ul>
    <section>
</main>