树形结构数组的处理

多纬数组怎样打平

示列数组

arr:[{
name:'aaa',
children:{
	name:'a2',
	childred:{
		name:'a3',
		children:{
			...
		}
	}
 }
}]

data是传入的数组

parentId 根据自己的业务来 这里是我父节点的id parentId是写死的0

flatData是_config写的全局数据配置

把children的id, name, children 取出来 没有就继续递归 再调用自身

flatMapData(data, parentId = 0) {
      if(parentId == 0) _config.flatData = [];
      if (!data || data.length == 0) return false;
      data.forEach(({ id, name, children }) => {
        _config.flatData.push({ parentId, id, name });
        if (children && children.length > 0) this.flatMapData(children, id);
      });
}

比uuid要更轻量级的nanoid

用于 JavaScript 的小型、安全、URL 友好、唯一的字符串 ID 生成器。

安装

npm i nanoid -S

nanoid说明

如何使用

import {nanoid} from 'nanoid';
import { customAlphabet } from 'nanoid';  
// 可以自定义字母 第二位参数为字节
// 如果想要纯数字id,可以*1 用js隐式转换
const nanoid = customAlphabet('abcdefg1234567890', 11);  

封装一个Tree组件 可以添删改

//index.vue
<el-form-item label="文件夹设置" required>
                    <tree ref="customTree" :tree-data="ruleForm.fileItems" :tree-expand-all="treeExpandAll"
                        :tree-node-key="treeNodeKey" :isEdit="isEdit" @addItem="addTreeItem"
                        @deleteItem="deleteTreeItem" @editItem="editTreeItem">
                    </tree>
                    <place-dialog ref="placeDialog" @addData="addData" @editData="editData" />
                </el-form-item>
 //index.js
 // 添加新记录
        addNewRecord() {
            this.$refs.placeDialog.openDialog(false)
        },

        // 新增表单数据
        addData(data) {
            // 新增树节点
            this.$refs.customTree.treeAddItem(data)
        },

        // 修改表单数据
        editData(data) {
            // 修改树节点
            this.$refs.customTree.treeEditItem(data)
        },

        // 增加树节点
        addTreeItem(data) {
            this.$refs.placeDialog.openDialog(false, data.id)
        },


        // 删除树节点
        deleteTreeItem(data) {
            this.$confirm('确定删除吗?', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                this.$refs.customTree.treeDeleteItem(data)
                this.$message({
                    type: 'success',
                    message: '删除成功!'
                })
            }).catch(() => {
                this.$message({
                    type: 'info',
                    message: '已取消删除'
                })
            })
        },

        // 修改树节点
        editTreeItem(data) {
            // 打开地点编辑弹窗
            this.$refs.placeDialog.openDialog(true, data.parentId, data)
        }
//tree.vue
<template>
    <div class="white-body-view">
        <el-tree id="my-tree" ref="tree" class="tree-view structure-tree" :data="treeData" highlight-current
            :default-expand-all="treeExpandAll" :props="defaultProps" check-strictly :node-key="treeNodeKey"
            :auto-expand-parent="false" :expand-on-click-node="false">
            <span slot-scope="{ node, data }" class="custom-tree-node">
                <span class="tooltip">
                    <span>{{ data.name }}</span>
                </span>
                <div class="operation-view">
                    <i class="small-operation-btn el-icon-plus" @click.stop="handleAdd(data)" />
                    <i class="small-operation-btn el-icon-edit" @click.stop="handleEdit(data)" />
                    <i class="small-operation-btn el-icon-delete" @click.stop="handleDelete(data)" />
                </div>
            </span>
        </el-tree>
    </div>
</template>
 
<script>
//dialog.vue
export default {
    props: {
        // 源数据
        treeData: {
            type: Array,
            default: function () {
                return []
            }
        },

        // 树节点是否默认展开
        treeExpandAll: {
            type: Boolean,
            default: true
        },

        // 树节点唯一标识
        treeNodeKey: {
            type: String,
            default: ''
        },
        isEdit: {
            type: Boolean,
            default: true
        },
        state:{
            type: Boolean,
            default: false
        }
    },

    data() {
        return {
            defaultProps: {
                children: 'children',
                label: 'name'
            },
            selectItem: {}
        }
    },

    methods: {
        // 添加新增按钮
        handleAdd(data) {
            this.$emit('addItem', data)
        },

        // 点击删除按钮
        handleDelete(data) {
            this.$emit('deleteItem', data)
        },

        // 点击编辑按钮
        handleEdit(data) {
            this.selectItem = data
            this.$emit('editItem', JSON.parse(JSON.stringify(data)))
        },

        // ============== 组件内事件 结束=============

        // ============== 父组件回调事件 开始=============

        // 添加新记录,树形列表回显
        treeAddItem(data) {
            this.$refs.tree.append(data, data.parentId)
        },

        // 删除节点
        treeDeleteItem(val) {
            this.$refs.tree.remove(val)
        },

        // 修改记录,树形列表回显
        treeEditItem(val) {
            Object.assign(this.selectItem, val)
            this.selectItem = {}
        },

        // ============== 父组件回调事件 结束=============

        openDialog(isEdit, parentId, data) {
            // this.initFormData()
            console.log(data)
            // if (this.isEdit) {
            //   this.$nextTick(() => {
            //     this.form = data
            //   })
            // }
        },

    }
}
</script>
<style lang="scss">
.white-body-view {
    width: 400px;
    height: 175px;
    background: #FFFFFF;
    border-radius: 3px;
    border: 1px solid #E5E6E7;
    padding: 5px 15px;
    overflow: auto;
    .custom-tree-node{
        width: 100%;
    }
}

.structure-tree {
    .el-scrollbar .el-scrollbar__wrap {
        overflow-x: hidden;
    }

    #my-tree .el-tree>.el-tree-node {
        min-width: 100%;
        display: inline-block;
    }

    .el-tree-node__content {
        margin-bottom: 10px;
        height: 26px;
        line-height: 26px;
    }

    .tooltip {
        span {
            font-size: 14px;
            font-weight: 400;
            white-space: nowrap;
        }
    }

    .operation-view {
        float: right;
        color: #777777;
        margin-left: 10px;
    }

    .small-operation-btn {
        margin: 5px;
    }

    .el-input,
    .el-input__inner {
        width: 200px;
        height: 25px;
        line-height: 25px;
    }
}
</style>
<template>
    <div>
        <el-dialog :title="title" :visible.sync="dialogVisible" width="50%">
            <el-form ref="form" :model="form" :rules="rules" label-width="100px">
                <el-form-item label="名称" prop="name">
                    <el-input v-model="form.name" />
                </el-form-item>
                <el-form-item>
                    <el-button class="pull-right" type="primary" @click="submitForm()">确定</el-button>
                </el-form-item>
            </el-form>
        </el-dialog>
    </div>
</template>
<script>
import {nanoid} from 'nanoid';
import { customAlphabet } from 'nanoid';  
export default {
    data() {
        return {
            dialogVisible: false,
            title: '',
            form: {
                name: ''
            },
            rules: {
                name: [
                    { required: true, message: '请输入名称', trigger: 'blur' }
                ]
            },
            isEdit: false,
            parentId: '',
            data: {}
        }
    },
    methods: {
        openDialog(isEdit, parentId, data) {
            this.isEdit = isEdit;
            this.parentId = parentId;
            this.data = data;
            this.title = isEdit ? '编辑' : '新增'
            this.initFormData()
            this.dialogVisible = true
            if (this.isEdit) {
                this.$nextTick(() => {
                    this.form = data;
                })
            }
        },

        initFormData() {
            this.form = {
                name: '',
            }
        },

        // 提交表单
        submitForm() {
            this.$refs.form.validate((valid) => {
                if (valid) {
                    const formData = JSON.parse(JSON.stringify(this.form))
                    if (this.isEdit) {
                        this.$emit('editData', formData)
                    } else {
                        // 设置新创建节点的父级编号
                        formData.parentId = this.parentId ? this.parentId : '';
                        const nanoid = customAlphabet('1234567890', 11);  
                        if (formData.parentId) {
                            formData.id = nanoid()*1;
                            this.$emit('addData', formData)
                        }

                    }
                    this.closeDialog()
                }
            })
        },

        // 关闭当前弹窗
        closeDialog() {
            this.$refs.form.resetFields()
            this.dialogVisible = false;
        }
    }
}
</script>
<style lang='scss' scoped>
.pull-right {
    float: right
}

.el-button {
    width: 110px;
    height: 36px;
    margin: 2% 0;
}
</style>

如何改变el-message-box__btns 的样式

scoped不生效,将样式放全局,在当前组件加上一段不带scoped的style

<style lang='scss'>

	.el-message-box__btns {
	    .el-button {
	        padding: 9px 27px;
	        color: #002FA8;
	    }
	
	    .el-button--primary {
	        color: #fff;
	    }
	}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值