基于 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 相关文章推荐
JQuyer $.post 与 $.ajax 访问WCF ajax service 时的问题需要注意的地方
Sep 20 Javascript
JS简单的轮播的图片滚动实例
Jun 17 Javascript
原生javascript实现拖动元素示例代码
Sep 01 Javascript
JavaScript实现的简单幂函数实例
Apr 17 Javascript
jquery移动点击的项目到列表最顶端的方法
Jun 24 Javascript
JS基于FileSystemObject创建一个指定路径的TXT文本文件
Aug 05 Javascript
JS获取地址栏参数的两种方法(简单实用)
Jun 14 Javascript
详解vue-router 2.0 常用基础知识点之router.push()
May 10 Javascript
详解用node搭建简单的静态资源管理器
Aug 09 Javascript
详解JavaScript栈内存与堆内存
Apr 04 Javascript
Vue 防止短时间内连续点击后多次触发请求的操作
Nov 11 Javascript
JavaScript中Object、map、weakmap的区别分析
Dec 15 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
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
浅谈json_encode用法
2015/03/05 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
利用php的ob缓存机制实现页面静态化方法
2017/07/09 PHP
ThinkPHP5 框架引入 Go AOP,PHP AOP编程项目详解
2020/05/12 PHP
Jquery.TreeView结合ASP.Net和数据库生成菜单导航条
2010/08/27 Javascript
javascript实现详细时间提醒信息效果的方法
2015/03/11 Javascript
使用AngularJS制作一个简单的RSS阅读器的教程
2015/06/18 Javascript
javascript设计简单的秒表计时器
2020/09/05 Javascript
JS折半插入排序算法实例
2015/12/02 Javascript
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
AngularJS与后端php的数据交互方法
2018/08/13 Javascript
JavaScript简单实现动态改变HTML内容的方法示例
2018/12/25 Javascript
vue组件中watch props根据v-if动态判断并挂载DOM的问题
2019/05/12 Javascript
Layui数据表格跳转到指定页的实现方法
2019/09/05 Javascript
浅谈Vue.set实际上是什么
2019/10/17 Javascript
vue 解决遍历对象显示的顺序不对问题
2019/11/07 Javascript
PYTHON 中使用 GLOBAL引发的一系列问题
2016/10/12 Python
python安装numpy和pandas的方法步骤
2019/05/27 Python
Python模块的制作方法实例分析
2019/12/21 Python
利用PyQt中的QThread类实现多线程
2020/02/18 Python
PyCharm Ctrl+Shift+F 失灵的简单有效解决操作
2021/01/15 Python
使用python实现学生信息管理系统
2021/02/25 Python
CSS3 实现雷达扫描图的示例代码
2020/09/21 HTML / CSS
Expedia印度:您的一站式在线旅游网站
2017/08/24 全球购物
本科毕业生的求职信范文
2013/11/20 职场文书
写好自荐信的几个要点
2013/12/26 职场文书
如何写你的创业计划书
2014/01/07 职场文书
运动会广播稿400字
2014/01/25 职场文书
捐助倡议书范文
2014/04/15 职场文书
后进基层党组织整改方案
2014/10/25 职场文书
人事局接收函
2015/01/31 职场文书
婚宴新娘致辞
2015/07/28 职场文书
入党后的感想
2015/08/10 职场文书
观看《信仰》心得体会
2016/01/15 职场文书
HTML基础详解(上)
2021/10/16 HTML / CSS