基于 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 相关文章推荐
一些mootools的学习资源
Feb 07 Javascript
javascript XMLHttpRequest对象全面剖析
Apr 24 Javascript
javascript判断iphone/android手机横竖屏模式的函数
Dec 20 Javascript
一个小例子解释如何来阻止Jquery事件冒泡
Jul 17 Javascript
window.open()实现post传递参数
Mar 12 Javascript
浅谈JavaScript中小数和大整数的精度丢失
May 31 Javascript
关于backbone url请求中参数带有中文存入数据库是乱码的快速解决办法
Jun 13 Javascript
浅谈jquery拼接字符串效率比较高的方法
Feb 22 Javascript
微信小程序实现点击按钮修改view标签背景颜色功能示例【附demo源码下载】
Dec 06 Javascript
JavaScript实现简单轮播图效果
Dec 01 Javascript
Vue2.x通用条件搜索组件的封装及应用详解
May 28 Javascript
js中延迟加载和预加载的具体使用
Jan 14 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永久登录、记住我功能实现方法和安全做法
2015/04/27 PHP
PHP面向对象程序设计实例分析
2016/01/26 PHP
PHP7使用ODBC连接SQL Server2008 R2数据库示例【基于thinkPHP5.1框架】
2019/05/06 PHP
prettify 代码高亮着色器google出品
2010/12/28 Javascript
jQuery之折叠面板的深入解析
2013/06/19 Javascript
AngularJS入门教程之Hello World!
2014/12/06 Javascript
node.js中的fs.readdirSync方法使用说明
2014/12/17 Javascript
jQuery实现的进度条效果
2015/07/15 Javascript
js小数运算出现多位小数如何解决
2015/10/08 Javascript
Vue 进阶教程之v-model详解
2017/05/06 Javascript
node.js利用mongoose获取mongodb数据的格式化问题详解
2017/10/06 Javascript
详解JS数值Number类型
2018/02/07 Javascript
Vue 全局loading组件实例详解
2018/05/29 Javascript
200行HTML+JavaScript实现年会抽奖程序
2019/01/22 Javascript
使用Vue.js中的过滤器实现幂方求值的方法
2019/08/27 Javascript
[55:42]VG vs VGJ.T 2018国际邀请赛淘汰赛BO1 8.21
2018/08/22 DOTA
[01:11:21]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第一场 3月6日
2021/03/11 DOTA
python最长回文串算法
2018/06/04 Python
详解Python 字符串相似性的几种度量方法
2019/08/29 Python
PyTorch预训练的实现
2019/09/18 Python
Python列表如何更新值
2020/05/27 Python
使用CSS3来绘制一个月食图案
2015/07/18 HTML / CSS
css3遮罩层镂空效果的多种实现方法
2020/05/11 HTML / CSS
html5 兼容IE6结构的实现代码
2012/05/14 HTML / CSS
采用专利算法搜索最廉价的机票:CheapAir
2016/09/10 全球购物
如何从一个文件档案的尾端新增记录
2016/12/02 面试题
后勤副校长自我鉴定
2013/10/13 职场文书
机械设计及其自动化专业推荐信
2013/10/31 职场文书
高三地理教学反思
2014/01/11 职场文书
青年文明号复核材料
2014/02/11 职场文书
小学生作文评语大全
2014/04/21 职场文书
人力资源管理专业毕业生自荐书
2014/05/25 职场文书
甜品店创业计划书
2014/09/21 职场文书
幼儿教师远程研修感悟
2015/11/18 职场文书
详解Python flask的前后端交互
2022/03/31 Python
使用ICOM IC-R9500接收机同时测评十台收音机中波接收性能
2022/05/10 无线电