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

前言

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>

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

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

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

子节点的一些设置

对于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这些。至于这些属性代表什么意思我们先不着急看。先上个效果图。

那么我们的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)联系我

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

(0)

相关推荐

  • Vue插件写、用详解(附demo)

    Vue插件 1.概述 简单来说,插件就是指对Vue的功能的增强或补充. 比如说,让你在每个单页面的组件里,都可以调用某个方法,或者共享使用某个变量,或者在某个方法之前执行一段代码等 2.使用方法 总体流程应该是: [声明插件]--[写插件]--[注册插件]--[使用插件] 写插件和声明插件是同步的,然后注册到Vue对象中(不用担心重复注册),最后在写Vue组件的时候使用写的插件 声明插件 先写一个js文件,这个js文件就是插件文件,里面的基本内容如下: /* 说明: * 插件文件:service

  • Vue使用zTree插件封装树组件操作示例

    本文实例讲述了Vue使用zTree插件封装树组件操作.分享给大家供大家参考,具体如下: 1.通过npm安装jquery npm install jquery --save-dev 2.在build/webpack.base.conf文件当中引入jquery module.exports = { ... resolve: { extensions: ['.js', '.vue', '.json'], alias: { 'vue$': 'vue/dist/vue.esm.js', '@': reso

  • Vue-cli@3.0 插件系统简析

    Vue-cli@3.0 是一个全新的 Vue 项目脚手架.不同于 1.x/2.x 基于模板的脚手架,Vue-cli@3.0 采用了一套基于插件的架构,它将部分核心功能收敛至 CLI 内部,同时对开发者暴露可拓展的 API 以供开发者对 CLI 的功能进行灵活的拓展和配置.接下来我们就通过 Vue-cli@3.0 的源码来看下这套插件架构是如何设计的. 整个插件系统当中包含2个重要的组成部分: @vue/cli,提供 cli 命令服务,例如vue create创建一个新的项目: @vue/cli-

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

    前言 Tree树形控件在前端开发中必不可少,对于数据的展示现在网站大都采取树形展示.因为大数据全部展示出来对于用户来说是不友好的.今天我们自己手写一个Tree插件. iview提供的控件 iview已经很成熟了,如果说我写的控件和iview提供的控件谁更好,那肯定是选择iview , 手写控件只是为了更好的了解vue父子组件之间的通信的. 请读者还是不要拿我的控件和iview或者其他第三方的去对比.下面我们先来看看iview的Tree控件如何使用 <template> <Tree :da

  • 手写vite插件教程示例

    目录 前言 1. 什么是 vite 插件 2. 为什么要写 vite 插件 创建  vite 插件通用模板 1. 初始化 2. 配置 eslint 和 prettier(可选) 3. 新增 src/index.ts 入口 4. 创建 examples 目录 5. 配置 examples/vite-vue3 项目 6. 安装 tsup 配置运行命令 7. 开发环境运行 8. 发布 vite 的插件钩子 hooks 们 1. vite 独有的钩子 2. vite 与 rollup 的通用钩子之构建阶

  • Vue手写实现组件初渲染

    目录 前言 生成虚拟节点 将虚拟节点处理为真实节点 总结 前言 在Vue进行文本编译之后,会得到代码字符串生成的render函数.本文会基于render函数介绍以下内容: 执行render函数生成虚拟节点 通过vm._update方法,将虚拟节点渲染为真实DOM 在vm.$mount方法中,文本编译完成后,要进行组件的挂载,代码如下: Vue.prototype.$mount = function (el) { // text compile code .... mountComponent(v

  • 基于SpringCloud手写一个简易版Sentinel

    Sentinel 是什么? 随着微服务的流行,服务和服务之间的稳定性变得越来越重要.Sentinel 以流量为切入点,从流量控制.熔断降级.系统负载保护等多个维度保护服务的稳定性. 不可否认的是,Sentinel功能丰富,并且在提供好用的dashboard提供配置,但是Sentinel在集成到项目中时需要引入多个依赖,并且需要阅读相关文档,以及dashboard中的相关配置才可以接入到项目中,这个过程还是较为复杂的. 如果我们的项目并不需要这么多的功能,只是需要当某个方法或者某个功能发生异常的时

  • 基于Python手写拼音识别

    目录 一.算法构造 1.简单介绍一下knn算法 2.Python实现KNN 二.准备数据 1.将图片转换成数组矩阵 三.处理数据:训练集与测试集 1.区分训练集和测试集 2.加载数据 3.建立训练数据 四.测试数据 一.算法构造 1.简单介绍一下knn算法 KNN算法,也叫K最近邻算法.功能是分类.算法逻辑非常简单,说直白点就是:先找到跟你最近的k个邻居(假设k=5),再看你的邻居给哪个类别投票(即邻居的标签),少数服从多数,得票最多的结果就是你的类别. 在这个算法中最关键的三点: k值 :选择

  • Vue手写横向轮播图的实例

    目录 Vue手写横向轮播图 Vue常见的轮播图 Vue手写横向轮播图 前提:自己封装的轮播图,暂时没测出bug~ 效果如下图,一行三个,点击上一张/下一张 向前或向后移动一格,窗口缩放会适当变形,不影响切换 <template> <div class="swiper-template"> <div class="my-swiper-page"> <div class="page-left"> <

  • 基于Java手写一个好用的FTP操作工具类

    目录 前言 windows服务器搭建FTP服务 工具类方法 代码展示 使用示例 前言 网上百度了很多FTP的java 工具类,发现文章代码都比较久远,且代码臃肿,即使搜到了代码写的还可以的,封装的常用操作方法不全面,于是自己花了半天实现一个好用的工具类.最初想用java自带的FTPClient 的jar 去封装,后来和apache的jar工具包对比后,发现易用性远不如apache,于是决定采用apache的ftp的jar 封装ftp操作类. windows服务器搭建FTP服务 打开控制版面,图示

  • 自己动手手写jQuery插件总结

    jQuery是继Prototype之后的又一款优秀的JavaScript框架,深受广大开发者热爱,用户甚广.而jQuery一个很好的地方在 于用户的自定义,即我们可以书写自己的插件来完善jQuery的各项功能,定制自己所需要的功能,剔除冗余的代码,在页面加载时候可以有一定程度上的提 升. 面试之后,触动很大,就是你要做的是一个了解十项还是精通一项的开发者?于是花了几天时间苦逼的研读jQuery源码,了解了jQuery的事件机制.选择器以及浏览器兼容性是如何做到的等.之后就一直想要书写一款jQue

  • python实现基于SVM手写数字识别功能

    本文实例为大家分享了SVM手写数字识别功能的具体代码,供大家参考,具体内容如下 1.SVM手写数字识别 识别步骤: (1)样本图像的准备. (2)图像尺寸标准化:将图像大小都标准化为8*8大小. (3)读取未知样本图像,提取图像特征,生成图像特征组. (4)将未知测试样本图像特征组送入SVM进行测试,将测试的结果输出. 识别代码: #!/usr/bin/env python import numpy as np import mlpy import cv2 print 'loading ...'

  • 基于vue.js的分页插件详解

    Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件.想了解更多,请戳http://cn.vuejs.org/ html代码: <div class="page-bar" v-else> <ul> <li style="width: 11%" v-if="showFirst"> <a v-on:click="cur--"> <<</

随机推荐