基于 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 相关文章推荐
javascript实现动态CSS换肤技术的脚本
Jun 29 Javascript
一个简单的Ext.XTemplate的实例代码
Mar 18 Javascript
js动态创建及移除div的方法
Jun 03 Javascript
由浅入深讲解Javascript继承机制与simple-inheritance源码分析
Dec 13 Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 Javascript
详解Angular CLI + Electron 开发环境搭建
Jul 20 Javascript
setTimeout时间设置为0详细解析
Mar 13 Javascript
vue实现城市列表选择功能
Jul 16 Javascript
vue自定义tap指令及tap事件的实现
Sep 18 Javascript
js脚本中执行java后台代码方法解析
Oct 11 Javascript
element-ui tree结构实现增删改自定义功能代码
Aug 31 Javascript
openlayers实现地图弹窗
Sep 25 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常量的详解
2013/06/09 PHP
PHP Class SoapClient not found解决方法
2018/01/20 PHP
php的扩展写法总结
2019/05/14 PHP
关于Yii2框架跑脚本时内存泄漏问题的分析与解决
2019/12/01 PHP
清华大学出版的事半功倍系列 javascript全部源代码
2007/05/04 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
2013/10/23 Javascript
chrome下img加载对height()的影响示例探讨
2014/05/26 Javascript
js中的如何定位固定层的位置
2014/06/15 Javascript
JavaScript常用的返回,自动跳转,刷新,关闭语句汇总
2015/01/13 Javascript
关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
2016/05/17 Javascript
ES6正则的扩展实例详解
2017/04/25 Javascript
Angular.JS中的this指向详解
2017/05/17 Javascript
全选复选框JavaScript编写小结(附代码)
2017/08/16 Javascript
微信小程序tabBar用法实例详解
2017/12/04 Javascript
vue脚手架中配置Sass的方法
2018/01/04 Javascript
浅谈angularJS2中的界面跳转方法
2018/08/31 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
layui 动态设置checbox 选中状态的例子
2019/09/02 Javascript
vue实现直播间点赞飘心效果的示例代码
2019/09/20 Javascript
[01:04:01]2014 DOTA2华西杯精英邀请赛5 24 DK VS VG
2014/05/25 DOTA
python基础教程项目二之画幅好画
2018/04/02 Python
浅谈pandas中Dataframe的查询方法([], loc, iloc, at, iat, ix)
2018/04/10 Python
解决python ogr shp字段写入中文乱码的问题
2018/12/31 Python
关于Numpy中的行向量和列向量详解
2019/11/30 Python
深入了解Python enumerate和zip
2020/07/16 Python
吉尔德利巧克力公司:Ghirardelli Chocolate Company
2019/03/27 全球购物
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
职工代表大会主持词
2014/04/01 职场文书
内勤主管岗位职责
2014/04/03 职场文书
车队司机个人自我鉴定
2014/04/17 职场文书
化学工程专业求职信
2014/08/10 职场文书
如何使用php生成zip压缩包
2021/04/21 PHP
基于HTML十秒做出淘宝页面
2021/10/24 HTML / CSS
默认网关不可用修复后过一会又不好使了解决方法
2022/04/08 数码科技
iOS 16进一步确认,一共支持16款iPhone
2022/04/28 数码科技
MySQL运行报错:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解决方法
2022/06/14 MySQL