Browse Source

1. 优化树形数据转换方法
2. 移除jsx配置

daxiongYang 7 years ago
parent
commit
ffc7d96e0f
6 changed files with 267 additions and 124 deletions
  1. 2 2
      .babelrc
  2. 0 3
      package.json
  3. 2 2
      src/element-ui/index.js
  4. 12 8
      src/utils/index.js
  5. 132 0
      src/views/menu/add-or-update.vue
  6. 119 109
      src/views/menu/index.vue

+ 2 - 2
.babelrc

@ -5,7 +5,7 @@
5 5
    }],
6 6
    "stage-2"
7 7
  ],
8
  "plugins": ["transform-runtime", "transform-vue-jsx", ["component", [
8
  "plugins": ["transform-runtime", ["component", [
9 9
    {
10 10
      "libraryName": "element-ui",
11 11
      "styleLibraryName": "theme-chalk"
@ -14,7 +14,7 @@
14 14
  "env": {
15 15
    "test": {
16 16
      "presets": ["env", "stage-2"],
17
      "plugins": ["transform-es2015-modules-commonjs", "dynamic-import-node", "transform-vue-jsx", "istanbul"]
17
      "plugins": ["transform-es2015-modules-commonjs", "dynamic-import-node"]
18 18
    }
19 19
  }
20 20
}

+ 0 - 3
package.json

@ -15,10 +15,7 @@
15 15
  },
16 16
  "dependencies": {
17 17
    "axios": "0.17.1",
18
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
19 18
    "babel-plugin-component": "0.10.1",
20
    "babel-plugin-syntax-jsx": "^6.18.0",
21
    "babel-plugin-transform-vue-jsx": "^3.5.1",
22 19
    "babel-polyfill": "6.26.0",
23 20
    "element-ui": "2.1.0",
24 21
    "vue": "2.5.2",

+ 2 - 2
src/element-ui/index.js

@ -20,7 +20,7 @@ import {
20 20
  MenuItem,
21 21
  MenuItemGroup,
22 22
  Input,
23
  // InputNumber,
23
  InputNumber,
24 24
  Radio,
25 25
  RadioGroup,
26 26
  // RadioButton,
@ -89,7 +89,7 @@ Vue.use(Submenu)
89 89
Vue.use(MenuItem)
90 90
Vue.use(MenuItemGroup)
91 91
Vue.use(Input)
92
// Vue.use(InputNumber)
92
Vue.use(InputNumber)
93 93
Vue.use(Radio)
94 94
Vue.use(RadioGroup)
95 95
// Vue.use(RadioButton)

+ 12 - 8
src/utils/index.js

@ -13,18 +13,22 @@ export function isAuth (key) {
13 13
 * @param {*} pid
14 14
 */
15 15
export function treeDataTranslate (data, id, pid) {
16
  var res = []
17
  var temp = {}
16 18
  for (var i = 0; i < data.length; i++) {
17
    for (var j = 0; j < data.length; j++) {
18
      if (data[j][id] === data[i][pid]) {
19
        data[j]['children'] = data[j]['children'] || []
20
        data[j]['children'].push(data[i])
21
        data.splice(i, 1)
22
        i--
23
        break
19
    temp[data[i][id]] = data[i]
20
  }
21
  for (var k = 0; k < data.length; k++) {
22
    if (temp[data[k][pid]] && data[k][id] !== data[k][pid]) {
23
      if (!temp[data[k][pid]]['children']) {
24
        temp[data[k][pid]]['children'] = []
24 25
      }
26
      temp[data[k][pid]]['children'].push(data[k])
27
    } else {
28
      res.push(data[k])
25 29
    }
26 30
  }
27
  return data
31
  return res
28 32
}
29 33
30 34
/**

+ 132 - 0
src/views/menu/add-or-update.vue

@ -0,0 +1,132 @@
1
<template>
2
  <el-dialog
3
    :title="!dataForm.userId ? '新增' : '修改'"
4
    :close-on-click-modal="false"
5
    :visible.sync="visible">
6
    <el-form :model="dataForm" :rules="dataRule" ref="dataForm" label-width="80px">
7
      <el-form-item label="类型" prop="type">
8
        <el-radio-group v-model="dataForm.type">
9
          <el-radio :label="0">目录</el-radio>
10
          <el-radio :label="1">菜单</el-radio>
11
          <el-radio :label="2">按钮</el-radio>
12
        </el-radio-group>
13
      </el-form-item>
14
      <el-form-item label="菜单名称" prop="name">
15
        <el-input v-model="dataForm.name" placeholder="菜单名称或按钮名称"></el-input>
16
      </el-form-item>
17
      <el-form-item label="上级菜单" prop="parentName">
18
        <el-input v-model="dataForm.parentName" placeholder="一级菜单"></el-input>
19
        <el-tree
20
          :data="menuList"
21
          :props="menuListTreeProps"
22
          node-key="menuId"
23
          ref="menuListTree"
24
          :default-expand-all="true"
25
          show-checkbox>
26
        </el-tree>
27
      </el-form-item>
28
      <el-form-item label="菜单URL" prop="url">
29
        <el-input v-model="dataForm.url" placeholder="菜单URL"></el-input>
30
      </el-form-item>
31
      <el-form-item label="授权标识" prop="perms">
32
        <el-input v-model="dataForm.perms" placeholder="多个用逗号分隔, 如: user:list,user:create"></el-input>
33
      </el-form-item>
34
      <el-form-item label="排序号" prop="orderNum">
35
        <el-input-number v-model="dataForm.orderNum" :min="1" :max="10" label="排序号"></el-input-number>
36
      </el-form-item>
37
      <el-form-item label="菜单图标" prop="icon">
38
        <el-input v-model="dataForm.icon" placeholder="菜单图标"></el-input>
39
      </el-form-item>
40
      <el-form-item label="" size="mini">
41
        <span>获取图标方法: <a href="http://element-cn.eleme.io/#/zh-CN/component/icon" target="_blank">http://element-cn.eleme.io/#/zh-CN/component/icon</a></span>
42
      </el-form-item>
43
    </el-form>
44
    <span slot="footer" class="dialog-footer">
45
      <el-button @click="visible = false">取消</el-button>
46
      <el-button type="primary" @click="dataFormSubmit()">确定</el-button>
47
    </span>
48
  </el-dialog>
49
</template>
50
51
<script>
52
  import API from '@/api'
53
  import { treeDataTranslate } from '@/utils'
54
  export default {
55
    data () {
56
      var validateUrl = (rule, value, callback) => {
57
        if (this.dataForm.type === 1 && !/\S/.test(value)) {
58
          callback(new Error('菜单URL不能为空'))
59
        } else {
60
          callback()
61
        }
62
      }
63
      return {
64
        visible: false,
65
        dataForm: {
66
          id: 0,
67
          type: '',
68
          name: '',
69
          parentName: '',
70
          url: '',
71
          perms: '',
72
          orderNum: '',
73
          icon: ''
74
        },
75
        dataRule: {
76
          name: [
77
            { required: true, message: '菜单名称不能为空', trigger: 'blur' }
78
          ],
79
          url: [
80
            { validator: validateUrl, trigger: 'blur' }
81
          ]
82
        },
83
        menuList: [],
84
        menuListTreeProps: {
85
          label: 'name',
86
          children: 'children'
87
        }
88
      }
89
    },
90
    methods: {
91
      init (id) {
92
        this.dataForm.id = id || 0
93
        API.menu.select().then(({data}) => {
94
          this.menuList = treeDataTranslate(data.menuList, 'menuId', 'parentId') || []
95
          console.log(this.menuList)
96
        })
97
        this.visible = true
98
      },
99
      dataFormSubmit () {
100
        this.$refs['dataForm'].validate((valid) => {
101
          if (valid) {
102
            var params = {
103
              'userId': this.dataForm.userId || undefined,
104
              'username': this.dataForm.userName,
105
              'password': this.dataForm.password,
106
              'email': this.dataForm.email,
107
              'mobile': this.dataForm.mobile,
108
              'status': this.dataForm.status,
109
              'roleIdList': this.dataForm.roleIdList
110
            }
111
            var tick = this.dataForm.userId ? API.user.update(params) : API.user.add(params)
112
            tick.then(({data}) => {
113
              if (data && data.code === 0) {
114
                this.$message({
115
                  message: '操作成功',
116
                  type: 'success',
117
                  duration: 1500,
118
                  onClose: () => {
119
                    this.addOrUpdateVisible = false
120
                    this.getDataList()
121
                  }
122
                })
123
              } else {
124
                this.$message.error(data.msg)
125
              }
126
            })
127
          }
128
        })
129
      }
130
    }
131
  }
132
</script>

+ 119 - 109
src/views/menu/index.vue

@ -5,60 +5,85 @@
5 5
        <el-button type="primary" @click="addOrUpdateHandle()">新增</el-button>
6 6
      </el-form-item>
7 7
    </el-form>
8
    <el-tree
8
    <tree-table
9
      :columns="treeTableColumns"
9 10
      :data="dataList"
10
      :props="dataListTreeProps"
11
      :highlight-current="true"
12
      node-key="menuId"
13
      :default-expand-all="true"
14
      :expand-on-click-node="false"
15
      @mouseleave.native="dataListTreeActiveNodeId = 0"
16
      :render-content="dataListTreeRenderContent">
17
    </el-tree>
11
      highlight-current-row
12
      border
13
      style="width: 100%;">
14
      <el-table-column
15
        prop="name"
16
        header-align="center"
17
        align="center"
18
        label="菜单名称">
19
      </el-table-column>
20
      <el-table-column
21
        prop="parentName"
22
        header-align="center"
23
        align="center"
24
        label="上级菜单">
25
      </el-table-column>
26
      <el-table-column
27
        prop="icon"
28
        header-align="center"
29
        align="center"
30
        label="图标">
31
      </el-table-column>
32
      <el-table-column
33
        prop="type"
34
        header-align="center"
35
        align="center"
36
        label="类型">
37
        <template slot-scope="scope">
38
          <el-tag v-if="scope.row.type === 0" size="small">目录</el-tag>
39
          <el-tag v-else-if="scope.row.type === 1" size="small" type="success">菜单</el-tag>
40
          <el-tag v-else-if="scope.row.type === 2" size="small" type="info">按钮</el-tag>
41
        </template>
42
      </el-table-column>
43
      <el-table-column
44
        prop="orderNum"
45
        header-align="center"
46
        align="center"
47
        label="排序号">
48
      </el-table-column>
49
      <el-table-column
50
        prop="url"
51
        header-align="center"
52
        align="center"
53
        width="150"
54
        :show-overflow-tooltip="true"
55
        label="菜单URL">
56
      </el-table-column>
57
      <el-table-column
58
        prop="perms"
59
        header-align="center"
60
        align="center"
61
        width="150"
62
        :show-overflow-tooltip="true"
63
        label="授权标识">
64
      </el-table-column>
65
      <el-table-column
66
        fixed="right"
67
        header-align="center"
68
        align="center"
69
        width="200"
70
        label="操作">
71
        <template slot-scope="scope">
72
          <el-button type="text" size="small" @click="addOrUpdateHandle(scope.row.userId)">修改</el-button>
73
          <el-button type="text" size="small" @click="deleteHandle(scope.row.userId)">删除</el-button>
74
        </template>
75
      </el-table-column>
76
    </tree-table>
18 77
    <!-- 弹窗, 新增 / 修改 -->
19
    <el-dialog
20
      :title="!addOrUpdateForm.userId ? '新增' : '修改'"
21
      :close-on-click-modal="false"
22
      :visible.sync="addOrUpdateDialogVisible">
23
      <el-form :model="addOrUpdateForm" :rules="addOrUpdateRule" ref="addOrUpdateForm" label-width="80px">
24
        <el-form-item label="用户名" prop="userName">
25
          <el-input v-model="addOrUpdateForm.userName" placeholder="登录帐号"></el-input>
26
        </el-form-item>
27
        <el-form-item label="密码" prop="password" :class="{ 'is-required': !addOrUpdateForm.userId }">
28
          <el-input v-model="addOrUpdateForm.password" type="password" placeholder="密码"></el-input>
29
        </el-form-item>
30
        <el-form-item label="确认密码" prop="comfirmPassword" :class="{ 'is-required': !addOrUpdateForm.userId }">
31
          <el-input v-model="addOrUpdateForm.comfirmPassword" type="password" placeholder="确认密码"></el-input>
32
        </el-form-item>
33
        <el-form-item label="邮箱" prop="email">
34
          <el-input v-model="addOrUpdateForm.email" placeholder="邮箱"></el-input>
35
        </el-form-item>
36
        <el-form-item label="手机号" prop="mobile">
37
          <el-input v-model="addOrUpdateForm.mobile" placeholder="手机号"></el-input>
38
        </el-form-item>
39
        <el-form-item label="角色" size="mini" prop="roleIdList">
40
          <el-checkbox-group v-model="addOrUpdateForm.roleIdList">
41
            <!-- <el-checkbox v-for="role in roleList" :key="role.roleId" :label="role.roleId">{{ role.roleName }}</el-checkbox> -->
42
          </el-checkbox-group>
43
        </el-form-item>
44
        <el-form-item label="状态" size="mini" prop="status">
45
          <el-radio-group v-model="addOrUpdateForm.status">
46
            <el-radio :label="0">禁用</el-radio>
47
            <el-radio :label="1">正常</el-radio>
48
          </el-radio-group>
49
        </el-form-item>
50
      </el-form>
51
      <span slot="footer" class="dialog-footer">
52
        <el-button @click="addOrUpdateDialogVisible = false">取消</el-button>
53
        <el-button type="primary" @click="addOrUpdateFormSubmit()">确定</el-button>
54
      </span>
55
    </el-dialog>
78
    <add-or-update v-if="addOrUpdateVisible" ref="addOrUpdate"></add-or-update>
56 79
  </div>
57 80
</template>
58 81
59 82
<script>
83
  import TreeTable from '@/components/tree-table'
60 84
  import API from '@/api'
61 85
  import { treeDataTranslate } from '@/utils'
86
  import AddOrUpdate from './add-or-update'
62 87
  import { isEmail, isMobile } from '@/utils/validate'
63 88
  export default {
64 89
    data () {
@ -93,15 +118,24 @@
93 118
        }
94 119
      }
95 120
      return {
96
        dataForm: {},
97
        dataListTreeProps: {
98
          label: 'name',
99
          children: 'children'
121
        dataForm: {
122
          userName: ''
100 123
        },
101
        dataListTreeHandlebarVisible: false,
102
        dataListTreeActiveNodeId: 0,
124
        treeTableColumns: [
125
          {
126
            text: 'ID',
127
            value: 'menuId',
128
            width: '120'
129
          }
130
        ],
103 131
        dataList: [],
104
        addOrUpdateDialogVisible: false,
132
        pageIndex: 1,
133
        pageSize: 10,
134
        totalPage: 0,
135
        dataListLoading: false,
136
        dataListSelections: [],
137
        roleList: [],
138
        addOrUpdateVisible: false,
105 139
        addOrUpdateForm: {
106 140
          userId: 0,
107 141
          userName: '',
@ -133,6 +167,10 @@
133 167
        }
134 168
      }
135 169
    },
170
    components: {
171
      TreeTable,
172
      AddOrUpdate
173
    },
136 174
    activated () {
137 175
      this.getDataList()
138 176
    },
@ -145,49 +183,37 @@
145 183
          this.dataListLoading = false
146 184
        })
147 185
      },
148
      // 树形数据列表, 呈现内容
149
      dataListTreeRenderContent (h, { node, data, store }) {
150
        return (
151
          <div on-mouseenter={ () => this.dataListTreeMouseenterHandle(node) } class="tree-handlebar">
152
            <span>{ data.menuId + '. ' + node.label }</span>
153
            {
154
              this.dataListTreeActiveNodeId === node.id
155
              ? <span class="tree-handlebar__btns">
156
                <el-button type="text" on-click={ () => this.append(data) }>修改</el-button>
157
                <el-button type="text" on-click={ () => this.remove(node, data) }>删除</el-button>
158
              </span>
159
              : ''
160
            }
161
          </div>
162
        )
163
      },
164
      // 树形数据列表, 数据进入处理
165
      dataListTreeMouseenterHandle (node) {
166
        this.dataListTreeActiveNodeId = node.id
186
      // 多选
187
      selectionChangeHandle (val) {
188
        this.dataListSelections = val
167 189
      },
168 190
      // 新增 / 修改
169 191
      addOrUpdateHandle (id) {
170
        this.addOrUpdateForm.userId = id || 0
171
        API.role.listByUser().then(({data}) => {
172
          this.roleList = data && data.code === 0 ? data.list : []
173
        }).then(() => {
174
          this.addOrUpdateDialogVisible = true
175
          this.$nextTick(() => {
176
            this.$refs['addOrUpdateForm'].resetFields()
177
          })
178
        }).then(() => {
179
          if (this.addOrUpdateForm.userId) {
180
            API.user.info(this.addOrUpdateForm.userId).then(({data}) => {
181
              if (data && data.code === 0) {
182
                this.addOrUpdateForm.userName = data.user.username
183
                this.addOrUpdateForm.email = data.user.email
184
                this.addOrUpdateForm.mobile = data.user.mobile
185
                this.addOrUpdateForm.roleIdList = data.user.roleIdList
186
                this.addOrUpdateForm.status = data.user.status
187
              }
188
            })
189
          }
192
        this.addOrUpdateVisible = true
193
        this.$nextTick(() => {
194
          this.$refs.addOrUpdate.init(id)
190 195
        })
196
        // this.addOrUpdateForm.userId = id || 0
197
        // API.role.listByUser().then(({data}) => {
198
        //   this.roleList = data && data.code === 0 ? data.list : []
199
        // }).then(() => {
200
        //   this.addOrUpdateVisible = true
201
        //   this.$nextTick(() => {
202
        //     this.$refs['addOrUpdateForm'].resetFields()
203
        //   })
204
        // }).then(() => {
205
        //   if (this.addOrUpdateForm.userId) {
206
        //     API.user.info(this.addOrUpdateForm.userId).then(({data}) => {
207
        //       if (data && data.code === 0) {
208
        //         this.addOrUpdateForm.userName = data.user.username
209
        //         this.addOrUpdateForm.email = data.user.email
210
        //         this.addOrUpdateForm.mobile = data.user.mobile
211
        //         this.addOrUpdateForm.roleIdList = data.user.roleIdList
212
        //         this.addOrUpdateForm.status = data.user.status
213
        //       }
214
        //     })
215
        //   }
216
        // })
191 217
      },
192 218
      // 新增 / 修改, 提交
193 219
      addOrUpdateFormSubmit () {
@ -210,7 +236,7 @@
210 236
                  type: 'success',
211 237
                  duration: 1500,
212 238
                  onClose: () => {
213
                    this.addOrUpdateDialogVisible = false
239
                    this.addOrUpdateVisible = false
214 240
                    this.getDataList()
215 241
                  }
216 242
                })
@ -250,19 +276,3 @@
250 276
    }
251 277
  }
252 278
</script>
253
254
<style lang="scss">
255
  .mod-menu {
256
    .tree-handlebar {
257
      width: 100%;
258
    }
259
    .tree-handlebar__btns {
260
      margin-left: 15px;
261
      > .el-button {
262
        padding: 0;
263
        font-size: 12px;
264
      }
265
    }
266
  }
267
</style>
268