Browse Source

feat: 优化menu

2637309949@qq.com 5 years ago
parent
commit
770a1e9402
4 changed files with 208 additions and 47 deletions
  1. 123 0
      src/components/Cascader/index.vue
  2. 16 27
      src/components/Tree/index.vue
  3. 4 6
      src/utils/tree.js
  4. 65 14
      src/views/menu/index.vue

+ 123 - 0
src/components/Cascader/index.vue

@@ -0,0 +1,123 @@
+<template>
+  <el-cascader
+    ref="cascader"
+    v-model="valueArray"
+    :options="options"
+    :props="props"
+    :style="styles"
+    :change-on-select="changeonselect"
+    :clearable="true"
+    :filterable="true"
+    @change="change"
+  />
+</template>
+<script>
+
+export default {
+  name: 'Cascader',
+  props: {
+    api: {
+      type: Function,
+      default: () => {}
+    },
+    code: {
+      type: String,
+      default: () => ''
+    },
+    value: {
+      type: String,
+      default: ''
+    },
+    styles: {
+      type: String,
+      default: 'width:100%'
+    },
+    placeholder: {
+      type: String,
+      default: () => '请选择'
+    },
+    dataQuery: {
+      type: Object,
+      default: () => {
+        return {
+          name: '',
+          code: '',
+          cn_id: ''
+        }
+      }
+    },
+    props: {
+      type: Object,
+      default: () => {
+        return {
+          children: 'nodes',
+          label: 'name',
+          value: 'id'
+        }
+      }
+    },
+    changeonselect: {
+      type: Boolean,
+      default: true
+    }
+  },
+  data: function() {
+    return {
+      options: []
+    }
+  },
+  computed: {
+    valueArray: {
+      get: function() {
+        if (this.value === '') return ['']
+        return this.getTreeDeepArr(this.value, this.options)
+      },
+      set: function(newValue) {
+        this.$emit('update:value', newValue[newValue.length - 1])
+      }
+    }
+  },
+  watch: {
+  },
+  created() {
+    this.api(this.dataQuery).then(res => {
+      res.data.unshift({ id: '', text: '无', parent: '', nodes: null })
+      this.options = res.data
+    })
+  },
+  methods: {
+    change() {
+      this.$refs.cascader.toggleDropDownVisible(false)
+    },
+    getTreeDeepArr(key, treeData) {
+      var _this = this
+      const arr = []
+      let returnArr = []
+      let depth = 0
+      function childrenEach(childrenData, depthN) {
+        for (var j = 0; j < childrenData.length; j++) {
+          depth = depthN
+          arr[depthN] = (childrenData[j].id)
+          if (childrenData[j].id === key) {
+            returnArr = arr.slice(0, depthN + 1)
+            break
+          } else {
+            if (childrenData[j].nodes) {
+              depth++
+              childrenEach(childrenData[j].nodes, depth)
+            }
+          }
+        }
+        _this.$emit('childFn', returnArr.length)
+        return returnArr
+      }
+      return childrenEach(treeData, depth)
+    }
+  }
+}
+</script>
+<style scoped>
+  .el-cascader-panel{
+    overflow: hidden !important;
+  }
+</style>

+ 16 - 27
src/components/Tree/index.vue

@@ -6,10 +6,10 @@
       </el-header>
       </el-header>
       <el-main class="tree-main" style="padding: 15px 0;">
       <el-main class="tree-main" style="padding: 15px 0;">
         <el-tree
         <el-tree
-          :data="treeData"
+          :data="data"
           node-key="id"
           node-key="id"
-          :props="defaultProps"
-          :default-expanded-keys="defaultExpends"
+          :props="props"
+          :default-expanded-keys="expends"
           :style="styleObject"
           :style="styleObject"
           :highlight-current="false"
           :highlight-current="false"
           @node-click="click"
           @node-click="click"
@@ -25,13 +25,13 @@ export default {
   props: {
   props: {
     title: {
     title: {
       type: String,
       type: String,
-      default: ''
+      default: 'Menu'
     },
     },
-    api: {
+    fetch: {
       type: Function,
       type: Function,
       default: () => {}
       default: () => {}
     },
     },
-    dataQuery: {
+    query: {
       type: Object,
       type: Object,
       default: () => {}
       default: () => {}
     },
     },
@@ -43,43 +43,32 @@ export default {
       type: Function,
       type: Function,
       default: () => {}
       default: () => {}
     },
     },
-    isShowAll: {
-      type: Boolean,
-      default: () => true
-    },
     styleObject: {
     styleObject: {
       type: Object,
       type: Object,
       default: () => {}
       default: () => {}
     },
     },
-    defaultExpends: {
+    expends: {
       type: Array,
       type: Array,
       default: () => []
       default: () => []
     },
     },
     props: {
     props: {
       type: Object,
       type: Object,
-      default: () => {}
+      default: () => ({
+        children: 'nodes',
+        label: 'name',
+        value: 'id'
+      })
     }
     }
   },
   },
   data: function() {
   data: function() {
     return {
     return {
-      treeData: [],
-      defaultProps: {
-        children: 'nodes',
-        label: 'name',
-        value: 'id'
-      }
+      data: []
     }
     }
   },
   },
   created() {
   created() {
-    if (typeof this.props === 'object') {
-      Object.assign(this.defaultProps, this.props)
-    }
-    this.api(this.dataQuery).then(res => {
-      this.treeData = addNodesAttr(res.data || [], 'opened', false) || []
-      if (this.isShowAll) {
-        this.treeData.unshift({ id: '', nodes: null, opened: false, parent: '', tag: { id: '' }, text: 'All' })
-      }
-      this.callBack(res.data)
+    this.fetch(this.query).then(({ data }) => {
+      this.data = addNodesAttr(data, 'opened', false) || []
+      this.callBack(data)
     })
     })
   }
   }
 }
 }

+ 4 - 6
src/utils/tree.js

@@ -1,9 +1,7 @@
 export function addNodesAttr(nodes, attr, val) {
 export function addNodesAttr(nodes, attr, val) {
-  nodes.forEach((item, i) => {
-    nodes[i][attr] = val
-    if (nodes[i].nodes !== null && nodes[i].nodes.length > 0) {
-      addNodesAttr(nodes[i].nodes, attr, val)
-    }
+  return nodes.map(item => {
+    item[attr] = val
+    item.nodes = addNodesAttr(item.nodes || [], attr, val)
+    return item
   })
   })
-  return nodes
 }
 }

+ 65 - 14
src/views/menu/index.vue

@@ -4,13 +4,7 @@
       <el-card>
       <el-card>
         <el-container>
         <el-container>
           <el-aside :width="treeWidth">
           <el-aside :width="treeWidth">
-            <tree
-              title="Menu"
-              :api="this.$api.sysMenu.tree"
-              :data-query="treeQuery"
-              :call-back="getTreeDataCallBack"
-              :click="treeClick"
-            />
+            <tree :fetch="this.$api.sysMenu.tree" :query="nodeQuery" :call-back="getTreeDataCallBack" :click="nodeClick" />
           </el-aside>
           </el-aside>
           <el-container>
           <el-container>
             <el-header height="120">
             <el-header height="120">
@@ -69,6 +63,53 @@
         </el-container>
         </el-container>
       </el-card>
       </el-card>
     </el-main>
     </el-main>
+    <el-dialog :title="dialogStatus==='create'?'Create':'Edit'" :visible.sync="dialogVisible" width="40%" @close="dialogClose">
+      <el-form ref="dataForm" :size="size" :rules="rules" :model="temp" label-width="85px">
+        <el-form-item label="Name:" prop="name">
+          <el-input v-model="temp.name" placeholder="Please input name" />
+        </el-form-item>
+        <el-form-item label="Code:" prop="code">
+          <el-input v-model="temp.code" placeholder="Please input code" />
+        </el-form-item>
+        <el-form-item label="Url:" prop="url">
+          <el-input v-model="temp.url" placeholder="Please input url" />
+        </el-form-item>
+        <el-form-item label="Com:" prop="component">
+          <el-input v-model="temp.component" placeholder="Please input component" />
+        </el-form-item>
+        <el-form-item label="Order:" prop="order_num">
+          <el-input v-model.number="temp.order_num" placeholder="Please input order" />
+        </el-form-item>
+        <el-form-item label="Icon:" prop="icon">
+          <el-input v-model="temp.icon" placeholder="Please input icon" />
+        </el-form-item>
+        <el-form-item label="Perms:" prop="perms">
+          <el-input v-model="temp.perms" placeholder="Please input perms" />
+        </el-form-item>
+        <el-form-item label="Type:" prop="type">
+          <el-select v-model="temp.type" placeholder="Please input type" style="width: 100%;">
+            <el-option v-for="item in menuTypes" :key="item.id" :label="item.name" :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="Parent:" prop="parent">
+          <cascader
+            :api="this.$api.sysMenu.tree"
+            :data-query="nodeQuery"
+            :value.sync="temp.parent"
+          />
+        </el-form-item>
+        <el-form-item label="Hidden:" prop="hidden">
+          <el-radio v-model="temp.hidden" :label="1">是</el-radio>
+          <el-radio v-model="temp.hidden" :label="0">否</el-radio>
+        </el-form-item>
+      </el-form>
+      <footer slot="footer" class="dialog-footer">
+        <el-button :size="size" @click="dialogVisible = false">取 消</el-button>
+        <el-button :size="size" type="primary" @click="dialogStatus==='create'?createData():updateData()">确 定
+        </el-button>
+      </footer>
+    </el-dialog>
+
   </el-container>
   </el-container>
 </template>
 </template>
 
 
@@ -76,10 +117,11 @@
 import { mapGetters } from 'vuex'
 import { mapGetters } from 'vuex'
 import Tree from '@/components/Tree'
 import Tree from '@/components/Tree'
 import Sheet from '@/components/Sheet'
 import Sheet from '@/components/Sheet'
+import Cascader from '@/components/Cascader'
 
 
 export default {
 export default {
   name: 'Menu',
   name: 'Menu',
-  components: { Tree, Sheet },
+  components: { Tree, Sheet, Cascader },
   data() {
   data() {
     return {
     return {
       tableColumns: [
       tableColumns: [
@@ -147,11 +189,10 @@ export default {
         name: '',
         name: '',
         code: '',
         code: '',
         cn_id: '',
         cn_id: '',
-        type_op: '>=',
-        type: '0',
-        hidden: 0
+        type: '0'
+      },
+      nodeQuery: {
       },
       },
-      treeQuery: { del_falg: 0, hidden: 0, type_op: '>=', type: 0 },
       temp: {
       temp: {
         id: undefined,
         id: undefined,
         name: '',
         name: '',
@@ -203,7 +244,10 @@ export default {
   },
   },
   created() {},
   created() {},
   methods: {
   methods: {
-    treeClick(node) {},
+    nodeClick(node) {
+      this.dataQuery.cn_id = node.id
+      this.$refs.qtable.getData()
+    },
     getTreeDataCallBack(tree) {},
     getTreeDataCallBack(tree) {},
     handleChange(value) {},
     handleChange(value) {},
     createData() {},
     createData() {},
@@ -214,7 +258,14 @@ export default {
     deleteBatch() {},
     deleteBatch() {},
     dialogClose() {},
     dialogClose() {},
     create() {},
     create() {},
-    edit(row) {}
+    edit(row) {
+      this.dialogStatus = 'update'
+      this.dialogVisible = true
+      this.$nextTick(() => {
+        this.$refs['dataForm'].clearValidate()
+        this.temp = Object.assign({}, row)
+      })
+    }
   }
   }
 }
 }
 </script>
 </script>