数据准备
![](https://i-blog.csdnimg.cn/blog_migrate/ccb3e92f23244e4c7da2cf813864c2f6.png)
结果呈现
![](https://i-blog.csdnimg.cn/blog_migrate/b3d83b506e387b30d08676878831b7aa.png)
添加最外层菜单
![](https://i-blog.csdnimg.cn/blog_migrate/adea0cfb6e34b2ac53853ba1199f6250.png)
添加子菜单界面
![](https://i-blog.csdnimg.cn/blog_migrate/60c7bafd1e3ee3bd5eb07f27cf72afda.png)
直接上代码
index.vue
<template>
<div class="table-container">
<vab-query-form>
<vab-query-form-left-panel :span="3">
<el-button icon="el-icon-plus" type="success" @click="handleAdd">
添加
</el-button>
</vab-query-form-left-panel>
<vab-query-form-right-panel :span="21">
<el-form
ref="form"
:inline="true"
label-width="80px"
:model="queryForm"
@submit.native.prevent
>
<el-form-item label="品牌名称">
<el-input
v-model="queryForm.brandName"
clearable
placeholder="请输入品牌名称"
style="width: 140px"
/>
</el-form-item>
<el-form-item>
<el-button
icon="el-icon-search"
native-type="submit"
type="primary"
@click="handleQuery"
>
查询
</el-button>
</el-form-item>
</el-form>
</vab-query-form-right-panel>
</vab-query-form>
<el-table
:key="Math.random()"
ref="tables"
v-loading="listLoading"
border
:data="list"
:default-expand-all="false"
fit
:height="height"
lazy
:load="loadChild"
row-key="brandNo"
:tree-props="{
children: 'lstChildren',
hasChildren: 'hasChildren',
}"
>
<el-table-column
label="品牌名称"
prop="brandName"
show-overflow-tooltip
/>
<el-table-column label="品牌编码" prop="brandNo" show-overflow-tooltip />
<el-table-column label="描述" prop="desr" show-overflow-tooltip />
<el-table-column label="排序" prop="sort" show-overflow-tooltip />
<el-table-column
label="创建人名称"
prop="createName"
show-overflow-tooltip
/>
<el-table-column label="操作">
<template #default="{ row }">
<el-button
circle
icon="el-icon-plus"
size="mini"
type="primary"
@click="handleChildrenAdd(row)"
/>
<el-button
circle
icon="el-icon-edit"
size="mini"
type="success"
@click="handleEdit(row)"
/>
<el-button
circle
icon="el-icon-delete"
size="mini"
type="danger"
@click="handleDelete(row)"
/>
</template>
</el-table-column>
</el-table>
<el-pagination
:background="background"
:current-page="queryForm.pageModel.pageIndex"
:layout="layout"
:page-size="queryForm.pageModel.pageSize"
:total="total"
@current-change="handleCurrentChange"
@size-change="handleSizeChange"
/>
<brand-add-edit
ref="edit"
@fetch-data="fetchData"
@fetch-edit-data="fetchEditData"
/>
</div>
</template>
<script>
import {
get_brands_page,
get_brands_all,
brand_delete,
} from '@/api/infoBrand'
import BrandAddEdit from './components/brandAddEdit.vue'
export default {
name: 'Brand',
components: { BrandAddEdit },
data() {
return {
total: 0,
layout: 'total, sizes, prev, pager, next, jumper',
background: true,
queryForm: {
brandNo: '',
brandName: '',
parentNo: '',
isDelete: false,
pageModel: {
pageIndex: 1,
pageSize: 10,
totalCount: 0,
},
},
list: [],
maps: new Map(),
listLoading: true,
currParentNo: '', //定义父级编码
}
},
computed: {
height() {
return this.$baseTableHeight(1) + 30
},
},
created() {
this.fetchData()
},
mounted() {},
methods: {
//加载模块的数据
async fetchData() {
this.listLoading = true
const { results, pageModel } = await get_brands_page(this.queryForm)
this.list = results
this.total = pageModel.totalCount
setTimeout(() => {
this.listLoading = false
}, 500)
},
//懒加载
async loadChild(tree, treeNode, resolve) {
let _this = this
const pid = tree.brandNo //取出当前的编码
_this.maps.set(pid, { tree, treeNode, resolve }) //将当前选中节点数据存储到maps中
get_brands_all({
parentNo: pid,
brandNo: '',
brandName: '',
}).then((res) => {
if (res.results.length) {
resolve(res.results)
} else {
resolve([])
}
})
},
fetchEditData(row) {
let _this = this
const { parentNo } = row
if (_this.currParentNo) {
//懒加载刷新当前菜单
if (parentNo && _this.maps.get(parentNo)) {
const { tree, treeNode, resolve } = _this.maps.get(parentNo)
_this.loadChild(tree, treeNode, resolve)
}
//懒加载刷新父级
if (_this.currParentNo && _this.maps.get(_this.currParentNo)) {
const { tree, treeNode, resolve } = _this.maps.get(
_this.currParentNo
)
_this.loadChild(tree, treeNode, resolve)
}
} else {
_this.fetchData()
}
},
handleDelete(row) {
let _this = this
_this.currParentNo = '' //清除父节点得历史数据
_this.$baseConfirm('你确定要删除当前项吗?', null, async () => {
const { msg, hasErr } = await brand_delete({
brandNo: row.brandNo,
isDelete: true,
})
_this.$baseMessage(msg, 'success')
//重新获取所有菜单,更新vuex中得所有类目得最新数据
_this.$store.dispatch(
'infobrand/updateBrandList',
_this.$refs['edit'].brandForm
)
const { parentNo } = row //取出当前删除行的parentNo (父编码)
//判断是否是一级删除
if (parentNo) {
const { tree, treeNode, resolve } = _this.maps.get(parentNo) //根据parentNo (父编码)取出对应的节点数据
//将对应节点下的数据清空,从而实现数据的重新加载
this.$set(
_this.$refs.tables.store.states.lazyTreeNodeMap,
parentNo,
[]
)
_this.currParentNo = tree.parentNo //获取当前父级编码进行重新加载节点
_this.fetchEditData(tree)
} else {
//重新加载数据
_this.fetchData()
}
})
},
handleAdd() {
//最外层添加
this.$refs['edit'].showEdit()
},
handleEdit(row) {
this.$refs['edit'].showEdit(row)
},
handleChildrenAdd(row) {
//添加子菜单
this.$refs['edit'].showEdit(row, 'childrenAdd')
},
handleQuery() {
this.queryForm.pageModel.pageIndex = 1
this.fetchData()
},
handleSizeChange(val) {
this.queryForm.pageModel.pageSize = val
this.fetchData()
},
handleCurrentChange(val) {
this.queryForm.pageModel.pageIndex = val
this.fetchData()
},
},
}
</script>
brandAddEdit.vue
<template>
<el-drawer
:before-close="close"
direction="rtl"
:title="title"
:visible.sync="dialogFormVisible"
>
<el-form
ref="form"
label-width="100px"
:model="form"
:rules="rules"
style="padding: 20px"
>
<el-form-item label="父菜单" prop="brandNo">
<el-cascader
v-model.trim="form.brandNo"
clearable
:disabled="disabled"
:options="brandList"
placeholder="根目录"
:props="{
checkStrictly: true,
children: 'lstChildren',
value: 'brandNo',
label: 'brandName',
}"
style="width: 100%"
/>
</el-form-item>
<el-form-item label="品牌名称" prop="brandName">
<el-input
v-model.trim="form.brandName"
autocomplete="off"
placeholder="输入品牌名称"
/>
</el-form-item>
<el-form-item label="描述" prop="desr">
<el-input
v-model.trim="form.desr"
autocomplete="off"
placeholder="输入描述"
type="textarea"
/>
</el-form-item>
<el-form-item label="排序" prop="sort">
<el-input
v-model.trim="form.sort"
autocomplete="off"
placeholder="输入排序"
/>
</el-form-item>
<el-form-item>
<el-button @click="close">取 消</el-button>
<el-button type="primary" @click="save">确 定</el-button>
</el-form-item>
</el-form>
</el-drawer>
</template>
<script>
import { brand_save_or_update } from '@/api/infoBrand'
import { mapGetters } from 'vuex'
export default {
name: 'BrandAddEdit',
data() {
return {
form: {
brandNo: '',
brandName: '',
sort: '',
parentNo: '',
desr: '',
isDelete: false,
},
rules: {
brandName: [
{ required: true, trigger: 'blur', message: '请输入品牌名称' },
],
},
title: '',
pname: '根目录',
dialogFormVisible: false,
disabled: false,
brandForm: {
brandNo: '',
brandName: '',
parentNo: '',
isDelete: false,
},
}
},
computed: {
...mapGetters({ brandList: 'infobrand/brandList' }),
},
created() {},
mounted() {},
methods: {
showEdit(row, type) {
this.disabled = false
this.dialogFormVisible = true
if (!row) {
this.title = '当前全局添加'
} else if (type == 'childrenAdd') {
this.title = '添加子菜单'
this.disabled = true //添加当前子菜单的时候不能选择其他类目
this.form.brandNo = row.brandNo //回显
this.form.parentNo = row.brandNo //一级添加子菜单的时候需要把当前编码作为添加时的父编码
if (!row.parentNo) {
//一级菜单添加
this.$parent.currParentNo = row.parentNo
} else {
//当前节点添加 (如果当前父节点编码没有数据,就取当前节点编码为父级)
this.$parent.currParentNo = row.parentNo || row.brandNo
}
} else {
this.title = '编辑'
this.disabled = true //编辑当前子菜单的时候不能选择其他类目
this.form = Object.assign({}, row)
}
},
close() {
this.$refs['form'].resetFields()
this.form = this.$options.data().form
this.dialogFormVisible = false
this.$emit('fetch-data')
},
save() {
let _this = this
_this.$refs['form'].validate(async (valid) => {
if (valid) {
const { parentNo } = _this.form
if (_this.title == '编辑') {
_this.$parent.currParentNo = _this.form.parentNo
_this.getFormCommit(_this.form)
} else {
if (!parentNo) {
//最外层添加
_this.getFormCommit(_this.form)
} else {
//当前节点添加
_this.form.brandNo = '' //在添加子菜单的时候需要把当前编码清空,因为添加编码是自动生成的,但是在回显的时候还是需要加上,添加就清空
_this.getFormCommit(_this.form)
}
}
} else {
return false
}
})
},
//调用更新接口
async getFormCommit(formdata) {
let _this = this
//添加和修改
const { msg } = await brand_save_or_update(formdata)
if (!formdata.parentNo) {
//刷新一级菜单
_this.$emit('fetch-data')
} else {
//添加成功后执行懒加载获取当前下得子菜单
_this.$emit('fetch-edit-data', formdata)
}
//重新获取所有菜单,更新vuex中得所有类目得最新数据
_this.$store.dispatch('infobrand/updateBrandList', _this.brandForm)
//重置form表单
_this.$refs['form'].resetFields()
_this.form = _this.$options.data().form
_this.dialogFormVisible = false
_this.$baseMessage(msg, 'success')
},
},
}
</script>