树目录、vue树目录

在前端实现树目录,首先我们要想想好数据结构,分单级与多级两种情况如图所示:

 

 

 json数据

{
    "code": "00000",
    "data": [
        {
            "uniq": "chap2022012113252715",
            "type": "0",
            "cname": "米国8",
            "parent_uniq": "root",
            "file_type": "",
            "file_uniq": "",
            "knowledge_point": "米国",
            "introduction": "米国",
            "created_time": "2022-01-21 13:25:27",
            "children": []
        },
        {
            "uniq": "chap2022012113260216",
            "type": "0",
            "cname": "米国18",
            "parent_uniq": "root",
            "file_type": "",
            "file_uniq": "",
            "knowledge_point": "米国",
            "introduction": "米国",
            "created_time": "2022-01-21 13:26:02",
            "children": []
        },
        {
            "uniq": "chap2022012113261017",
            "type": "0",
            "cname": "乌拉",
            "parent_uniq": "root",
            "file_type": "",
            "file_uniq": "",
            "knowledge_point": "乌拉",
            "introduction": "乌拉",
            "created_time": "2022-01-21 13:26:10",
            "children": [
                {
                    "uniq": "chap2022012113265020",
                    "type": "0",
                    "cname": "2",
                    "parent_uniq": "chap2022012113261017",
                    "file_type": "",
                    "file_uniq": "",
                    "knowledge_point": "28",
                    "introduction": "2",
                    "created_time": "2022-01-21 13:26:50",
                    "children": [
                        {
                            "uniq": "chap2022012113294121",
                            "type": "0",
                            "cname": "8",
                            "parent_uniq": "chap2022012113265020",
                            "file_type": "",
                            "file_uniq": "",
                            "knowledge_point": "8",
                            "introduction": "8",
                            "created_time": "2022-01-21 13:29:41",
                            "children": []
                        },
                        {
                            "uniq": "chap2022012113303222",
                            "type": "0",
                            "cname": "9",
                            "parent_uniq": "chap2022012113265020",
                            "file_type": "",
                            "file_uniq": "",
                            "knowledge_point": "9",
                            "introduction": "9",
                            "created_time": "2022-01-21 13:30:32",
                            "children": [
                                {
                                    "uniq": "chap2022012113323824",
                                    "type": "0",
                                    "cname": "88",
                                    "parent_uniq": "chap2022012113303222",
                                    "file_type": "",
                                    "file_uniq": "",
                                    "knowledge_point": "8",
                                    "introduction": "8",
                                    "created_time": "2022-01-21 13:32:38",
                                    "children": []
                                }
                            ]
                        },
                        {
                            "uniq": "chap2022012113304323",
                            "type": "0",
                            "cname": "7",
                            "parent_uniq": "chap2022012113265020",
                            "file_type": "",
                            "file_uniq": "",
                            "knowledge_point": "7",
                            "introduction": "7",
                            "created_time": "2022-01-21 13:30:43",
                            "children": [
                                {
                                    "uniq": "chap2022012113332225",
                                    "type": "0",
                                    "cname": "6",
                                    "parent_uniq": "chap2022012113304323",
                                    "file_type": "",
                                    "file_uniq": "",
                                    "knowledge_point": "6",
                                    "introduction": "6",
                                    "created_time": "2022-01-21 13:33:22",
                                    "children": [
                                        {
                                            "uniq": "chap2022012113332826",
                                            "type": "0",
                                            "cname": "5",
                                            "parent_uniq": "chap2022012113332225",
                                            "file_type": "",
                                            "file_uniq": "",
                                            "knowledge_point": "5",
                                            "introduction": "5",
                                            "created_time": "2022-01-21 13:33:28",
                                            "children": []
                                        }
                                    ]
                                }
                            ]
                        },
                        {
                            "uniq": "file2113295507",
                            "type": "1",
                            "cname": "西溪碧桂园.pdf",
                            "parent_uniq": "chap2022012113265020",
                            "file_type": "1",
                            "file_uniq": "0038654742",
                            "knowledge_point": "88",
                            "introduction": "",
                            "created_time": "2022-01-21 13:29:54",
                            "children": []
                        }
                    ]
                },
                {
                    "uniq": "file2113330308",
                    "type": "1",
                    "cname": "朱飞-评估表-",
                    "parent_uniq": "chap2022012113261017",
                    "file_type": "0",
                    "file_uniq": "0038654743",
                    "knowledge_point": "8",
                    "introduction": "",
                    "created_time": "2022-01-21 13:33:03",
                    "children": []
                }
            ]
        }
    ],
    "msg": "接口调用成功"
}
children是我们判断单级还是多级的字段
梳理好业务及数据结构,在动手写代码前我们要考虑代码的逻辑复杂度、维护性、可读性等等,
在树目录这个需求中。1)、我们用vue来开发按照以往开发习惯写一堆Dom结构,在Dom中需要写许多v-if判断,代码可读性不高,维护性不高
          2)、如果你用过react或了解果vue3.0或在vue2.0用过jsx,jsx是做复杂业务的首选
总上此需求采用jsx作为子组件完成树目录的业务开发
代码如下:
父级:
<template>
    <!-- 知识库 -->
    <div class="box">
        <a-row class="simpleImage"
               v-if="visited">
            <a-empty :image="simpleImage" />
        </a-row>
        <a-row class="main_box"
               v-if="!visited">
            <a-col span='7'
                   class="main left_box">
                <div class="catalogue">目录</div>
          // 树目录
<div class="a_table"> <s-tree ref='s_tree' :dataSource="orgTree" :search="true" @click="handleClick" @add="handleAdd" @defaultTitleClick="defaultTitleClick "> </s-tree> </div> </a-col> </a-row> </div> </template>
<script>
import { Empty } from 'ant-design-vue'
import { query_knowledge_base_catalogue } from '@/api/factory'
import STree from '@/components/ZF/menuTree.jsx'

export default {
    name: 'Knowledge',
    components: {
        STree
    // pdf
    },
    data () {
        return {
            visited: false,
            orgTree: [],
            openKeys: []

        }
    },
    beforeCreate () {
        this.simpleImage = Empty.PRESENTED_IMAGE_SIMPLE
    },
    created () {
    },
    watch: {},
    mounted () {
        this.base_catalogue()
    },
    methods: {
        base_catalogue () {
            const params = {}
            query_knowledge_base_catalogue(params).then(res => {
                if (res.code === '00000') {
                    // console.log(res)
                    this.orgTree = res.data
                    this.openKeys.push(res.data[0].uniq)
                    // 默认展示第一项
                    this.$refs.s_tree.openKeys(this.openKeys)
                } else {
                    this.$message.error(res.msg)
                }
            })
        },
        // 父级
        defaultTitleClick (e) {

        },
        // 单级触发
        handleClick (e) {
        },
        // 单级触发
        handleAdd (item) {

        }
    },
    beforeDestroy () { }
}
</script>

子组件jsx

import { Menu, Tooltip, Input } from 'ant-design-vue'
import './menuTree.less'
const { Item, ItemGroup, SubMenu } = Menu
const { Search } = Input

export default {
    name: 'Tree',
    props: {
        dataSource: {
            type: Array,
            required: true
        }
        // search: {
        //     type: Boolean,
        //     default: false
        // }
    },
    mounted () {

    },
    data () {
        return {
            localOpenKeys: []
        }
    },
    methods: {
    // 默认项 openKeys (val) {
this.localOpenKeys = val }, defaultSelectedKeys (item) { this.$emit('add', item) }, defaultTitleClick (item) { this.$emit('defaultTitleClick', item) }, // 搜索框 // renderSearch () { // return ( // <Search // placeholder="input search text" // style="width: 100%; margin-bottom: 1rem" // /> // ) // }, // 图标 renderIcon (type) { return type && type === '0' ? (<span class='limit img_one'></span>) : (<span class="limit img_two"></span>) }, // 单级 renderMenuItem (item) { return ( <Item key={item.uniq} {...{ on: { click: () => this.defaultSelectedKeys(item) } }}> <span class="father"> { this.renderIcon(item.type) } <Tooltip placement="topLeft"> <template slot="title"> { item.cname } </template> <span class="cname">{ item.cname }</span> </Tooltip> {/* <a class="btn" style="width: 20px;z-index:1300" {...{ on: { click: () => this.handlePlus(item) } }}></a> */} </span> </Item> ) }, // 判断是多级还是单级菜单 renderItem (item) { return item.children.length > 0 ? this.renderSubItem(item, item.uniq) : this.renderMenuItem(item, item.uniq) }, // 多级结构 renderSubItem (item, uniq) { // console.log(item) const childrenItems = item.children.length > 0 && item.children.map(o => { return this.renderItem(o, o.uniq) }) const title = ( <span slot="title" class="father"> { this.renderIcon(item.type) } <Tooltip placement="topLeft"> <template slot="title"> { item.cname } </template> <span class="cname">{ item.cname }</span> </Tooltip> </span> ) return ( <SubMenu key={uniq} {...{ on: { titleClick: () => this.defaultTitleClick(item) } }}> { title } { childrenItems } </SubMenu> ) } }, render () { const { dataSource, search } = this.$props // this.localOpenKeys = openKeys.slice(0) const list = dataSource.map(item => { return this.renderItem(item) }) return ( <div class="tree-wrapper"> {/* { search ? this.renderSearch() : null } 搜索框 */} <Menu mode="inline" class="custom-tree" {...{ on: { click: item => this.$emit('click', item), 'update:openKeys': val => { this.localOpenKeys = val } } }} openKeys={this.localOpenKeys}> { list } </Menu> </div> ) } }

css    注:在使用jsx时图片用img加载不出来时,可以采用背景图片加载,写代码条条道路通罗马,

.img_one {
    background-image: url(../../assets/img/pdf.png);
}
.img_two {
    background-image: url(../../assets/img/file.png);
}
.limit {
    display: inline-block;
    width: 16px;
    height: 16px;
    background-repeat: no-repeat;
    background-size: 16px 16px;
    margin-right:3px
}
.father {
    display: flex;
    align-items: center;
}
.cname {
    display: inline-block;
    width: 95%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

由此发现jsx在复杂业务场景下为首选

posted @ 2022-01-23 11:26  Jim-vue  阅读(1189)  评论(0编辑  收藏  举报