vue项目左右布局的菜单效果,树形菜单
效果图:
index.vue
<template> <div class="app-container"> <div class="mt30"></div> <el-row :gutter="20"> <!-- title --> <!-- <div class="modt-box">导航管理</div> --> <el-col :span="2"> <div class="grid-content bg-purple"></div> </el-col> <el-col :span="6"> <!-- default-expand-all="" tree-border--> <div class="lefttree"> <div class="tit-box">菜单目录</div> <el-tree class="treeclass" default-expand-all="" ref="tree" :data="treeData" :props="defaultProps" @node-click="nodeclick" @check-change="handleClick" check-strictly node-key="id" > <!-- 操作的插槽 --> <span class="custom-tree-node" slot-scope="{ node, data }"> <div class="custom-tree-node-wrapper"> <span class="custom-tree-node-label">{{ node.label }}</span> <span class="operate-btns"> <dot-dropdown :eventsa="dropevents" :data="{node,data}" @addPeerNode="addPeerNode" @addNode="addNode" @editNode="editNode" @removeNode="removeNode" /> </span> </div> </span> </el-tree> </div> </el-col> <el-col :span="2"> <div class="grid-content bg-purple"></div> </el-col> <el-col :span="16"> <div class="rightform"> <div class="tit-box">{{tit}}</div> <!-- <div class="mod-btnbox"> <el-button type="primary" icon="el-icon-plus" @click="addModule">添加</el-button> </div>--> <el-form ref="form" :model="form" label-width="80px" :rules="rules"> <!-- <el-form-item label="父级菜单" prop="parentId"> <el-select v-model="form.parentId" placeholder="请选择" class="selectw"> <el-option v-for="parm in fmenu" :key="parm.id" :label="parm.name" :value="parm.id"></el-option> </el-select> </el-form-item> --> <!-- <el-form-item label="上级菜单"> <treeselect v-model="form.id" :options="fmenu" :normalizer="normalizer" :show-count="true" placeholder="选择上级菜单" /> </el-form-item> --> <el-form-item label="名称" prop="name"> <el-input v-model="form.name"></el-input> </el-form-item> <!-- <el-form-item label="图标" prop="moduleIcon"> <el-input v-model="form.moduleIcon"></el-input> </el-form-item>--> <el-form-item label="Path" prop="path"> <el-input v-model="form.path"></el-input> </el-form-item> <el-form-item label="Link" prop="link"> <el-input v-model="form.link"></el-input> </el-form-item> <el-form-item label="顺序" prop="sortNum"> <el-input v-model="form.sortNum"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="saveModule('form')">保存</el-button> <el-button v-show="!form.id" type="primary" @click="reset('form')">重置</el-button> <!-- <el-button type="primary" v-show="showdelete" @click="deleteModule">删除</el-button> --> </el-form-item> </el-form> </div> </el-col> <!-- <dot-dropdown :events="sysDropMenuEvents" :data="{node,data}" @addNode="addResource" /> --> </el-row> </div> </template> <script> import { listCategory, getCategory, delCategory, addCategory, updateCategory, exportCategory, listCategorytree } from "@/api/cms/category"; import DotDropdown from "./drop.vue"; import Treeselect from "@riophae/vue-treeselect"; import "@riophae/vue-treeselect/dist/vue-treeselect.css"; export default { name: "Category", components: { DotDropdown, Treeselect }, data() { return { tit:'新建同级', dropevents: [ { label: '新建同级', funcName: 'addPeerNode' }, { label: '新建子级', funcName: 'addNode' }, { label: '编辑', funcName: 'editNode' }, { label: '删除', funcName: 'removeNode' } ], showdelete: false, treeData: [], defaultProps: { children: "children", label: "label" }, form: { id: '', parentId:'', link:"", path: "", name: "", sortNum: "", }, // rules表单验证 rules: { // parentId: [ // { required: true, message: "请选择父级菜单", trigger: "blur" } // ], name: [ { required: true, message: "请输入菜单名称", trigger: "blur" } ], link: [{ required: true, message: "请输入link", trigger: "blur" }], path: [{ required: true, message: "请输入path", trigger: "blur" }], sortNum: [ { required: true, message: "请输入菜单顺序", trigger: "blur" } ] }, fmenu: [], }; }, created() { // this.getList(); this.getdata(); // this.getmenu(); // console.log(DotDropdown, " DotDropdown,"); }, methods: { //弹框的四个操作 //新建同级 addPeerNode(item){ console.log(item,'新建同级') this.reset('form') this.form.id='' // 这个能确保建立子级的同级 this.form.parentId=item.node.parent.data.id console.log(item.node.parent.data.id,"item.node.id") this.tit = '新建同级' }, //新建子级 addNode(item){ console.log(item,'新建子级') let id = item.data.id this.form.parentId = id this.reset('form') this.form.id='' this.tit = '新建子级' }, //编辑 editNode(item){ console.log(item,'编辑') this.tit = '编辑' let id = item.data.id getCategory(id) .then(res => { console.log(res, "根据id查信息"); this.form = res.data // console.log(JSON.stringify(res)) // this.form = res.data.data // this.$refs.tree.setCheckedNodes([]) // this.$refs.tree.setCheckedNodes([arr]) }) .catch(err => { this.loading = false; this.$message.error("用户管理获取失败,请稍后再试!"); }); }, //删除(ok) removeNode(item){ this.tit = '删除' let id = item.data.id // console.log(id,"kk") delCategory(id).then(res=>{ this.getdata(); this.reset('form') this.form.id='' this.tit="新建同级" this.$message.success("删除成功!"); }) .catch(err => { this.$message.error("表删除失败,请稍后再试!"); }) }, // 获取数据 getdata() { listCategorytree() .then(res => { this.treeData = res.categorys; }) .catch(err => { this.loading = false; this.$message.error("菜单管理列表失败,请稍后再试!"); }); }, // 添加 addModule() { // this.showdelete = false; this.form.link = ""; this.form.name = ""; this.form.path = ""; this.form.sortNum = ""; this.form.parentId = ""; this.form.id = ""; }, // 获取父级菜单 // getmenu() { // listCategory() // .then(response => { // //为啥返回的parentid不一样 // response.rows.forEach(a=>{ // a.parentId =0 // }) // this.fmenu = []; // const menu = { id: '', menuName: "主类目", children: [] }; // menu.children = this.handleTree(response.rows, "id"); // this.fmenu.push(menu); // }) // .catch(err => { // this.loading = false; // this.$message.error("父级菜单列表获取失败,请稍后再试!"); // }); // }, /** 转换菜单数据结构 */ // normalizer(node) { // // console.log(node,"nnn") // if (node.children && !node.children.length) { // delete node.children; // } // return { // id: node.id, // label: node.name, // children: node.children // }; // }, // 复选变单选 handleClick(data, checked, node) { if (checked) { // this.$refs.tree.setCheckedNodes([]); // this.$refs.tree.setCheckedNodes([data]); this.showdelete = true; } else { } }, // 点击节点 nodeclick(arr, node, self) { }, // 保存菜单 saveModule(editData) { this.$refs[editData].validate(valid => { if (valid) { console.log(this.form,this.form.parentId,"idiidid") if (this.form.id != '') { updateCategory(this.form).then(response => { this.msgSuccess("修改成功"); this.getdata(); // this.getmenu(); this.reset('form') }); } else { addCategory(this.form).then(response => { this.msgSuccess("新增成功"); this.getdata(); // this.getmenu(); this.reset('form') }); } } else { return false; } }); }, // 重置 reset(formName) { this.$refs[formName].resetFields(); } } }; </script> <style lang="less" scoped> .mt30 { margin-bottom: 30px; } .el-tree-node__content { position: relative; } .el-tree-node__content :hover, .el-tree-node__content :focus-within { .operate-btns { display: inline; } } .operate-btns { position: absolute; right: 2px; } // .bg-purple { background: #d3dce6; } .rightform{ border: #f1f3f7 solid 1px; padding: 30px 30px 20px 0px; box-shadow: 5px 5px 5px #cdcfcf; background: #fff } .lefttree{ border: #f1f3f7 solid 1px; padding: 30px 30px 20px 0px; box-shadow: 5px 5px 5px #cdcfcf; background: #fff } .tit-box{ // border-bottom: #666 solid 1px; text-align: center; width: 100%; /* margin: 0 auto; */ margin-bottom: 20px; } </style>
子组件drop.vue
<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 eventsa' :key="index" :divided="index >0" @click.native="clickMenu(item)"> {{item.label}} </el-dropdown-item> </el-dropdown-menu> </el-dropdown> </template> <script> export default { props: { eventsa: { type: Array, default: function() { return [ { label: '新建同级', funcName: 'addPeerNode' }, { label: '新建子级', funcName: 'addNode' }, // { label: '分配操作', funcName: 'distributeAction' }, { label: '编辑', funcName: 'editNode' }, { label: '删除', funcName: 'removeNode' } ] } }, // 注入数据 data: { type: Object } }, data(){ return{ // events2:[] } }, methods: { clickMenu(item) { console.log(item,"item",this.data) this.$emit(item.funcName, this.data) } } } </script> <style scoped> .el-icon-more:before { content: "\E794"; color: #c0c4cc; font-size: 15px; } .rotate { cursor: pointer; margin-left: 5px; transform: rotate(90deg); } /* .rotate:focus { width: 15px; height: 15px; border-radius: 4em; background-color: rgba(130, 132, 138, 0.2); } */ </style>
接口数据: