美文网首页
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-树组件

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