基于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 相关文章推荐
JavaScript 密码强度判断代码
Sep 05 Javascript
jquery 弹出层实现代码
Oct 30 Javascript
Jquery中对数组的操作代码
Aug 12 Javascript
javascript学习笔记(八) js内置对象
Jun 19 Javascript
jquery中cookie用法实例详解(获取,存储,删除等)
Jan 04 Javascript
javascript+html5+css3自定义提示窗口
Jun 21 Javascript
vue.js实现条件渲染的实例代码
Jun 22 Javascript
使用Angular 6创建各种动画效果的方法
Oct 10 Javascript
微信小程序常用赋值方法小结
Apr 30 Javascript
vue如何限制只能输入正负数及小数
Jul 04 Javascript
Vue实现push数组并删除的例子
Nov 01 Javascript
JavaScript 定时器详情
Nov 11 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
mysql下创建字段并设置主键的php代码
2010/05/16 PHP
作为PHP程序员应该了解MongoDB的五件事
2013/06/03 PHP
PHP中使用gettext解决国际化问题的例子(i18n)
2014/06/13 PHP
全面解析PHP验证码的实现原理 附php验证码小案例
2016/08/17 PHP
php 常用的系统函数
2017/02/07 PHP
Yii框架分页实现方法详解
2017/05/20 PHP
在 IE 中调用 javascript 打开 Excel 表
2006/12/21 Javascript
Javascript模块模式分析
2008/05/16 Javascript
extjs关于treePanel+chekBox全部选中以及清空选中问题探讨
2013/04/02 Javascript
Node.js中HTTP模块与事件模块详解
2014/11/14 Javascript
jquery实现页面虚拟键盘特效
2015/08/08 Javascript
javascript正则表达式中分组详解
2016/07/17 Javascript
jQuery判断自定义属性data-val用法示例
2019/01/07 jQuery
用node撸一个监测复联4开售短信提醒的实现代码
2019/04/10 Javascript
详解ECMAScript2019/ES10新属性
2019/12/06 Javascript
原生javascript制作的拼图游戏实现方法详解
2020/02/23 Javascript
原生微信小程序开发中 redux 的使用详解
2021/02/18 Javascript
[04:13]2018国际邀请赛典藏宝瓶Ⅱ饰品一览
2018/07/21 DOTA
Python中常见的数据类型小结
2015/08/29 Python
python中reload(module)的用法示例详解
2017/09/15 Python
用python实现k近邻算法的示例代码
2018/09/06 Python
Python multiprocessing多进程原理与应用示例
2019/02/28 Python
pandas实现将dataframe满足某一条件的值选出
2019/06/12 Python
python 计算两个列表的相关系数的实现
2019/08/29 Python
Python autoescape标签用法解析
2020/01/17 Python
Pycharm IDE的安装和使用教程详解
2020/04/30 Python
Python 利用OpenCV给照片换底色的示例代码
2020/08/03 Python
西班牙最大的在线滑板和街头服饰商店:Fillow.net
2019/04/15 全球购物
医生进修自我鉴定
2014/01/19 职场文书
幼儿园消防安全制度
2014/01/26 职场文书
病人写给医生的感谢信
2015/01/23 职场文书
学风建设主题班会
2015/08/17 职场文书
《陶罐和铁罐》教学反思
2016/03/03 职场文书
创业项目(超低成本创业项目)
2019/08/16 职场文书
Java方法重载和方法重写的区别到底在哪?
2021/06/11 Java/Android
Vue vee-validate插件的简单使用
2021/06/22 Vue.js