基于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 中的事件教程
Apr 05 Javascript
javascript支持firefox,ie7页面布局拖拽效果代码
Dec 20 Javascript
遮罩层点击按钮弹出并且具有拖动和关闭效果(两种方法)
Aug 20 Javascript
基于MVC5和Bootstrap的jQuery TreeView树形控件(一)之数据支持json字符串、list集合
Aug 11 Javascript
详解Node.js如何开发命令行工具
Aug 14 Javascript
bootstrap中使用google prettify让代码高亮的方法
Oct 21 Javascript
angular十大常见问题
Mar 07 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
Apr 14 Javascript
vue cli 全面解析
Feb 28 Javascript
详解Vue-cli中的静态资源管理(src/assets和static/的区别)
Jun 19 Javascript
jQuery表单校验插件validator使用方法详解
Feb 18 jQuery
js点击事件的执行过程实例分析【冒泡与捕获】
Apr 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
怎样辨别一杯好咖啡
2021/03/03 新手入门
PHP函数shuffle()取数组若干个随机元素的方法分析
2016/04/02 PHP
laravel 实现向公共模板中传值 (view composer)
2019/10/22 PHP
jquery仿京东导航/仿淘宝商城左侧分类导航下拉菜单效果
2013/04/24 Javascript
浏览器窗口加载和大小改变事件示例
2014/02/27 Javascript
seajs中模块的解析规则详解和模块使用总结
2014/03/12 Javascript
nodejs开发环境配置与使用
2014/11/17 NodeJs
JavaScript父子窗体间的调用方法
2015/03/31 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
2015/07/28 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
JS如何判断是否为ie浏览器的方法(包括IE10、IE11在内)
2015/12/13 Javascript
JS中改变this指向的方法(call和apply、bind)
2016/03/26 Javascript
JavaScript 函数节流详解及方法总结
2017/02/09 Javascript
w3c编程挑战_初级脚本算法实战篇
2017/06/23 Javascript
JS库之Waypoints的用法详解
2017/09/13 Javascript
图文介绍Vue父组件向子组件传值
2018/02/17 Javascript
js中innerText/textContent和innerHTML与target和currentTarget的区别
2019/01/21 Javascript
详解vue-element Tree树形控件填坑路
2019/03/26 Javascript
详解vue项目中调用百度地图API使用方法
2019/04/25 Javascript
js实现圆形显示鼠标单击位置
2020/02/11 Javascript
vue 实现element-ui中的加载中状态
2020/11/11 Javascript
[06:06]2018DOTA2亚洲邀请赛主赛事第四日战况回顾 全明星赛欢乐上演
2018/04/07 DOTA
zbar解码二维码和条形码示例
2014/02/07 Python
Windows 8.1 64bit下搭建 Scrapy 0.22 环境
2018/11/18 Python
python实现维吉尼亚加密法
2019/03/20 Python
win10安装tesserocr配置 Python使用tesserocr识别字母数字验证码
2020/01/16 Python
python3 实现口罩抽签的功能
2020/03/11 Python
Django mysqlclient安装和使用详解
2020/09/17 Python
pycharm2020.1.2永久破解激活教程,实测有效
2020/10/29 Python
西班牙多品牌鞋店连锁店:Krack
2018/11/30 全球购物
英国领先的豪华时尚家居网上商店:Amara
2019/08/12 全球购物
美团网旗下网上订餐平台:美团外卖
2020/03/05 全球购物
党校毕业心得体会
2014/09/13 职场文书
党员转正大会主持词
2015/07/02 职场文书
《给予树》教学反思
2016/03/03 职场文书
vue 自定义组件添加原生事件
2022/04/21 Vue.js