基于 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 相关文章推荐
IE8 兼容性问题(属性名区分大小写)
Jun 04 Javascript
js几秒以后倒计时跳转示例
Dec 26 Javascript
node.js中的path.normalize方法使用说明
Dec 08 Javascript
浅谈JavaScript数据类型
Mar 03 Javascript
jQuery()方法的第二个参数详解
Apr 29 Javascript
jQuery拖动元素并对元素进行重新排序
Dec 30 Javascript
Bootstrap模态对话框的简单使用
Apr 29 Javascript
浅谈JavaScript的全局变量与局部变量
Jun 10 Javascript
ionic 自定义弹框效果
Jun 27 Javascript
layui问题之自动滚动二级iframe页面到指定位置的方法
Sep 18 Javascript
webpack 如何同时输出压缩和未压缩的文件的实现步骤
Jun 05 Javascript
Node.js中出现未捕获异常的处理方法
Jun 29 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实现多级树型菜单
2006/10/09 PHP
PHP使用range协议实现输出文件断点续传代码实例
2014/07/04 PHP
PHP判断是否连接上网络的方法
2015/07/01 PHP
PHP中如何使用session实现保存用户登录信息
2015/10/20 PHP
PHP中多线程的两个实现方法
2016/10/14 PHP
php使用自定义函数实现汉字分割替换功能示例
2017/01/30 PHP
Mootools 1.2教程 正则表达式
2009/09/15 Javascript
node.js中的fs.stat方法使用说明
2014/12/16 Javascript
AngularJS实现表单验证
2015/01/28 Javascript
JavaScript实现的类字典插入或更新方法实例
2015/07/10 Javascript
js+div实现文字滚动和图片切换效果代码
2015/08/27 Javascript
微信小程序  modal详解及实例代码
2016/11/09 Javascript
Node.js Mongodb 密码特殊字符 @的解决方法
2017/04/11 Javascript
Vue.js在使用中的一些注意知识点
2017/04/29 Javascript
你可能不知道的JSON.stringify()详解
2017/08/17 Javascript
浅谈react-router HashRouter和BrowserRouter的使用
2017/12/29 Javascript
Vue动态面包屑功能的实现方法
2019/07/01 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
vue实现简单加法计算器
2020/10/22 Javascript
使用Python来开发Markdown脚本扩展的实例分享
2016/03/04 Python
Python常用算法学习基础教程
2017/04/13 Python
python 环境变量和import模块导入方法(详解)
2017/07/11 Python
Python实现随机生成手机号及正则验证手机号的方法
2018/04/25 Python
Python基础之函数的定义与使用示例
2019/03/23 Python
tensorflow如何批量读取图片
2019/08/29 Python
python爬虫用scrapy获取影片的实例分析
2020/11/23 Python
东芝官网商城:还原日式美学,打造美好生活
2018/12/27 全球购物
高中语文教学反思
2014/01/16 职场文书
事业单位考核材料
2014/05/21 职场文书
应聘护士求职信
2014/07/21 职场文书
个人三严三实对照检查材料
2014/09/25 职场文书
董事长开业致辞
2015/07/29 职场文书
Spring Bean的实例化之属性注入源码剖析过程
2021/06/13 Java/Android
Python多线程实用方法以及共享变量资源竞争问题
2022/04/12 Python
Python四款GUI图形界面库介绍
2022/06/05 Python
Python 避免字典和元组的多重嵌套问题
2022/07/15 Python