基于 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 相关文章推荐
checkbox全选/取消全选以及checkbox遍历jQuery实现代码
Dec 02 Javascript
jquery如何把参数列严格转换成数组实现思路
Apr 01 Javascript
JS对HTML标签select的获取、添加、删除操作
Oct 17 Javascript
对象转换为原始值的实现方法
Jun 06 Javascript
原生js实现类似fullpage的单页/全屏滚动
Jan 22 Javascript
原生JS发送异步数据请求
Jun 08 Javascript
使用Node.js搭建静态资源服务详细教程
Aug 02 Javascript
实例分析vue循环列表动态数据的处理方法
Sep 28 Javascript
教你搭建按需加载的Vue组件库(小结)
Jul 29 Javascript
vue实现Input输入框模糊查询方法
Jan 29 Javascript
mapboxgl实现带箭头轨迹线的代码
Jan 04 Javascript
原生JavaScript实现轮播图
Jan 10 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中3des加密代码(完全与.net中的兼容)
2012/08/02 PHP
php 保留字列表
2012/10/04 PHP
浅析SVN常见问题及解决方法
2013/06/21 PHP
Discuz批量替换帖子内容的方法(使用SQL更新数据库)
2014/06/23 PHP
PHP遍历数组的三种方法及效率对比分析
2015/02/12 PHP
PHP通过API获取手机号码归属地
2015/05/28 PHP
PHP+HTML+JavaScript+Css实现简单爬虫开发
2016/03/28 PHP
php用户名的密码加密更安全的方法
2019/06/21 PHP
在TP5数据库中四个字段实现无限分类的示例
2019/10/18 PHP
js实现的真正的iframe高度自适应(兼容IE,FF,Opera)
2010/03/07 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
javascript高级学习笔记整理
2011/08/14 Javascript
jquery对单选框,多选框,文本框等常见操作小结
2014/01/08 Javascript
jQuery实现新消息闪烁标题提示的方法
2015/03/11 Javascript
jQuery实现手机上输入后隐藏键盘功能
2017/01/04 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
2017/01/22 Javascript
vue+socket.io+express+mongodb 实现简易多房间在线群聊示例
2017/10/21 Javascript
three.js 入门案例详解
2018/01/23 Javascript
vue如何判断dom的class
2018/04/26 Javascript
node.js如何根据URL返回指定的图片详解
2020/10/21 Javascript
Python 匹配任意字符(包括换行符)的正则表达式写法
2009/10/29 Python
Python标准库之Sys模块使用详解
2015/05/23 Python
PyQt5实现简易计算器
2020/05/30 Python
python实现AES加密和解密
2019/03/27 Python
Python中函数的返回值示例浅析
2019/08/28 Python
python爬虫scrapy图书分类实例讲解
2020/11/23 Python
html5实现canvas阴影效果示例
2014/05/07 HTML / CSS
Expedia英国:全球最大的在线旅游公司
2017/09/07 全球购物
给海归自荐信的建议
2013/12/13 职场文书
会计职业生涯规划范文
2014/01/04 职场文书
京剧自荐信
2014/01/26 职场文书
大学生就业意向书范文
2014/04/01 职场文书
数据保密承诺书
2014/06/03 职场文书
乡镇党员群众路线教育实践活动对照检查材料思想汇报
2014/10/05 职场文书
python某漫画app逆向
2021/03/31 Python
解决MySQL报“too many connections“错误
2022/04/19 MySQL