elementUI树结构添加子级结构

1.父组件 

<template>
    <div>
        <div
            class="filter-input searchinput"
            :opendialog="inputValue"
            :constractId="fatherId"
        >
            <el-input
                v-model="filterText"
                clearable
                placeholder="输入名称查找"
                size="small"
                prefix-icon="el-icon-search"
            />
        </div>
        <div style="height: 50vh;overflow-y: scroll">
            <el-tree
                ref="tree"
                :data="partOptions"
                :filter-node-method="filterNode"
                node-key="id"
                size="small"
                :props="defaultCategory"
                :highlight-current="true"
                :check-on-click-node="true"
            >
                <span slot-scope="{ node, data }" class="custom-tree-node">
                    <div class="custom-tree-node-wrapper">
                        <span class="custom-tree-node-label">
                            {{ node.label }}
                        </span>
                        <span class="operate-btns">
                            <dot-dropdown
                                :events="dropMenuEvents"
                                :data="{node,data}"
                                @clickNode="addResource"
                            />
                        </span>
                    </div>
                </span>
            </el-tree>
            <!--新增事件节点分类弹窗-->
            <el-dialog
                :title="title"
                width="450px"
                :visible.sync="open"
                append-to-body
            >
                <el-form
                    ref="addEventForm"
                    :model="addEventForm"
                    label-width="80px"
                >
                    <el-form-item label="工程名称" prop="categoryName">
                        <el-input v-model="addEventForm.partialName" />
                    </el-form-item>
                </el-form>
                <div slot="footer" class="dialog-footer">
                    <form-button
                        :loading="loading"
                        :has-submit="type !== 'detail'"
                        @submit="submitForm"
                        @cancel="cancel"
                    />
                </div>
            </el-dialog>
        </div>
    </div>
</template>

<script>
import FormButton from '_c/FormButton'
import DotDropdown from '_c/DotDropdown/index'
import { isNotEmpty } from '@/libs/utils'
import { listPartialTree, addProjectPartialFromMeasure, updateProjectPartial } from '@/api/project/base/partial'
export default {
    name: 'Index',
    components: {
        FormButton,
        DotDropdown,
        listPartialTree
    },
    props: {
        inputValue: {
            type: Boolean,
            default: false
        },
        fatherId: {
            type: String
        }
    },
    data() {
        return {
            // 是否显示弹出层
            open: false,
            //
            title: '',
            // 确认按钮加载状态
            loading: false,
            // 表单类型:add:新增  edit:编辑  detail:详情
            type: '',
            parentId: '',
            addEventForm: {},
            filterText: '',
            partOptions: [],
            /* partOptions: [{
                id: 1,
                parentId:0,
                partialName: '一级 1',
                children: [{
                    id: 4,
                    parentId:1,
                    partialName: '二级 1-1',
                    children: [{
                        id: 9,
                        parentId:2,
                        partialName: '三级 1-1-1'
                    }, {
                        id: 10,
                        parentId:2,
                        partialName: '三级 1-1-2'
                    }]
                }]
            }, {
                id: 2,
                parentId: 0,
                partialName: '一级 2',
                children: [{
                    id: 5,
                    parentId: 1,
                    partialName: '二级 2-1'
                }, {
                    id: 6,
                    parentId: 1,
                    partialName: '二级 2-2'
                }]
            }
            ],*/
            defaultCategory: {
                children: 'children',
                label: 'partialName'
            },
            // sysDropMenuEvents: [{ label: '新增资源', funcName: 'addNode' }],
            dropMenuEvents: [
                { label: '新建同级', funcName: 'addPeerNode', type: 'addbrother' },
                { label: '新建子级', funcName: 'addNode', type: 'add' },
                { label: '修改', funcName: 'editNode', type: 'edit' },
                { label: '删除', funcName: 'removeNode', type: 'delete' }
            ]
        }
    },
    computed: {

    },
    watch: {
        filterText(val) {
            this.$refs.tree.filter(val)
        },
        type(val) {
            const title = '工程部位'
            switch (val) {
                case this.type = 'add':
                    this.title = `新增${title}`
                    break
                case this.type = 'addbrother':
                    this.title = `新增${title}`
                    break
                case this.type = 'edit':
                    this.title = `修改${title}`
                    break
                case this.type = 'delete':
                    this.title = `删除${title}`
                    break
            }
        },
        inputValue: {
            handler(val) {
                if (!val) {
                    this.filterText = null
                }
            }
        },
        fatherId: {
            handler(val) {
                this.getPartInfo()
            },
            immediate: true,
            deep: true
        }
    },
    created() {
        // this.getPartInfo()
    },
    methods: {
        // 过滤显示
        filterNode(value, data) {
            if (!value) return true
            return data.partialName.indexOf(value) !== -1
        },
        // 打开新增资源弹窗
        addResource(type, id, parent) {
            this.type = type
            // alert(parent)
            // this.form.parentId = parent
            if (type === 'delete') {
                this.$confirm('是否确认删除?', '警告', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
            } else {
                this.show(type, id, parent)
            }
        },
        getPartInfo() {
            listPartialTree({
                teamId: this.addEventForm.teamId,
                projectId: this.addEventForm.projectId,
                contractSectId: this.fatherId
            }).then(res => {
                this.partOptions = res.data
            })
        },
        show(type, id, parentId) {
            console.log(type, id, parentId)
            this.reset()
            // 编辑/详情相关
            if (type === 'edit') {
                // 获取表单数据
            }
            this.addEventForm.parentId = parentId
            this.addEventForm.id = id
            this.open = true
        },
        /** 提交按钮 */
        submitForm() {
            this.$refs['addEventForm'].validate(valid => {
                if (valid) {
                    this.loading = true
                    console.log(this.addEventForm)
                    if (this.type === 'edit') { // 修改
                        updateProjectPartial(this.addEventForm).then(res => {
                            if (res.data) {
                                this.getPartInfo()
                            }
                        }).finally(() => {
                            this.loading = false
                            this.open = false
                        })
                    } else if (this.type === 'delete') { // 删除
                        this.loading = false
                    } else { // 新增子级 or 新增同级
                        addProjectPartialFromMeasure(this.addEventForm).then(res => {
                            if (res.data) {
                                this.getPartInfo()
                            }
                        }).finally(() => {
                            this.loading = false
                            this.open = false
                        })
                    }
                }
            })
        },
        /** 取消按钮 */
        cancel() {
            this.open = false
            this.reset()
        },
        reset() {
            this.addEventForm = {
                id: undefined,
                teamId: this.$store.getters.teamId,
                projectId: this.$store.getters.projectId,
                contractSectId: this.fatherId,
                partialName: undefined,
                parentId: undefined,
                submitType: this.type
            }
        }
    }
}
</script>

<style lang="scss">
    .el-tree-node__content {
        position: relative;
        .operate-btns {
            position: absolute;
            right: 2px;
            display: none;
        }
        // 鼠标悬停时,展示
        &:hover,
        :focus-within {
            .operate-btns {
                display: inline;
            }
        }
    }
    .searchinput {
        .el-input__inner,.el-input-group__prepend{
            width: calc(100% - 20px);
            margin:0 10px;
            height: 40px;
            border-top:none;
            border-width: 0 0 1px;
            border-radius:0;
        }
        .el-input__prefix{
            .el-input__icon{
                margin-right: 15px;
                display: inline-block;
            }
            font-size:18px;
        }
        .el-input:focus-within{
            .el-icon-search:before {
                color: #1890ff;
                /*font-weight: bold;*/
            }
        }
    }

</style>

父组件@clickNode="addResource" 接收type,节点id,父级id

 // 打开新增资源弹窗
        addResource(type, id, parent) {
            this.type = type
            // alert(parent)
            // this.form.parentId = parent
            if (type === 'delete') {
                this.$confirm('是否确认删除?', '警告', {
                    confirmButtonText: '确定',
                    cancelButtonText: '取消',
                    type: 'warning'
                })
            } else {
                this.show(type, id, parent)
            }
        },

2.子组件

<template>
    <el-dropdown trigger="click" class="custom-tree-menu" size="small">
        <i class="el-icon-more rotate " />
        <el-dropdown-menu slot="dropdown">
            <el-dropdown-item
                v-for="(item,index) in events"
                :key="index"
                :divided="index >0"
                @click.native="clickMenu(item)"
            >
                {{ item.label }}
            </el-dropdown-item>
        </el-dropdown-menu>
    </el-dropdown>
</template>

<script>
export default {
    name: 'Index',
    props: {
        events: {
            type: Array,
            default: function() {
            }
        },
        // 注入数据
        data: {
            type: Object
        }
    },
    data() {
        return {
        }
    },
    methods: {
        clickMenu(val) {
            this.$emit('clickNode', val.type, this.data.data.id, this.data.data.parentId)
        }
    }
}
</script>

<style lang="scss">
    .el-icon-more:before {
        content: "\E794";
        color: #1890ff;
        font-size: 20px;
    }
    .rotate {
        cursor: pointer;
        margin-left: 5px;
        transform: rotate(90deg);
    }
    .rotate:focus {
        width: 20px;
        height: 20px;
        border-radius: 4em;
        background-color: rgba(130, 132, 138, 0.2);
    }
</style>

 搜索框样式

 .el-icon-more:before {
        content: "\E794";
        color: #1890ff;
        font-size: 20px;
    }
    .rotate {
        cursor: pointer;
        margin-left: 5px;
        transform: rotate(90deg);
    }
    .rotate:focus {
        width: 20px;
        height: 20px;
        border-radius: 4em;
        background-color: rgba(130, 132, 138, 0.2);
    }

上一篇:多叉树的样例


下一篇:js 递归树结构数据查找指定元素的所有父级