el-tree公共组件(带操作按钮)源码分享

介绍一款基于vue-elementui的tree树形公共组件

效果如下图:

13a3a72e549540fabc3c359ad3f58e27.png

提供源码:

template

<template>
  <div class="el-tree-div" :class="{'show-tree':showTree,'hide-tree':!showTree}">
    <div class="el-tree-top">
      <div class="el-tree-title">
        <span v-show="showTree">{{treeTitle}}</span>
        <el-link type="primary" :underline="false" class="inline-block refresh-tree" v-show="showTree&&refresh" @click="clickFresh">
          <svg-icon icon-class="refresh"/>刷新</el-link>
      </div>
      <svg-icon class="inline-block change-nav-i show-tree-icon" :icon-class="showTree?'put':'open'" @click.native="changeShowTree"/>
    </div>
    <div class="el-tree-content" v-show="showTree">
      <el-input placeholder="输入关键字进行过滤" v-model.trim="filterText" clearable size="small"></el-input>
      <div class="tree-body" :class="{'can-add-first-node':canAddFirstNode}">
        <el-tree
          :class="{'tree-no-data':!treeData}"
          ref="tree"
          :data="treeData"
          :show-checkbox="showCheck"
          :check-strictly="checkStrictly"
          :default-expand-all="defaultExpandAll"
          :expand-on-click-node="false"
          highlight-current
          @node-click="handleNodeClick"
          @check-change="handleCheckChange"
          node-key="id"
          :default-expanded-keys="[]"
          :default-checked-keys="[]"
          :filter-node-method="filterNode"
          :props="treeProps"
          :render-content="showRender?renderContent:''">
        </el-tree>
      </div>
    </div>
  </div>
</template>

script

<script>
export default {
  name: 'el-tree-div',
  props:['treeData','treeTitle','showRender','refresh','delMsg','showCheck','checkStrictly','defaultExpandAll','showAllBtn','canAddFirstNode'],
  components: {},
  data() {
    return {
      showTree:true,
      filterText: '',
      treeProps: {
        children: 'children',
        label: 'label'
      },
    };
  },
  created() {

  },
  mounted() {
    this.filterText = '';
  },
  methods: {
    filterNode(value, data) {
      if (!value) return true;
      return data.label.indexOf(value) !== -1;
    },
    // check点击
    handleCheckChange(data) {
      this.$emit("checkNode",data,this.$refs.tree.getCheckedNodes());
    },
    // 点击节点
    handleNodeClick(data) {
      this.$emit("clickNode",data);
    },
    // 返回选中节点数据
    getCheckedNodes() {
      this.$emit("getCheckedNodes",this.$refs.tree.getCheckedNodes());
    },
    // 返回选中节点key数组
    getCheckedKeys() {
      this.$emit("getCheckedKeys",this.$refs.tree.getCheckedKeys());
    },
    // 通过node节点渲染选中的元素
    setCheckedNodes(nodes) {
      this.$refs.tree.setCheckedNodes(nodes);
    },
    // 通过id数组渲染选中的元素
    setCheckedKeys(arr) {
      this.$refs.tree.setCheckedKeys(arr);
    },
    // 移除tree中选中的元素
    delTreeCheck(id){
      let getCheckedKeys = this.$refs.tree.getCheckedKeys();
      for(var i in getCheckedKeys){
        if(getCheckedKeys[i] == id){
          getCheckedKeys.splice(i,1);
        }
      }
      this.setCheckedKeys(getCheckedKeys);
    },
    // 折叠展开tree
    changeShowTree(){
      if(this.showTree){
        this.$emit("changeShowTree",false);
      }else{
        this.$emit("changeShowTree",true);
      }
      this.showTree = !this.showTree;
    },
    // 渲染树形图自定义插件
    renderContent: function(h, data) {
        let _this = this;
        return h('span', {}, [
            h('span', data.data.label),
            h("el-link", {
                class: 'article-classify-add',
                props: {
                    type: 'info'
                },
                title: '添加',
                on: {
                    click: function(event) {
              event.stopPropagation();
              _this.$emit("getAdd",data.data);
                        // _this.articleClassifyAdd(event,data.data);
                    },
                }
            }, ''),
            h("el-link", {
                class: 'article-classify-edit',
                props: {
                    type: 'primary'
                },
                title: '编辑',
                on: {
                    click: function(event) {
              event.stopPropagation();
              _this.$emit("getEdit",data.data);
                        // _this.articleClassifyEdit(event,data.data);
                    },
                }
            }, ''),
            h("el-link", {
                class: data.data.parentId != "0" || this.showAllBtn ? 'article-classify-del' : '',
                props: {
                    type: 'danger'
                },
                title: '删除',
                on: {
                    click: function(event) {
              event.stopPropagation();
              if(data.data.parentId == "0" && !_this.showAllBtn){
                _this.$warning("主企业不能删除!");
                return;
              }
              if(!_this.delMsg){
                _this.delMsg = "删除后不可恢复,请确认后删除!";
              }
              _this.$confirm(_this.delMsg, '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              }).then(() => {
                _this.$emit("getDel",data.data);
              }).catch(() => {});
                        // _this.articleClassifyDel(event,data.data);
                    },
                }
            }, ''),
        ])
    },
    // 点击刷新按钮
    clickFresh(){
      this.filterText = '';
      this.$emit("clickFresh");
    },
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    }
  }
};
</script>

style

<style scoped>
.el-tree-div{border: 1px solid #E4E4E4;background-color: white;height: auto;box-shadow: 0 0 10px #E8F4FF;border-radius: 3px;}
.el-tree-top{padding-left: 16px;line-height: 30px;height: 30px;border-bottom: 1px solid #E4E4E4;background-color: #fff;position: relative;}
.refresh-tree{margin-left:12px; line-height: 30px;}
.refresh-tree .svg-icon {vertical-align: -0.1em; margin-right:4px;}
.el-tree-title{font-size: 14px;font-weight: 700;}
.show-tree-icon{position: absolute;right: 8px; color: #54595c; top: 16px; width: 20px; height: 15px;margin: 0;font-size: 20px;cursor: pointer;}
.el-tree-content{padding: 10px;}
.tree-body{margin-top: 10px;height: auto;overflow: auto;}
.tree-body .el-tree{width: fit-content;font-size: 12px;min-width: max-content;}
.tree-body /deep/ .el-tree__empty-block{width: 278px;}
.tree-no-data{width: 100%!important;}
.hide-tree .el-tree-top{height: 500px;}
.hide-tree .show-tree-icon{right: 5px;}
.tree-body /deep/ .article-classify-add,.tree-body /deep/ .article-classify-edit,.tree-body /deep/ .article-classify-del {
  display: inline-block;
  width: 15px;
  height: 15px;
  vertical-align: middle;
  border-radius: 3px;
  background-size: 100%;
}
.tree-body /deep/ .article-classify-add {
  background-color: #409eff;
  margin-left: 20px;
  background: url(https://图标路径/tree-add-icon.png) no-repeat center center;
}
.tree-body /deep/ .article-classify-edit {
  background-color: #409eff;
  margin-left: 5px;
  background: url(https://图标路径/tree-edit-icon.png) no-repeat center center;
}
.tree-body /deep/ .article-classify-del {
  background-color: #f56c6c;
  margin-left: 5px;
  background: url(https://图标路径/tree-reduce-icon.png) no-repeat center center;
}
.can-add-first-node /deep/ .el-tree-node:nth-last-child(2) .el-link{display: none;}
.can-add-first-node /deep/ .el-tree-node:nth-last-child(2)>div>span>span{display: inline-block;width: 200px;text-align: center;color: #0994DC;}
.el-tree-content /deep/ .el-link{opacity: 0;}
.el-tree-content /deep/ .el-link:last-child{margin-right: 60px;}
.el-tree-content /deep/ .el-tree-node__content:hover .el-link{opacity: 1;}
.el-tree--highlight-current{width: 100% !important;}
</style>

可能发布以后格式有点乱,复制之后格式化就好

很实用,望小伙伴们点赞、分享、收藏,不然以后找不着的嘿

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,076评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,658评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,732评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,493评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,591评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,598评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,601评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,348评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,797评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,114评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,278评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,953评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,585评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,202评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,180评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,139评论 2 352

推荐阅读更多精彩内容