基于vue手写tree插件的那点事儿


Posted in Javascript onAugust 20, 2019

前言

Tree树形控件在前端开发中必不可少,对于数据的展示现在网站大都采取树形展示。因为大数据全部展示出来对于用户来说是不友好的。今天我们自己手写一个Tree插件。

iview提供的控件

iview已经很成熟了,如果说我写的控件和iview提供的控件谁更好,那肯定是选择iview , 手写控件只是为了更好的了解vue父子组件之间的通信的。 请读者还是不要拿我的控件和iview或者其他第三方的去对比。下面我们先来看看iview的Tree控件如何使用

<template>
  <Tree :data="data2" show-checkbox></Tree>
</template>

<script>
  export default {
    data () {
      return {
        data2: [
          {
            title: 'parent 1',
            expand: true,
            children: [
              {
                title: 'parent 1-1',
                expand: true,
                children: [
                  {
                    title: 'leaf 1-1-1'
                  },
                  {
                    title: 'leaf 1-1-2'
                  }
                ]
              },
              {
                title: 'parent 1-2',
                expand: true,
                children: [
                  {
                    title: 'leaf 1-2-1'
                  },
                  {
                    title: 'leaf 1-2-1'
                  }
                ]
              }
            ]
          }
        ]
      }
    }
  }
</script>

上述的代码形成的效果如下

基于vue手写tree插件的那点事儿

在使用Tree控件时在Template中还有如下树形可以使用(根据自己需求)

基于vue手写tree插件的那点事儿

然后就是控件的一些事件捕获

基于vue手写tree插件的那点事儿

子节点的一些设置

基于vue手写tree插件的那点事儿

对于iview的Tree总结就是一句话:到位!。在这里小编也推荐大家使用iview来开发。这个框架对于后端程序员来说是个福利。因为我们不需要了解太专业的前端的只是就能够满足80%的需求了。

手写控件

同样的我们先来看看他的用法其实和iview一样。用我们封装好的模板就行了。下面是做一个部门树。部门下面挂着人员这个功能。

<zxhtree
    v-if="userChange"
    class="item"
    treekey="deptId"
    treename="deptName"
    treechildren="children"
    :model="deptData"
    :ids="sysUserRole.deptIds"
    :names="sysUserRole.deptNames"
    @keyname="selectedUserObj"
>
</zxhtree>

js就是去填补上述的数据,比如deptData、sysUserRole这些。至于这些属性代表什么意思我们先不着急看。先上个效果图。

基于vue手写tree插件的那点事儿

那么我们的zxhtree控件是在哪里注册的呢,这里被我们抽离在component.js里。Vue.component('zxhtree', {});
继续在zxhtree里看除绑定的节点是template: '#tree-template'
tree-template的模板是在component.html中写好的

<script type="text/x-template" id="tree-template">
  <div>
    <tree-item
        class="item"
        :treekey="treekey"
        v-for="(model, index) in model"
        :treename="treename"
        :treechildren="treechildren"
        :model="model"
        :ids="ids"
        :names="names"
        @keyname="selectedObj"
        @data="synchdata"
    >
    </tree-item>
  </div>
</script>

而在tree-template用到的tree-item控件才是真正的tree控件。这里是为了将树形包裹起来,所以才包裹了一层模板。
tree-item对应的模板代码是

<script type="text/x-template" id="item-template">
  <ul class="ztree">
    <li class="level0" @blur="blur" @focus="focus" tabindex="0" hidefocus="true" treenode="">
      <input type="checkbox" :disabled="model.disabled" :ref="model[treename]" :checked="checkStatus" @click="selectedObj"/>
      <span title="" @click="toggle" :class="openStatus" treenode_switch=""></span>
      <a :class="selectClass" treenode_a="" onclick="" target="_blank" style="" :title="model[treename]">
        <span title="" treenode_ico="" class="button ico_open" style=""></span>
        <span @dblclick="toggle" class="node_name">{{model[treename]}}</span>
      </a>
      <tree-item
        class="item"
        v-show="open"
        v-for="(model, index) in model[treechildren]"
        :key="index"
        :model="model"
        :treekey="treekey"
        :treename="treename"
        :vistreekey="vistreekey"
        :vistreename="vistreename"
        :treechildren="treechildren"
        ref="child"
        @keyname="keyname"
      >
      </tree-item>
    </li>
  </ul>
</script>

可以很明显的看到这里我们使用了递归进行展示树形结构。因为树形结构你无法确定层级。所以在里面又使用了针对子节点的展示tree-item.

属性 含义 示例
treekey 内部树形展示 deptId
vistreekey 树形展示key deptId
ids 默认显示的数据
names 默认显示的数据
treename 内部真是展示数据 deptName
vistreename 树形展示数据 deptName
treechildren 当前树的子节点数据
model 当前树的数据
(M)keyname 用于接受返回的数据

手写控件扩展

控件接受数据处理逻辑

//接收到数据在外面套一层
if(this.model[this.treekey]==undefined){
  this.treekey=this.vistreekey;
}
if(this.model[this.treename]==undefined){
  this.treename=this.vistreename;
}
if (this.model.disabled == true) {
  this.model.disabled = 'disabled';
}
console.log('组件注册了吗');
if ((','+this.ids+',').indexOf(','+this.model[this.treekey]+',') == -1) {
  this.checkStatus = false;
  this.model.checkStatus=this.checkStatus;
} else {
  this.checkStatus=true;
  this.model.checkStatus=this.checkStatus;
  this.treekeys[this.model[this.treekey]]= this.checkStatus;
  this.treenames[this.model[this.treename]]= this.checkStatus;
  this.opt.key=this.treekeys;
  this.opt['name']=this.treenames;
}
if(this.ids!=''){
  var idarr = this.ids;
  for(var index in idarr){
    this.treekeys[idarr[index]]=true;
  }
  if (this.names.indexOf(",") == -1&&this.names!='') {
    this.treenames[this.names]=true;
  }else{
    var namearr = this.names.split(",");
    for(var index in namearr){
      this.treenames[namearr[index]]=true;
    }
  }
}

渲染默认数据

var newOpt ={'key':{},'name':{}};
  newOpt.key = Object.assign(this.opt.key, opt.key);
  newOpt.name = Object.assign(this.opt.name, opt.name);
  var flag=false;
  for(var index in this.model[this.treechildren]){
    if(newOpt.key[this.model[this.treechildren][index][this.treekey]]!=true){
      flag=true;
    }
  }
  if(!flag){
    newOpt.key[this.model[this.treekey]]=true;
    newOpt.name[this.model[this.treename]]=true;
    this.checkStatus=true;
    this.model.checkStatus=true;
  }
  for(var key in newOpt){
    this.filterRealCheck(newOpt[key]);
  }
  this.opt=newOpt;
  this.$emit('keyname', newOpt);

选择节点数据处理

if(selected instanceof MouseEvent){
  this.checkStatus=!this.checkStatus;
}else{
  this.checkStatus=selected;
}

this.model.checkStatus=this.checkStatus;
if (this.model.expected != true) {
  this.treekeys[this.model[this.treekey]]= this.checkStatus;
  this.treenames[this.model[this.treename]]= this.checkStatus;
  this.opt.key=this.treekeys;
  this.opt['name']=this.treenames;
}
for(var index in this.$refs.child){
  this.$refs.child[index].selectedObj(this.checkStatus);
}

this.$emit('keyname', this.opt);

手写控件总结

因为笔者是侧重后端,所以前端知识不是很好,这个组件写的也是很乱。这个组件是之前临时写的。里面没有进行系统的梳理,上述的逻辑也是很乱。读者需要的可以选择下列加入战队(#addMe)联系我

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
关于Jqzoom的使用心得 jquery放大镜效果插件
Apr 12 Javascript
JavaScript实现数字数组正序排列的方法
Apr 06 Javascript
jQuery插件zTree实现删除树子节点的方法示例
Mar 08 Javascript
javascript编程开发中取色器及封装$函数用法示例
Aug 09 Javascript
ES6知识点整理之对象解构赋值应用示例
Apr 17 Javascript
Vue使用watch监听一个对象中的属性的实现方法
May 10 Javascript
vue.js循环radio的实例
Nov 07 Javascript
angular8和ngrx8结合使用的步骤介绍
Dec 01 Javascript
javascrpt密码强度校验函数详解
Mar 18 Javascript
Element Backtop回到顶部的具体使用
Jul 27 Javascript
如何用JavaScript实现一个数组惰性求值库
May 05 Javascript
webpack的移动端适配方案小结
Jul 25 Javascript
详解基于原生JS验证表单组件xy-form
Aug 20 #Javascript
详解微信小程序图片地扯转base64解决方案
Aug 18 #Javascript
wx-charts 微信小程序图表插件的具体使用
Aug 18 #Javascript
微信小程序canvas绘制圆角base64图片的实现
Aug 18 #Javascript
Node.js从字符串生成文件流的实现方法
Aug 18 #Javascript
微信公众号生成新浪短网址的实现(快速生成)
Aug 18 #Javascript
js 实现 list转换成tree的方法示例(数组到树)
Aug 18 #Javascript
You might like
欧美媒体选出10年前最流行的17部动画
2017/01/18 日漫
PHP中echo,print_r与var_dump区别分析
2014/09/29 PHP
Yii不依赖Model的表单生成器用法实例
2014/12/04 PHP
在IE模态窗口中自由查看HTML源码的方法
2007/03/08 Javascript
javascript复制对象使用说明
2011/06/28 Javascript
jQuery中ajax的post()方法用法实例
2014/12/26 Javascript
Javascript编写俄罗斯方块思路及实例
2015/07/07 Javascript
javascript每日必学之循环
2016/02/19 Javascript
第七篇Bootstrap表单布局实例代码详解(三种表单布局)
2016/06/21 Javascript
JS中对Cookie的操作详解
2016/08/05 Javascript
详解vue 计算属性与方法跟侦听器区别(面试考点)
2018/04/23 Javascript
详解Vue单元测试case写法
2018/05/24 Javascript
Vue 实时监听窗口变化 windowresize的两种方法
2018/11/06 Javascript
javascript 函数的暂停和恢复实例详解
2020/04/25 Javascript
koa中间件核心(koa-compose)源码解读分析
2020/06/15 Javascript
Element DateTimePicker日期时间选择器的使用示例
2020/07/27 Javascript
微信小程序实现底部弹出框
2020/11/18 Javascript
python基于phantomjs实现导入图片
2016/05/13 Python
python爬虫之百度API调用方法
2017/06/11 Python
Python反射和内置方法重写操作详解
2018/08/27 Python
python使用ddt过程中遇到的问题及解决方案【推荐】
2018/10/29 Python
python实现对任意大小图片均匀切割的示例
2018/12/05 Python
Python 实例方法、类方法、静态方法的区别与作用
2019/08/14 Python
Python上下文管理器类和上下文管理器装饰器contextmanager用法实例分析
2019/11/07 Python
妙用itchat! python实现久坐提醒功能
2019/11/25 Python
pyqt5 QlistView列表显示的实现示例
2020/03/24 Python
python中numpy数组与list相互转换实例方法
2021/01/29 Python
StubHub哥伦比亚:购买和出售您的门票
2016/10/20 全球购物
Does C# support multiple inheritance? (C#支持多重继承吗)
2012/01/04 面试题
聘用意向书范本
2014/04/01 职场文书
资助贫困学生倡议书
2014/05/16 职场文书
计算机系统管理员求职信
2014/06/20 职场文书
法律专业大学生职业生涯规划书:向目标一步步迈进
2014/09/22 职场文书
党员专题组织生活会发言材料
2014/10/17 职场文书
少年犯观后感
2015/06/11 职场文书
详解Mysql数据库平滑扩容解决高并发和大数据量问题
2022/05/25 MySQL