最近在使用iview admin3.0做前段UI框架,但是做菜单树的时候发现了一个问题,iview的tree没有右键菜单事件 需要我们自己想办法去实现,今天就来试试吧
整体效果如下
完整代码如下:
<style lang="less">
@import '../../../styles/common.less';
</style>
<template>
<div>
<Col span="24" class="padding-left-1">
<Card>
<Row>
<Col span="4" class="padding-left-1">
<Tree :data="menuTree" @on-select-change="getSelectedNodes"></Tree>
</Col>
<Col span="20" class="padding-left-1">
<table v-model="tableData" @on-change="handleChange" @on-delete="handleDel" :editIncell="false" :columns-list="menuList"></table>
</Col>
<Button style="float:right;margin-top: 3px;" v-on:click="add" type="success">添加一行</Button>
</Row>
</Card>
</Col>
<Dropdown transfer ref="contentMenu" style="display: none;" trigger="click" placement="right-start">
<DropdownMenu slot="list" ref="ppp" style="min-width: 80px;">
<DropdownItem ><a @click="addMenu">添加菜单</a></DropdownItem>
<DropdownItem name="edit"><a>修改菜单</a></DropdownItem>
<DropdownItem name="del"><a>删除菜单</a></DropdownItem>
</DropdownMenu>
</Dropdown>
<!-- 新增菜单 -->
<Modal v-model="addModal" title="新增菜单" @on-ok="submit" @on-cancel="cancel" :loading="loading" class="ivuModal">
<Row>
<Col span="6" class="formLabel"><label>使用者名称:</label></Col>
<Col span="18">
<div class="formInput">
<input v-model="addName" placeholder="使用者名称" class="classTwo">
</input>
</div>
</Col>
</Row>
</Modal>
</div>
</template>
<script>
import tableData from '../components/table_data.js';
export default {
name: 'editable-table',
components: {},
data() {
return {
nodeInfo: [], //节点信息
loading: false,
addName: "test",
addModal: false,
tableData: [],
mLevel: "", //临时存储当前表格菜单等级
pId: "", //临时存储当前表格菜单父亲
menuTree: [{
title: '菜单树',
expand: true,
render: (h, {root,node,data
}) => {
return h('span', {
style: {
display: 'inline-block',
color: 'green'
}
}, [
h('span', [
h('Icon', {
props: {
type: 'home'
},
style: {
marginRight: '8px'
}
}),
h('span', data.title)
])
]);
},
children: []
}],
folder: (h, {root,node,data}) => {
return h('span', {
style: {
display: 'inline-block',
cursor: 'pointer',
color: 'green'
},
on: {
click: () => {
this.getSelectedNodes(data)
},
//右键点击事件
contextmenu: (e) => {
e.preventDefault();
this.nodeInfo = data;
this.$refs.contentMenu.$refs.reference = event.target;
this.$refs.contentMenu.currentVisible = !this.$refs.contentMenu.currentVisible;
},
}
}, [h('span', [h('Icon', {
props: {
type: 'folder'
},
style: {
marginRight: '8px'
}
}), h('span', data.title)])]);
},
files: (h, {root,node,data}) => {
return h('span', {
style: {
display: 'inline-block',
cursor: 'pointer',
color: 'green'
},
on: {
//鼠标点击事件
click: () => {
this.getSelectedNodes(data)
},
//右键点击事件
contextmenu: (e) => {
e.preventDefault();
this.nodeInfo = data;
this.$refs.contentMenu.$refs.reference = event.target;
this.$refs.contentMenu.currentVisible = !this.$refs.contentMenu.currentVisible;
},
}
}, [h('span', [h('Icon', {
props: {
type: 'document-text'
},
style: {
marginRight: '8px'
}
}), h('span', data.title)])]);
},
};
},
methods: {
initTable() {
this.menuList = tableData.menuList;
}, //初始化一行空数据
add() {
var initData = {
expand: true,
iconClass: "--",
menuLevel: this.mLevel,
parentId: this.pId,
menuUrl: "#",
sortBy: "--",
title: "--"
};
this.tableData.push(initData);
},
//点击目录树事件
getSelectedNodes(data) {
var id = data.id;
var level = data.menuLevel;
this.pId = id;
this.mLevel = level;
//根据当前id显示子目录
this.$store.dispatch({
type: 'getChildrenMenusById',
id: id,
menuLevel: level
}).then(res => {
this.total = res.data.content.length;
this.tableData = [];
for(var i = 0; i < this.total; i++) {
this.pId = res.data.content[i].parentId;
this.mLevel = res.data.content[i].menuLevel;
this.tableData.push(res.data.content[i]);
}
}, err => {
this.$Message.error(err);
});
},
//加载菜单
loadData() {
this.$store.dispatch({
type: 'getMenus',
}).then(res => {
this.total = res.data.content.length;
for(var i = 0; i < this.total; i++) {
this.tableData.push(res.data.content[i]);
this.pId = res.data.content[i].parentId;
this.mLevel = res.data.content[i].menuLevel;
}
this.setTree(res.data);
}, err => {
this.$Message.error(err);
});
},
//设置菜单树样式
setTree(data) {
for(var i = 0; i < data.content.length; i++) {
data.content[i].render = this.folder;
if(data.content[i].children.length != 0) {
for(var j = 0; j < data.content[i].children.length; j++) {
data.content[i].children[j].render = this.files;
}
}
this.menuTree[0].children.push(data.content[i]);
}
},
handleDel(val, index) {
//删除菜单
this.$store.dispatch({
type: 'deleteMenusById',
id: val[index].id
}).then(res => {
location.reload();
}, err => {
this.$Message.error(err);
});
},
handleChange(val, index) {
//添加&修改菜单
this.$store.dispatch({
type: 'addAndModifyMenus',
parentId: val[index].parentId,
expand: true,
menuLevel: val[index].menuLevel,
menuUrl: val[index].menuUrl,
sortBy: val[index].sortBy,
title: val[index].title,
node: val[index].node,
menuType: val[index].type
}).then(res => {
location.reload();
}, err => {
this.$Message.error(err);
});
},
//添加菜单
addMenu() {
const children = this.nodeInfo.children || [];
children.push({
title: 'test appended node',
expand: true
});
this.$set(data, 'children', children);
this.addModal = true;
},
submit() {},
cancel() {},
},
created() {
this.initTable();
this.loadData();
}
};
</script>
主要代码讲解:
首先 在定义树的时候添加监听事件 我在二级和三级目录上添加了监听事件
右键点击菜单 后 首先关闭默认的右键事件 一般默认右键事件是这样的:
然后打开我们自己定义的右键菜单 :
<Dropdown transfer ref="contentMenu" style="display: none;" trigger="click" placement="right-start">
<DropdownMenu slot="list" ref="ppp" style="min-width: 80px;">
<DropdownItem ><a @click="addMenu">添加菜单</a></DropdownItem>
<DropdownItem name="edit"><a>修改菜单</a></DropdownItem>
<DropdownItem name="del"><a>删除菜单</a></DropdownItem>
</DropdownMenu>
</Dropdown>
具体的添加事件在这里:
目前只是完成了简单的右键菜单以及菜单的添加 后续还要进一步的完成修改删除等 存在的问题是 目前只能添加到子节点中去 怎样去添加到当前节点中 并且能自动排序 是需要思考的一个问题