樹目錄、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在復雜業務場景下為首選


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM