基于 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 相关文章推荐
js判断浏览器类型的方法
Aug 07 Javascript
jQuery制作仿腾讯web qq用户体验桌面
Aug 20 Javascript
浅析IE10兼容性问题(frameset的cols属性)
Jan 03 Javascript
js调用iframe实现打印页面内容的方法
Mar 04 Javascript
javascript写的异步加载js文件函数(支持数组传参)
Jun 07 Javascript
JS实现的竖向折叠菜单代码
Oct 21 Javascript
Bootstrap如何创建表单
Oct 21 Javascript
微信小程序实现上传图片功能
May 28 Javascript
Vue项目pdf(base64)转图片遇到的问题及解决方法
Oct 19 Javascript
浅谈Vue.js 关于页面加载完成后执行一个方法的问题
Apr 01 Javascript
在vue-cli创建的项目中使用sass操作
Aug 10 Javascript
Vue前端判断数据对象是否为空的实例
Sep 02 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 文件上传类代码
2011/08/06 PHP
js新闻滚动 js如何实现新闻滚动效果
2013/01/07 Javascript
浅析JavaScript中的类型和对象
2013/11/29 Javascript
Javascript获取CSS伪元素属性的实现代码
2014/09/28 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
window.open()实现post传递参数
2015/03/12 Javascript
JavaScript实现拖拽网页内元素的方法
2015/04/15 Javascript
自己编写的支持Ajax验证的JS表单验证插件
2015/05/15 Javascript
js数组如何添加json数据及js数组与json的区别
2015/10/27 Javascript
只需五句话搞定JavaScript作用域(经典)
2016/07/26 Javascript
原生js实现addclass,removeclass,toggleclasss实例
2016/11/24 Javascript
微信小程序开发的四十个技术窍门总结(推荐)
2017/01/23 Javascript
关于js的三种使用方式(行内js、内部js、外部js)的程序代码
2018/05/05 Javascript
JS数组去重的6种方法完整实例
2018/12/08 Javascript
uin-app+mockjs实现本地数据模拟
2020/08/26 Javascript
解决Vue watch里调用方法的坑
2020/11/07 Javascript
[01:23:59]2018DOTA2亚洲邀请赛 4.1 小组赛 B组 VP vs Secret
2018/04/03 DOTA
详解Python中for循环的使用
2015/04/14 Python
对python自动生成接口测试的示例讲解
2018/11/30 Python
Python文件路径名的操作方法
2019/10/30 Python
Python Django中间件,中间件函数,全局异常处理操作示例
2019/11/08 Python
解决pycharm最左侧Tool Buttons显示不全的问题
2019/12/17 Python
python中提高pip install速度
2020/02/14 Python
Python控制台实现交互式环境执行
2020/06/09 Python
keras 解决加载lstm+crf模型出错的问题
2020/06/10 Python
Python3合并两个有序数组代码实例
2020/08/11 Python
详解css3中dispaly的Grid布局与Flex布局
2020/09/11 HTML / CSS
Brydge英国:适用于Apple iPad和Microsoft Surface Pro的蓝牙键盘
2019/05/16 全球购物
财务经理的岗位职责
2013/12/17 职场文书
销售顾问岗位职责
2014/02/25 职场文书
信用卡工资证明范本
2014/10/17 职场文书
酒店辞职书怎么写
2015/02/26 职场文书
二手房购房意向书
2015/05/09 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
党员干部学习心得体会
2016/01/23 职场文书
Python爬取奶茶店数据分析哪家最好喝以及性价比
2022/09/23 Python