基于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 相关文章推荐
js string 转 int 注意的问题小结
Aug 15 Javascript
jquery 页面滚动到底部自动加载插件集合
Jan 31 Javascript
无限树Jquery插件zTree的常用功能特性总结
Sep 11 Javascript
js剪切板应用clipboardData实例解析
May 29 Javascript
JavaScript中清空数组的方法总结
Dec 02 Javascript
jquery 手势密码插件
Mar 17 Javascript
JS库 Highlightjs 添加代码行号的实现代码
Sep 13 Javascript
Vue项目自动转换 px 为 rem的实现方法
Oct 29 Javascript
说说Vuex的getters属性的具体用法
Apr 15 Javascript
深入理解Vue keep-alive及实践总结
Aug 21 Javascript
Nuxt.js实现一个SSR的前端博客的示例代码
Sep 06 Javascript
webpack 最佳配置指北(推荐)
Jan 07 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
PHP Trait代码复用类与多继承实现方法详解
2019/06/17 PHP
Array的push与unshift方法性能比较分析
2011/03/05 Javascript
jQuery实现炫酷的鼠标轨迹特效
2015/02/01 Javascript
nodejs实现HTTPS发起POST请求
2015/04/23 NodeJs
jQuery解析Json实例详解
2015/11/24 Javascript
js实现控制textarea输入字符串的个数,鼠标按下抬起判断输入字符数
2016/10/25 Javascript
JavaScript构建自己的对象示例
2016/11/29 Javascript
JS实现图片放大镜插件详解
2017/11/06 Javascript
angularJs提交文本框数据到后台的方法
2018/10/08 Javascript
vue 中几种传值方法(3种)
2019/11/12 Javascript
[02:56]《DAC最前线》之国外战队抵达上海备战亚洲邀请赛
2015/01/28 DOTA
[05:04]DOTA2上海特级锦标赛主赛事第二日TOP10
2016/03/04 DOTA
调试Python程序代码的几种方法总结
2015/04/28 Python
Python中类型关系和继承关系实例详解
2015/05/25 Python
Python 专题三 字符串的基础知识
2017/03/19 Python
python使用Plotly绘图工具绘制柱状图
2019/04/01 Python
python3下载抖音视频的完整代码
2019/06/05 Python
python绘制多个子图的实例
2019/07/07 Python
利用Python实现Shp格式向GeoJSON的转换方法
2019/07/09 Python
浅析Python+OpenCV使用摄像头追踪人脸面部血液变化实现脉搏评估
2019/10/17 Python
基于python监控程序是否关闭
2020/01/14 Python
Python任务自动化工具tox使用教程
2020/03/17 Python
html5 localStorage本地存储_动力节点Java学院整理
2017/07/06 HTML / CSS
英国轻奢珠宝品牌:Astley Clarke
2016/12/18 全球购物
我的求职计划书
2014/01/10 职场文书
金融行业职业生涯规划范文
2014/01/17 职场文书
简历的自我评价
2014/02/03 职场文书
新品发布会主持词
2014/04/02 职场文书
高三毕业寄语
2014/04/10 职场文书
家庭教育教师培训学习体会
2016/01/14 职场文书
小学体育队列队形教学反思
2016/02/16 职场文书
Python实战之实现康威生命游戏
2021/04/26 Python
一文读懂navicat for mysql基础知识
2021/05/31 MySQL
redis实现的四种常见限流策略
2021/06/18 Redis
详解MySql中InnoDB存储引擎中的各种锁
2022/02/12 MySQL
Spring Boot 实现 WebSocket
2022/04/30 Java/Android