入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

使用vue开发多级多选菜单组件

创建时间:2016-08-25 投稿人: 浏览次数:24472

多级多选菜单组件
要开发一个这样的多级多选菜单组件,功能是:

  • 点击父标题栏可以打开与折叠子列表
  • 点击父标题栏的勾选图标可以全选或取消子列表
  • 点击子列表的勾选图标达到全选时,父标题栏的勾选图标自动勾选;反之,没达到全选时,父标题栏的勾选图标自动取消勾选
  • 当所有父标题栏的勾选图标达到全选时,最底下那个全选框自动勾选;反之,没达到全选时,最底下那个全选框自动取消勾选
  • 点击最底下那个全选框可以全选或取消全部的勾选图标

    所以总结起来我们重点要利用子列表勾选了哪些项来计算出父标题与底下的全选框是自动勾选还是自动取消,并且父标题与底下的全选框在选择变化时子列表应有什么变化。要做到以上,实现过程是:

构建我们model层数据

datas : [
  {
    //用于判断是否展示子列表
    isShowListItem : false,
    //用于记录选中了哪些子项
    selected : [],
    //父标题
    listTitle : "保利南悦湾",
    //子列表
    listItem : [
      {
        id : 1,
        name : "李小龙"
      },
      {
        id : 2,
        name : "周星驰"
      },
      {
        id : 3,
        name : "周杰伦"
      }
    ]
  },
  {
    isShowListItem : false,
    selected : [],
    listTitle : "南庄万科城",
    listItem : [
      {
        id : 4,
        name : "大魔王"
      },
      {
        id : 5,
        name : "老妖怪"
      }
    ]
  }
]

记录子列表勾选了哪些项

子列表通过v-model=”data.selected”去双向绑定到selected数组中,当子列表项的checked发生变化时,就会把当前项的id记录到selected数组里去

<input 
type="checkbox"
:value="item.id"
v-model="data.selected"
>

当父标题勾选变化时的处理方法
自动处理父标题勾选图标的变化

在HTML里,通过绑定:checked=”isTitleChecked(data)”,这时,每当其他项变化时,父标题都会调用一下isTitleChecked这个方法去判断一下这时自己的checked状态是true还是false,从而达到根据子项选中数目不同,父标题自动变化的目的。
通过@change=”changeTitleChecked(data,$event)”,每当父标题主动勾选或取消时触发
父标题HTML

<input :id="data.listTitle"
  class="list-input"
  type="checkbox"
  :checked="isTitleChecked(data)"
  @change="changeTitleChecked(data,$event)"
>

父标题JS

  • changeTitleChecked方法:当主动触发父标题的勾选图标时,如果这次触发chaeked的状态是true,则要把子列表项中没选中的全部选中,即将它们全部加进selected数组中;如果是false,则要把子列表项全部取消选中,即清空selected数组。
  • isTitleChecked方法:当子列表项全部选中时自动勾选父标题。
/**
* 当父标题状态变化时的处理方法
* @param data  [当前项的data]
* @param event [当前项的event]
*/
changeTitleChecked : function (data,event) {
  if (event.target.checked === true) {
    data.listItem.forEach(function (item) {
    data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
    })
  }else {
    data.selected = [];
  }
}
/**
* 判断父标题选择状态
* @param data        [当前项的data]
* @returns {boolean}
*/
isTitleChecked : function (data) {
  var _selected = data.selected;
  var _listItem = data.listItem;
  // 验证selected中是否含有全部的item的id 如果是 证明title要选中
  return _listItem.every(function (item) {
   return _selected.indexOf(item.id) != -1;
  });
}

当底下的全选框变化时的处理方法
自动处理底下的全选框的变化

全选框HTML:

<input id="all-checked"
  type="checkbox"
  :checked="isAllChecked()"
  @change="changeAllChecked($event)"
>

全选框JS:

  • changeAllChecked方法:当主动触发全选框时,如果checked为true,则将全部的子项都放进selected数组里;反之则清空全部selected数组。
  • isAllChecked 方法:判断selected数组的长度是否等于全部子项数,如果相等,则全选框checked状态设为true。
/**
* 全选框change事件的回调处理方法
* @param event 
*/
changeAllChecked : function (event) {
  if (event.target.checked === true) {
    this.datas.forEach(function (data) {
      data.listItem.forEach(function (item) {
      data.selected.indexOf(item.id) === -1 && data.selected.push(item.id);
    })
  })
}else {
      this.datas.forEach(function (data) {
      data.selected = [];
    })
  }
}
/**
* 判断全选框选择状态
* @returns {boolean}
*/
isAllChecked : function () {
    return this.datas.every(function (data) {
        return data.selected.length === data.listItem.length;
    });
}
声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。