Vue JS2 父子复选框

Posted

技术标签:

【中文标题】Vue JS2 父子复选框【英文标题】:Vue JS2 parent and child checkboxes 【发布时间】:2018-02-05 07:38:27 【问题描述】:

我有一个列表列表:

<ul>
      <li v-for="subregion in continents">
        <input type="checkbox" :id="subregion[0].subregion" > <label :for="subregion[0].subregion"> subregion[0].subregion </label>
        <ul>
          <li v-for="country of subregion">
              <input type="checkbox" :id="country.name" > <label :for="country.name"> country.name  (+ country.callingCodes[0])</label>
          </li>
        </ul>
      </li>
</ul>
完整代码在这里: https://jsfiddle.net/kw1vmvqy/

如何实现一种方法,以便当我选中/取消选中大陆复选框时,它会选中/取消选中其中的所有国家/地区复选框?此外,如果我取消选中一个国家/地区复选框 - 它会取消选中相应的大陆复选框。

【问题讨论】:

【参考方案1】:

您应该做的第一件事是将值和 v-model 绑定到您的复选框:

<input type="checkbox" :id="subregion[0].subregion" v-model="subregionCheck" :value="subregion[0].subregion">

<input type="checkbox" :id="country.name" v-model="countryCheck" :value="country.name">

并在您的数据中添加 subregionCheck 和 countryCheck 数组:

  data: 
    subregions: null,
    countries: null,
    query: '',
    countryList: [],
    subregionCheck:[],
    countryCheck: []
  ,

这些数组用作我们复选框的标记:如果它们包含单个复选框的值,则会检查它。一开始他们都是空的。

在下一步中,我们应该为子区域复选框创建一个侦听器,并为该子区域创建一个检查所有国家/地区复选框的函数。让我们先为我们的子区域添加一个点击监听器:

<input type="checkbox" :id="subregion[0].subregion" v-model="subregionCheck" :value="subregion[0].subregion" @click="checkAllCountries(subregion)">

然后指定方法(只要你不使用 ES6,我需要将“this”委托给变量):

checkAllCountries: function (subregion) 
        var that = this;
        if (this.subregionCheck.indexOf(subregion[0].subregion) > -1) 
            subregion.forEach(function (element) 
              if (that.countryCheck.indexOf(element.name) <= -1) 
                that.countryCheck.push(element.name);
              
            );
      
      else 
         subregion.forEach(function (element) 
            that.countryCheck.splice(that.countryCheck.indexOf(element.name), 1);
        )
      
    ,

现在我们需要一种方法来取消选中子区域复选框,如果其中一个国家未选中。将点击监听器添加到国家复选框:

<input type="checkbox" :id="country.name" v-model="countryCheck" :value="country.name" @click="checkSubregion(subregion)"> 

然后指定方法:

checkSubregion: function (country) 
  if ((this.countryCheck.indexOf(country.name) <= -1) && this.subregionCheck.indexOf(country.subregion) > -1 ) 
    this.subregionCheck.splice(this.subregionCheck.indexOf(country.subregion), 1);
  
,

Working fiddle

【讨论】:

【参考方案2】:

您的要求太大了,无法在这里做。检查this link 以获得一个想法。此处检查子区域时会检查子区域下的国家/地区。但反之亦然,也不完整。您可以按照这种方式创建动态模型绑定。但这会有点慢,因为每次更改都必须遍历很多东西。

<ul>
  <li v-for="(subregion, index) in continents">
    <input type="checkbox" :id="subregion[0].subregion" v-on:change="onSubregionChecked(subregion[0].subregion)">
    <label :for="subregion[0].subregion"> subregion[0].subregion </label>
    <ul>
      <li v-for="country in subregion">
        <input type="checkbox" v-on:change="onCountryChanged(country)" v-model="countryMap[country.alpha3Code].isChecked" :id="country.name">
        <label :for="country.name"> country.name  (+ country.callingCodes[0])</label>
      </li>
    </ul>
  </li>
</ul>

在脚本中:

fetchData: function() 
  var xhr = new XMLHttpRequest();
  var self = this;
  xhr.open('GET', apiURL);
  xhr.onload = function() 
    self.countryList = JSON.parse(xhr.responseText);
    _.each(self.countryList, function(country) 
      self.countryMap[country.alpha3Code] = 
        country: country.alpha3Code,
        isChecked: false,
        subRegion: country.subregion
      ;
    );
  ;
  xhr.send();
,
onSubregionChecked(val) 
  const self = this;
  self.countryMap = _.mapValues(self.countryMap, function(countryInSubRegion) 
    if (_.isObject(countryInSubRegion) && countryInSubRegion.subRegion === val) 
      countryInSubRegion.isChecked = true;
    
    return countryInSubRegion;
  );

同样,这不是一个有效的解决方案 - 它只会让您提前做好准备。

【讨论】:

以上是关于Vue JS2 父子复选框的主要内容,如果未能解决你的问题,请参考以下文章

将一串数据从父组件传递给子组件。 Vue.js 2

如何将 Vue.js 2 组件值分配给主实例变量?

vue+ element ui 树形控件tree实现单选功能 2021-04-28

PHP MySql:打印树 - 父子复选框

DevExpress TreeList 父子节点复选框状态同步

Ext.js 2 复选框和事件通过更改侦听器触发两次