1.menu-form.vue
<template>
<div>
<avue-form :option="modelOption" v-model="modelForm" @submit="handleSubmit"></avue-form>
</div>
</template>
<script>
export default {
name: "menu-form",
watch: {
'form.parentId'(n, o) {
this.modelForm=this.form
},
'form.id'(n, o) {
this.modelForm=this.form
}
},
model: {
prop: 'form',//指向props的参数名
event: 'returnBack'//事件名称
},
props: {
form: {
type: Object
},
option: {
type: Object
}
},
data() {
return {
modelForm: this.form,
modelOption: this.option
}
},
methods: {
handleSubmit(form, done) {
this.$emit("submit", form, done);
}
}
}
</script>
<style scoped>
</style>
2.meun-tree.vue
<template>
<div>
<el-row >
<el-col :span="17">
<el-input
placeholder="输入关键字进行过滤"
v-model="filterText">
</el-input>
</el-col>
<el-col :span="6" style="margin-left: 10px" >
<slot name="handle">
<el-button slot="handle" type="primary">添加</el-button>
</slot>
</el-col>
</el-row>
<el-tree
show-checkbox
node-key="id"
class="filter-tree"
:data="modelData"
:props="defaultProps"
default-expand-all
:expand-on-click-node="false"
:filter-node-method="filterNode"
@node-click="nodeClick"
ref="tree">
<span class="custom-tree-node" slot-scope="{ node, data }">
<span class="treeLeft">{{ node.label }}</span>
<span class="treeRight">
<el-button
type="text"
size="mini"
@click="() => append(data)">
添 加
</el-button>
<el-button
type="text"
size="mini"
@click="() => edit(data)">
编 辑
</el-button>
<el-button
type="text"
size="mini"
@click="() => remove(node, data)">
删 除
</el-button>
</span>
</span>
</el-tree>
</div>
</template>
<script>
export default {
name: "menu-tree",
model: {
prop: 'data',//指向props的参数名
event: 'returnBack'//事件名称
},
props: {
data: {
type:Array
}
},
data() {
return {
filterText: '',
modelData:this.data,
defaultProps: {
children: 'children',
label: 'label'
}
};
},
watch: {
data(){
this.modelData=this.data
},
filterText(val) {
this.$refs.tree.filter(val);
},
},
methods: {
filterNode(value, data) {
if (!value) return true;
return data.label.indexOf(value) !== -1;
},
nodeClick(data,n,x){
this.$emit("node-click",data)
},
append(data) {
// const newChild = {id: id++, label: 'testtest', children: []};
// if (!data.children) {
// this.$set(data, 'children', []);
// }
// data.children.push(newChild);
this.$emit("append",data)
},
remove(node, data) {
// const parent = node.parent;
// const children = parent.data.children || parent.data;
// const index = children.findIndex(d => d.id === data.id);
// children.splice(index, 1);
this.$emit("remove",node, data)
},
edit(data){
this.$emit("edit",data)
}
},
};
</script>
<style scoped>
.filter-tree{
}
.treeRight {
}
.treeLeft {
}
.custom-tree-node {
flex: 1;
display: flex;
width: 100%;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>
3.menu-tree-form.vue
<template>
<el-row :gutter="50">
<el-col :span="8" style="width: 400px;height: 75vh; ">
<menu-tree v-model="menuDataModel" @node-click="nodeClick" @append="append" @remove="remove" @edit="edit">
<el-button slot="handle" type="primary" @click="add">添加</el-button>
</menu-tree>
</el-col>
<el-col :span="16" style=" box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);padding: 20px">
<menu-form v-model="menuFormModel" :option="menuOptionModel" @submit="handleSubmit"></menu-form>
</el-col>
</el-row>
</template>
<script>
import MenuTree from "@/page/admin/menu/menu-tree";
import MenuForm from "@/page/admin/menu/menu-form";
export default {
name: "menu-tree-form",
components: {MenuForm, MenuTree},
model: {
prop: 'menuData',//指向props的参数名
event: 'returnBack'//事件名称
},
props: {
menuData: {
type: Object
},
menuForm: {
type: Object
},
menuOption: {
type: Object
}
},
data() {
return {
menuDataModel: this.menuData.list,
menuFormModel: this.menuData.form,
menuOptionModel: this.menuData.option
}
},
watch: {
'menuData.list'(n, o) {
this.menuDataModel = n;
},
'menuData.form.parentId'(n, o) {
this.menuFormModel = this.menuData.form;
},
'menuData.form.id'(n, o) {
this.menuFormModel = this.menuData.form;
}
},
methods: {
nodeClick(data) {
this.$emit("node-click", data)
},
add() {
this.$emit("add");
},
append(data) {
this.$emit("append", data);
},
remove(node, data) {
this.$emit("remove", node, data);
},
edit(data) {
this.$emit("edit", data);
},
handleSubmit(form, done) {
this.$emit("submit", form, done);
}
}
}
</script>
<style scoped>
</style>
4.index.vue 使用
<template>
<basic-container>
<menu-tree-form v-model="menuData" @add="add" @append="append" @edit="edit"
@remove="remove"
@submit="handleSubmit"></menu-tree-form>
</basic-container>
</template>
<script>
import {mapGetters} from 'vuex';
import MenuTreeForm from "@/page/admin/menu/menu-tree-form";
import {treeListLoad, del, save} from '@/api/admin/menu';
export default {
name: "index",
components: {MenuTreeForm},
watch: {},
data() {
return {
menuData: {
list: [],
form: {parentId: 0},
option: {
column: [{
label: "父级编码",
prop: "parentId",
value:0,
disabled: true,
span: 24
}, {
label: "权限名称",
prop: "name",
span: 24,
rules: [{
required: true,
message: "请输入权限名称",
trigger: "blur"
}]
}, {
label: "权限标识",
prop: "code",
span: 24,
rules: [{
required: true,
message: "请输入权限标识",
trigger: "blur"
}]
}, {
label: "类型",
prop: "state",
span: 24,
type: "radio",
dicData: [{
label: '系统',
value: 0
}, {
label: '菜单',
value: 1
}, {
label: '按钮',
value: 2
}],
rules: [{
required: true,
message: "请输入类型",
trigger: "blur"
}]
}, {
label: "组件地址",
prop: "component",
span: 24
}, {
label: "图标",
prop: "icon",
span: 24
}, {
label: "请求地址",
prop: "path",
span: 24
}, {
label: "权限描述",
prop: "des",
span: 24
}, {
label: "排序",
prop: "order",
span: 24
}]
}
},
menuOption: {
column: [{
label: "父级编码",
prop: "parentId",
disabled: true,
span: 24
}, {
label: "权限名称",
prop: "name",
span: 24,
rules: [{
required: true,
message: "请输入权限名称",
trigger: "blur"
}]
}, {
label: "权限标识",
prop: "code",
span: 24,
rules: [{
required: true,
message: "请输入权限标识",
trigger: "blur"
}]
}, {
label: "类型",
prop: "state",
span: 24,
type: "radio",
dicData: [{
label: '系统',
value: 0
}, {
label: '菜单',
value: 1
}, {
label: '按钮',
value: 2
}],
rules: [{
required: true,
message: "请输入类型",
trigger: "blur"
}]
}, {
label: "组件地址",
prop: "component",
span: 24
}, {
label: "图标",
prop: "icon",
span: 24
}, {
label: "请求地址",
prop: "path",
span: 24
}, {
label: "权限描述",
prop: "des",
span: 24
}, {
label: "排序",
prop: "order",
span: 24
}]
}
}
}, methods: {
treeLoad() {
let dto = {};
treeListLoad(dto).then(res => {
this.menuData.list = res.data.data;
}).catch(err => {
this.$message.error("网络异常:" + err)
})
},
add() {
const model = {
parentId: 0,
name: null,
code: null,
component: null,
icon: null,
id: null,
label: null,
meta: null,
path: null,
state: null,
des: null
};
this.menuData.form = model;
},
append(data) {
const model = {
parentId: data.id,
name: null,
code: null,
component: null,
icon: null,
id: null,
label: null,
meta: null,
path: null,
state: null,
des: null
};
this.menuData.form = model;
},
remove(node, data) {
console.log(node, data);
this.$confirm('此操作将永久删除该权限, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
del(data.id).then(res => {
this.$message.success("操作完成")
}).catch(err => {
this.$message.error("网络异常:" + err)
});
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
setTimeout(() => {
this.treeLoad();
}, 3000)
},
edit(data) {
this.menuData.form = data.menu;
},
handleSubmit(form, done) {
this.$message.success('3s后关闭');
let dto = form;
save(dto).then(res => {
this.$message.success("操作完成")
}).catch(err => {
this.$message.error("网络异常:" + err)
});
setTimeout(() => {
this.treeLoad();
done()
}, 3000)
}
},
created() {
this.treeLoad();
}
}
</script>
<style scoped>
</style>