基于 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将数据库中的TEXT类型数据动态赋值到TEXTAREA中
Apr 20 Javascript
Jquey拖拽控件Draggable使用方法(asp.net环境)
Sep 28 Javascript
原生javascript兼容性测试实例
Jul 01 Javascript
用js将内容复制到剪贴板兼容浏览器
Mar 18 Javascript
jQuery中Form相关知识汇总
Jan 06 Javascript
jQuery插件Zclip实现完美兼容个浏览器点击复制内容到剪贴板
Apr 30 Javascript
基于JavaScript判断浏览器到底是关闭还是刷新(超准确)
Feb 01 Javascript
手机Web APP如何实现分享多平台功能
Aug 19 Javascript
jQuery序列化表单成对象的简单实现
Nov 29 Javascript
JS中this的指向以及call、apply的作用
May 06 Javascript
TypeScript魔法堂之枚举的超实用手册
Oct 29 Javascript
基于javascript实现移动端轮播图效果
Dec 21 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 编程安全性小结
2010/01/08 PHP
LotusPhp笔记之:Cookie组件的使用详解
2013/05/06 PHP
PHP设计模式之适配器模式代码实例
2015/05/11 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
实例分析PHP中PHPMailer发邮件
2017/12/13 PHP
PHP函数用法详解【初始化、嵌套、内置函数等】
2020/06/02 PHP
菜鸟javascript基础整理1
2010/12/06 Javascript
JS实现图片翻书效果示例代码
2013/09/09 Javascript
js动态添加onclick事件可传参数与不传参数
2014/07/29 Javascript
js替换字符串中所有指定的字符(实现代码)
2016/08/17 Javascript
Vue.js列表渲染绑定jQuery插件的正确姿势
2017/06/29 jQuery
实例讲解DataTables固定表格宽度(设置横向滚动条)
2017/07/11 Javascript
用Vue写一个分页器的示例代码
2018/04/22 Javascript
20个必会的JavaScript面试题(小结)
2019/07/02 Javascript
elementui实现预览图片组件二次封装
2020/12/29 Javascript
使用python实现baidu hi自动登录的代码
2013/02/10 Python
分享一个可以生成各种进制格式IP的小工具实例代码
2017/07/28 Python
MxNet预训练模型到Pytorch模型的转换方式
2020/05/25 Python
Django-simple-captcha验证码包使用方法详解
2020/11/28 Python
Django后端按照日期查询的方法教程
2021/02/28 Python
HTML5中5个简单实用的API(第二篇,含全屏、可见性、拍照、预加载、电池状态)
2014/05/07 HTML / CSS
奥地利汽车配件店:Pkwteile.at
2017/03/10 全球购物
linux面试题参考答案(4)
2013/01/28 面试题
高中毕业生自我鉴定
2013/11/03 职场文书
教师专业理论水平的自我评价分享
2013/11/09 职场文书
会计专业自我鉴定范文
2013/12/29 职场文书
机电专业个人求职信范文
2013/12/30 职场文书
高中生期末评语
2014/01/28 职场文书
化学教学随笔感言
2014/02/19 职场文书
如何写求职信
2014/05/24 职场文书
2014年学校领导班子对照检查材料
2014/09/19 职场文书
优秀班主任先进事迹材料
2014/12/16 职场文书
培训后的感想
2015/08/07 职场文书
学生会主席任命书
2015/09/21 职场文书
Win11如何修改dns?Win11修改dns图文教程
2022/01/18 数码科技