基于 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 相关文章推荐
删除重复数据的算法
Nov 23 Javascript
使用Javascript接收get传递的值的代码
Nov 30 Javascript
JavaScript中计算网页中某个元素的位置
Jun 10 Javascript
js漂浮广告实现代码
Aug 15 Javascript
详解javascript高级定时器
Dec 31 Javascript
js实现为a标签添加事件的方法(使用闭包循环)
Aug 02 Javascript
JS高仿抛物线加入购物车特效实现代码
Feb 20 Javascript
Vue学习之路之登录注册实例代码
Jul 06 Javascript
全新打包工具parcel零配置vue开发脚手架
Jan 11 Javascript
js+html5实现手机九宫格密码解锁功能
Jul 30 Javascript
详解webpack模块加载器兼打包工具
Sep 11 Javascript
vue监听滚动事件的方法
Dec 21 Vue.js
简单实现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
基于mysql的bbs设计(一)
2006/10/09 PHP
php实现查看邮件是否已被阅读的方法
2013/12/03 PHP
ThinkPHP框架任意代码执行漏洞的利用及其修复方法
2014/07/04 PHP
php之Smarty模板使用方法示例详解
2014/07/08 PHP
Yii分页用法实例详解
2014/12/04 PHP
php实现统计目录文件大小的函数
2015/12/25 PHP
PHP模拟post提交数据方法汇总
2016/02/16 PHP
Wordpress ThickBox 点击图片显示下一张图的修改方法
2010/12/11 Javascript
JS关闭窗口或JS关闭页面的几种代码分享
2013/10/25 Javascript
jQuery设置和获取HTML、文本和值示例
2014/07/08 Javascript
jQuery检测输入的字符串包含的中英文的数量
2015/04/17 Javascript
深入理解js数组的sort排序
2016/05/28 Javascript
基于vue的fullpage.js单页滚动插件
2017/03/20 Javascript
Angular指令之restict匹配模式的详解
2017/07/27 Javascript
javascript如何用递归写一个简单的树形结构示例
2017/09/06 Javascript
详解使用VueJS开发项目中的兼容问题
2018/08/02 Javascript
15分钟上手vue3.0(小结)
2020/05/20 Javascript
jQuery+Ajax+js实现请求json格式数据并渲染到html页面操作示例
2020/06/02 jQuery
JavaScript缺少insertAfter解决方案
2020/07/03 Javascript
Vue 使用iframe引用html页面实现vue和html页面方法的调用操作
2020/11/16 Javascript
基于vue项目设置resolves.alias: '@'路径并适配webstorm
2020/12/02 Vue.js
Taro小程序自定义顶部导航栏功能的实现
2020/12/17 Javascript
[01:05]主宰至宝剑心之遗
2017/03/16 DOTA
[01:32:22]DOTA2-DPC中国联赛 正赛 Ehome vs VG BO3 第一场 2月5日
2021/03/11 DOTA
Python 爬虫多线程详解及实例代码
2016/10/08 Python
PyQt5每天必学之滑块控件QSlider
2018/04/20 Python
Django 拆分model和view的实现方法
2019/08/16 Python
浅析python中的del用法
2020/09/02 Python
详解基于 Canvas 手撸一个六边形能力图
2019/09/02 HTML / CSS
adidas瑞典官方网站:购买阿迪达斯鞋子和运动服
2019/12/11 全球购物
资产经营总监岗位职责范文
2013/12/01 职场文书
集团薪酬管理制度
2014/01/13 职场文书
银行贷款承诺书
2014/03/29 职场文书
保护校园环境倡议书
2015/04/28 职场文书
旅游投诉信范文
2015/07/02 职场文书
Java实战之用Swing实现通讯录管理系统
2021/06/13 Java/Android