美文网首页
vue-树组件

vue-树组件

作者: 青青草原灰太狼 | 来源:发表于2018-09-25 19:24 被阅读0次

话不多说,直接上代码
tree.vue:

<template>
<ul class="tree__ul">
    <treeItem
            v-for="(treeData,index) in treeDatas"
            :treeData="treeData"
            :key="index"
            @nodeItemClick="nodeClick"
            :options="options"
            :level="1"></treeItem>
</ul>
</template>
<script>
export default {
    data(){
        return{
            
        }
    },
    props:{
        treeDatas:Array,
        options:Object,
    },
    methods:{
        nodeClick(value){
            if(this._events["nodeClick"]){
                this.$emit('nodeClick', value)
            }
        },
        getSelectNode(){
            let nodes=[];
            nodes=this.getChildrenSelect(this.treeDatas);
            return nodes;
        },
        getChildrenSelect(children){
            let nodes=[];
            children.forEach((item,index)=>{
                if(item.children&&item.children.length){
                    let childNodes=this.getChildrenSelect(item.children);
                    childNodes.forEach((childItem,childIndex)=>{
                        nodes.push(childItem);
                    })
                }else if(item.checked){
                    nodes.push(item);
                }
            });
            return nodes;
        }
    },
    components:{
        treeItem:{
            name:"treeItem",
            data(){
                return{
                    isOpen:false,
                    isUnAllCheck:false
                }
            },
            props:{
                treeData:Object,
                options:Object,
                level:Number,
            },
            computed:{
                isFolder(){
                    return this.treeData.children&&this.treeData.children.length;
                }

            },
            created(){
                //默认全选
                if(this.options.isSelected){
                    this.treeData.checked=true;
                }
            },
            mounted(){
                this.isOpen=this.options.expandNum>=this.level;
            },
            methods:{
                changeType(){
                    if(this.isFolder){
                        this.isOpen=!this.isOpen;
                        //异步树展开节点的时候调用回调
                        if(this.isOpen&&this._events["expandNode"]){
                            this.$emit('expandNode', this.treeData)
                        }
                    }
                },
                nodeClick(value,level){
                    if(level){
                        this.currentNodeClick();
                    }else{
                        this.parentNodeState();
                    }

                    //是否有回调函数
                    if(this._events["nodeItemClick"]){
                        this.$emit('nodeItemClick', value)
                    }
                },
                currentNodeClick(){
                    this.isUnAllCheck=false;
                    this.treeData.checked=!this.treeData.checked;
                    let state=this.treeData.checked;
                    if(this.treeData.children&&this.treeData.children){
                        this.childStateChange(this.treeData.children,state);
                    }

                },
                childStateChange(children,state){
                    if(children&&children.length){
                        children.forEach((item,index)=>{
                            item.checked=state;
                            if(item.children&&item.children){
                                this.childStateChange(item.children,state);
                            }
                        });
                    }
                },
                parentNodeState(){
                    let state=this.getChildrenState(this.treeData.children);
                    if(state===null){
                        this.isUnAllCheck=true;
                    }else{
                        this.isUnAllCheck=false;
                        this.treeData.checked=state;
                    }
                },
                getChildrenState(children){
                    var state=false;
                    if(children&&children.length>0){
                        for(let i=0;i<children.length;i++){
                            let item=children[i];
                            //子节点没有选全
                            if(state!=item.checked&&i>0){
                                return null;
                            }
                            state=item.checked;
                            if(item.children&&item.children.length){
                                let childState=this.getChildrenState(item.children);
                                //子节点没有选全
                                if(childState==null||state!=childState)
                                    return null;
                            }
                        }
                    }
                    return state;
                }
            },
            template:`<li class="tree__li">
        <div :class="['tree__item--arrow',isOpen?'tree__item--arrow-down':'']" @click="changeType" v-if="isFolder"><i></i></div>
        <div class="tree__item" @click="nodeClick(treeData,level)">
            <span :class="['tree-icon', isFolder&&isOpen?'tree-folder_open':isFolder?'tree-folder':'tree-file']" v-if="options.hasicon"></span>
            <span :class="['tree-checkbox', isUnAllCheck?'tree-checkbox_unallchecked':treeData.checked?'tree-checkbox_checked':'tree-checkbox_unchecked']"></span>
            <span class="tree-text" >{{treeData.name}}</span>
            <span title="删除" class="glyphicon glyphicon-remove tree-delete" v-if="treeData.candelete">x</span>

        </div>
        <ul class="tree__ul" v-show="isOpen" v-if="isFolder">
            <treeItem v-for="(item,index) in treeData.children"
                  :treeData="item"
                  :key="index"
                  :options="options"
                  :level="level+1"
                  @nodeItemClick="nodeClick"
                  ></treeItem>
        </ul>
    </li>`
        }
    }
}
</script>

css:

body{
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
}
 .header{
  height: 50px;
  border-bottom: 1px solid hsla(0,0%,100%,.15);
  background-color: #373d41;
}
.body{
  position: absolute;
  top:50px;
  left: 220px;
  right:0;
  bottom: 0;
  background-color: #fff;
}
.menu{
  position: absolute;
  top:50px;
  left: 0;
  bottom: 0;
  width: 220px;
}

.tree{
  position: relative;
  width: 100%;
  height: 100%;
  padding: 15px 10px;
  overflow-x: hidden;
  overflow-y: auto;
}
.tree__ul{
  margin: 0;
  padding: 0;
  list-style: none;
}
.tree__li{
  position: relative;
  padding-left: 12px;

}
.tree__item{
  margin: 0;
  padding: 2px 12px 2px 6px;
  line-height: 20px;
  font-size: 12px;
  color: #222;
  background-color: transparent;
  cursor: pointer;
}
.tree__item:hover{
  background-color: #F0F8FD;
}
.tree__item_selected{
  background-color: #F0F8FD;
}
.tree__item--arrow{
  display: inline-block;
  position: absolute;
  top: 0;
  left: 2px;
  width: 12px;
  height: 24px;
  overflow: hidden;
  cursor: pointer;
}
.tree__item--arrow i{
  display: inline-block;
  position: absolute;
  top: 7px;
  left: 4px;
  border-width: 5px;
  border-style: dashed dashed dashed solid;
  border-color: transparent transparent transparent #222;
  font-size: 0;
  line-height: 0;
  cursor: pointer;
}
.tree__item--arrow:hover i{
  border-color: transparent transparent transparent #999;
}

.tree__item--arrow-down{

}
.tree__item--arrow-down i{
  display: inline-block;
  position: absolute;
  top: 10px;
  left: 0px;
  border-width: 5px;
  border-style: solid dashed dashed dashed;
  border-color: #222 transparent transparent transparent;
  font-size: 0;
  line-height: 0;
}
.tree__item--arrow-down:hover i{
  border-color: #999 transparent transparent transparent;
}
.tree__item--arrow + .tree__ul{
  display: none;
}
.tree__item--arrow-down + .tree__ul{
  display: block;
}
/*树样式*/
.tree-icon,.tree-checkbox {
  display: inline-block;
  width: 16px;
  height: 16px;
  vertical-align: top;
  overflow: hidden;
}
.tree-icon{
  background-image: url('../img/treeicon.png');

}
.tree-folder {
  background-position: 52px -3px;
}
.tree-folder_open {
  background-position: 52px 47px;
}
.tree-file {
  background-position: 52px 21px;
}
.tree-checkbox {
  background-image: url('../img/treeicon.png');
}
.tree-checkbox_checked {
  background-position: 25px 47px;
}
.tree-checkbox_unchecked {
  background-position: 25px -2px;
}
.tree-checkbox_unallchecked {
  background-position: 25px 22px;
}

.tree-text {
  display: inline-block;
  vertical-align: top;
}

.tree-delete {
  padding-left: 10px;
  color: red;
}

样式图标:


treeicon.png

调用:

<tree
                    ref="testTree"
                    :treeDatas="treeDatas"
                    @nodeClick="nodeClick"
                    @expandNode="expandClick"
                    :options="options"></tree>

数据格式:

var options = {
        expandNum: 4,
        isAllexpand: true,
        hascheckbox: true,
        hasicon: true,
        folderClass: "",
        folderopenClass: "",
        fileClass: "",
        candelete: true,
        checkedCallback: false,
        removeCallback: false,
        checkedSelectChild: true,
    };
    var treeDatas = [{
        "id": 4,
        "value": "省XX",
        "name": "省XX",
        "checked": false,
        "children": [{"id": 1026, "value": "chenXX", "name": "陈XX","checked": false}, {
            "id": 2427,
            "value": "zhuangXX",
            "name": "庄XX", "checked": false
        }, {"id": 100730, "value": "dwliuXX", "name": "刘XX", "checked": false}, {
            "id": 100906,
            "value": "linXX",
            "name": "林XX", "checked": true
        }, {"id": 212, "value": "zhangXX", "name": "张XX", "checked": false}, {
            "id": 214,
            "value": "wangXX",
            "name": "王XX", "checked": false
        }, {"id": 236, "value": "huangXX", "name": "黄XX", "checked": false}, {
            "id": 265,
            "value": "caihouen",
            "name": "蔡XX", "checked": false,
            "children":[{"id": 1026, "value": "chenXX", "name": "陈XX", "checked": true}, {
                "id": 212,
                "value": "zhangXX",
                "name": "张XX","checked": true
            }, {"id": 531, "value": "liuXX", "name": "刘XX", "checked": true}, {
                "id": 4477,
                "value": "liXX",
                "name": "李XX",
                "checked": true
            }]
        }]
    }, {
        "id": 55,
        "value": "省XX分析组",
        "name": "省XX分析组",
        "checked": true,
        "children": [
            {"id": 1026, "value": "chenXX", "name": "陈XX", "checked": true}, {
                "id": 212,
                "value": "zhangXX",
                "name": "张XX","checked": true
            }, {"id": 531, "value": "liuXX", "name": "刘XX", "checked": true}, {
                "id": 4477,
                "value": "liXX",
                "name": "李XX",
                "checked": true
            }]
    }];

获取树数据的方法:

           //数结构的回调
            nodeClick(value) {
                console.log(value);
            },
            expandClick(value){
                console.log(value);
            },
            getSelectNode(){
                let nodes=this.$refs.testTree.getSelectNode();
                console.log(nodes);
             }

以上,一个功能还不够完善的树组件(一直没时间完善功能)

相关文章

  • vue-树组件

    话不多说,直接上代码tree.vue: css: 样式图标: 调用: 数据格式: 获取树数据的方法: 以上,一个功...

  • Vue父传子、子传夫通信--小案例

    父传子 子传夫 如有不懂,可以看我的 Vue-组件通信

  • Vue-基础-04-重点

    Vue-基础-day04-重点 01-基础-组件-局部组件 组件: 封装html+css+js 两类+三步 定义 ...

  • 4 动画及组件

    vue-> 过渡(动画) (它的本质走的是css3: transtion ,animation) 组件 ...

  • 《目录》

    更新到 111、MD5在项目中的加密のmd5单向加密2、vue-组件化の封装组件、引用组件3、微信小程序开发...

  • vue-组件

    1.Vue中是如何引入组件(对象 构造函数 )1.1. Vue是vue实例的构造函数, 通过new Vue() ...

  • VUE-组件

    组件 组件就是为了拆分Vue实例的代码量的,能够让我们以不同的组件来划分不同的功能模块,将来我们需要什么样的功能,...

  • Vue-组件

    定义Vue组件 什么是组件: 组件的出现,就是为了拆分Vue实例的代码量的,能够让我们以不同的组件,来划分不同的功...

  • Vue-组件

    一.组件 组件都具有模板,template new Vue()创建的是根组件 组件与实例一一对应,创建一个实例就是...

  • Vue-组件

网友评论

      本文标题:vue-树组件

      本文链接:https://www.haomeiwen.com/subject/ikoloftx.html