基于 Vue 的树形选择组件的示例代码


Posted in Javascript onAugust 18, 2017

本文介绍了基于 Vue 的树形选择组件。分享给大家,具体如下:

系统要求:Vue 2

基本特性

  •  完美的多级联动效果
  •  支持无限多的分级
  •  有 全选、半选、不选 三种状态

 截图展示

基于 Vue 的树形选择组件的示例代码

代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <link rel="icon" href="https://v1-cn.vuejs.org/images/logo.png" rel="external nofollow" type="image/x-icon">
 <title>Vue Tree Select Example</title>
 <script src="https://cdn.bootcss.com/vue/2.4.2/vue.js"></script>
</head>
<body>

 <!-- 递归引用的模板 -->
 <template id="one-select" style="display: none;">
  <ul>
   <li v-for="(node, key, index) in tree">
    <div v-if="key != 'selected'">
     <div v-on:click="nodeClick(node, index)" v-bind:class="[node.selected == null ? 'tree-select-null' : (node.selected == 'half' ? 'tree-select-half' : 'tree-select-full'), 'tree-select', 'inline-block']"></div>
     
     <div class="inline-block">{{ key }}</div>
     <div v-if="key != ''">
      <one-select v-bind:tree="node" v-bind:isroot="false"></one-select>
     </div>
    </div>
   </li>
  </ul>
 </template>

 <!-- 整体树容器 -->
 <div id="tree">
  <one-select v-bind:isroot="true" v-bind:tree="tree"></one-select>
 </div>

<textarea id="treeDataJSON" style="display: none;">
{
 "客户管理": {
  "我的客户": {
   "新分配": {},
   "跟进中": {},
   "签单客户": {},
   "长期客户": {}
  },
  "长期客户权限": {
   "设为长期客户": {},
   "还原长期客户": {}
  }
 },
 "采购列表": {
  "添加异常客情": {},
  "添加采购单": {},
  "采购退货单列表": {},
  "供应商管理": {},
  "供应商联系人": {},
  "品牌列表": {
   "宝洁": {},
   "乐视": {
    "乐视网": {},
    "乐视手机": {
     "乐视手机 1": {},
     "乐视手机 2": {},
     "乐视手机 3": {},
     "乐视手机 4": {},
     "乐视手机 5": {
      "体验超深层级": {
       "继续体验超深层级": {
        "依然体验超深层级": {},
        "依然体验超深层级 2": {}
       }
      }
     }
    },
    "乐视电视": {}
   },
   "可口可乐": {},
   "圣象": {}
  }
 }
}
</textarea>

<script>
// 初始数据
var treeDataJSON = document.getElementById("treeDataJSON").value;
var treeData = JSON.parse(treeDataJSON);
Vue.component('one-select', {
 name: 'one-select',
 template: '#one-select',
 props: ['tree', 'isroot'],
 created: function() {
  var realTree = Object.assign({}, this.tree);
  delete realTree.selected;
  if (Object.keys(realTree).length === 0) { // 判断最低级,再刷新父级
   this.refreshAllParentNodes(this.$parent);
  }
 },
 methods: {
  nodeClick: function(node, index) {
   if (node.selected === 'full' || node.selected === 'half') {
    Vue.set(node, 'selected', null);
   } else {
    Vue.set(node, 'selected', 'full');
   }
   this.refreshAllParentNodes(self.$parent);
   this.refreshAllParentNodes(this);
   this.refreshAllSonNodes(this.$children[index], node.selected);
  },
  refreshAllSonNodes: function(node, status) {
   if (node instanceof Vue && node.$children.length) {
    for (index in node.$children) {
     Vue.set(node.$children[index].tree, 'selected', status);
     // 递归计算子级
     this.refreshAllSonNodes(node.$children[index], status);
    }
   }
  },
  refreshAllParentNodes: function(node) {
   if (node instanceof Vue) {
    var status = null;
    var nullCount = 0;
    var halfCount = 0;
    var fullCount = 0;
    for (index in node.$children) {
     if (typeof node.$children[index].tree.selected === 'undefined') {
      nullCount++;
     } else if (node.$children[index].tree.selected === null) {
      nullCount++;
     } else if (node.$children[index].tree.selected === 'half') {
      halfCount++;
     } else if (node.$children[index].tree.selected === 'full') {
      fullCount++;
     }
    }
    if (fullCount === node.$children.length) {
     status = 'full';
    } else if (nullCount === node.$children.length) {
     status = null;
    } else {
     status = 'half';
    }
    Vue.set(node.tree, 'selected', status);

    // 递归计算父级
    this.refreshAllParentNodes(node.$parent);
   }
  },
  log: function(o) {
   console.log(o);
  }
 }
});
vm = new Vue({
 el: '#tree',
 data: {
  tree: treeData
 },
 methods: {
  // 返回最终数据
  getResult: function() {
   return Object.assign({}, this.tree);
  }
 }
});
</script>

<style>
#tree {
 width: 500px;
 margin: 0 auto;
 margin-top: 50px;
}
li {
 list-style: none;
 line-height: 25px;
}
.inline-block {
 display: inline-block;
}
.tree-select {
 width: 13px;
 height: 13px;
 line-height: 16px;
 margin: 3px;
 display: inline-block;
 vertical-align: middle;
 border: 0 none;
 cursor: pointer;
 outline: none;
 background-color: transparent;
 background-repeat: no-repeat;
 background-attachment: scroll;
 background-image: url('selects.png');
}
.tree-select-null {
 background-position: 0 0;
}
.tree-select-full {
 background-position: -14px 0;
}
.tree-select-half {
 background-position: -14px -28px;
}
</style>

</body>
</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js实现的日期操作类DateTime函数代码
Mar 16 Javascript
javascript各浏览器中option元素的表现差异
Apr 07 Javascript
纯JAVASCRIPT图表动画插件Highcharts Examples
Apr 16 Javascript
Jquery Ajax xmlhttp请求成功问题
Feb 04 Javascript
鼠标经过子元素触发mouseout,mouseover事件的解决方案
Jul 26 Javascript
浅析javascript的return语句
Dec 15 Javascript
jQuery Ajax使用FormData对象上传文件的方法
Sep 07 Javascript
react-native封装插件swiper的使用方法
Mar 20 Javascript
原生JS实现的简单小钟表功能示例
Aug 30 Javascript
微信小程序 拍照或从相册选取图片上传代码实例
Aug 28 Javascript
Vue CLI项目 axios模块前后端交互的使用(类似ajax提交)
Sep 01 Javascript
详解JSON.stringify()的5个秘密特性
May 26 Javascript
简单实现jQuery手风琴效果
Aug 18 #jQuery
JavaScript中Hoisting详解 (变量提升与函数声明提升)
Aug 18 #Javascript
JavaScript实现旋转轮播图
Aug 18 #Javascript
JavaScript定时器setTimeout()和setInterval()详解
Aug 18 #Javascript
ECMAscript 变量作用域总结概括
Aug 18 #Javascript
微信小程序之前台循环数据绑定
Aug 18 #Javascript
Vue Cli与BootStrap结合实现表格分页功能
Aug 18 #Javascript
You might like
PHP 写文本日志实现代码
2010/05/18 PHP
ThinkPHP3.1基础知识快速入门
2014/06/19 PHP
实用的PHP带公钥加密类分享(每次加密结果都不一样哦)
2014/08/20 PHP
php获取、检查类名、函数名、方法名的函数方法
2015/06/25 PHP
PHP简单生成缩略图相册的方法
2015/07/29 PHP
php文件上传类完整实例
2016/05/14 PHP
laravel-admin 后台表格筛选设置默认的查询日期方法
2019/10/03 PHP
phpfpm的作用和用法
2019/10/10 PHP
PHP实现页面静态化深入讲解
2021/03/04 PHP
jquery 关键字“拖曳搜索”之“拖曳”以及 图片“提示自适应放大”效果 的实现
2010/04/18 Javascript
一个原生的用户等级的进度条
2010/07/03 Javascript
浅谈JavaScript Math和Number对象
2015/01/26 Javascript
javascript中tostring()和valueof()的用法及两者的区别
2015/11/16 Javascript
Bootstrap每天必学之按钮(Button)插件
2016/04/25 Javascript
Thinkjs3新手入门之添加一个新的页面
2017/12/06 Javascript
浅谈jquery fullpage 插件增加头部和版权的方法
2018/03/20 jQuery
浅谈在node.js进入文件目录的问题
2018/05/13 Javascript
基于Vue+element-ui 的Table二次封装的实现
2018/07/20 Javascript
vue-cli脚手架的安装教程图解
2018/09/02 Javascript
JS实现简单的抽奖转盘效果示例
2019/02/16 Javascript
webpack4.x下babel的安装、配置及使用详解
2019/03/07 Javascript
Vue实现菜单切换功能
2020/11/08 Javascript
Python的自动化部署模块Fabric的安装及使用指南
2016/01/19 Python
浅谈python为什么不需要三目运算符和switch
2016/06/17 Python
Python实现多并发访问网站功能示例
2017/06/19 Python
python实现守护进程、守护线程、守护非守护并行
2018/05/05 Python
python快排算法详解
2019/03/04 Python
Python坐标线性插值应用实现
2019/11/13 Python
将pymysql获取到的数据类型是tuple转化为pandas方式
2020/05/15 Python
Django filter动态过滤与排序实现过程解析
2020/11/26 Python
Python用SSH连接到网络设备
2021/02/18 Python
网络维护中文求职信
2014/01/03 职场文书
医学生自我评价
2014/01/27 职场文书
四风问题专项整治工作情况报告
2014/10/28 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
微信小程序APP页面的之间的相互传递参数以及自定义组件
2022/04/19 Javascript