Vue组件扩展及权限管理的实现技巧
Vue 组件扩展及权限管理的实现技巧
# Vue 组件扩展
最近使用 ant-design-vue 作为 UI 库进行开发,不得不说 ant-design 的外观的确比 ElementUI 要好看,ElementUI 呈现的一种灰蒙蒙的感觉,而 ant-design 就让人感觉很亮,细节动画也很多。
另外,ant-design 的开发方式偏 React,很多示例也是使用 JSX 来编写的,在开发思路上得做一个切换。
在新的项目中,有很多 table 列表以及增删改查工作,列表样式基本都统一,而且下方有分页,列表第一页为序号,如下图所示:
本着少写一行就绝不多写一行,因此,我们可以把 table 封装起来,将一些属性设置为默认样式,但是有时候可能又会有所不同,因此,我们既要保持 table 的灵活性,同时又配置一些默认属性,因此,我们可以继承 table 原有的属性,同时进行一些扩展,并设置一些默认属性。这样使用 JSX 十分方便,我们可以如下进行开发一个 STable 进行扩展:
import T from 'ant-design-vue/es/table/Table'
export default {
data() {
return {
selectedRowKeys: [],
selectedRows: [],
localPagination: Object.assign(
{
showTotal: total => `总共有${total}条数据`,
showSizeChanger: true,
pageSize: 10,
current: 1
},
this.pagination
)
}
},
props: Object.assign({}, T.props, {
// 是否分页
showPagination: {
type: Boolean,
default: true
},
// 是否展示可选框
showSelect: {
type: Boolean,
default: true
},
// 显示序号
showSerialNo: {
type: Boolean,
default: true
}
}),
methods: {
handleTableChange(pagination, filters, sorter) {
this.localPagination = Object.assign({}, this.pagination, {
current: pagination.current,
pageSize: pagination.pageSize
})
this.$emit('change', pagination, filters, sorter)
},
handleRowSelect(selectedRowKeys, selectedRows) {
this.selectedRowKeys = selectedRowKeys
this.$emit('rowSelection', selectedRowKeys, selectedRows)
}
},
render() {
const props = {}
Object.keys(T.props).forEach(key => {
// 分页
if (key === 'showPagination') {
if (!this.showPagination) {
this.localPagination = false
}
} else if (key === 'pagination') {
props[key] = Object.assign({}, this.localPagination, this[key])
} else if (key === 'rowSelection') {
// 是否显示第一行的选择框
if (this.showSelect) {
props.rowSelection = {
selectedRows: this.selectedRows,
selectedRowKeys: this.selectedRowKeys,
onChange: (selectedRowKeys, selectedRows) => {
this.handleRowSelect(selectedRowKeys, selectedRows)
}
}
}
} else if (key === 'rowKey') {
props[key] = record => record.id
} else if (key === 'columns') {
const columns = [].concat(this[key])
// 添加序号
if (this.showSerialNo) {
const { pageSize, current } = this.localPagination
columns.splice(0, 0, {
title: '编号',
dataIndex: 'serialNo',
key: 'serialNo',
align: 'center',
customRender: (text, record, index) => (current - 1) * pageSize + index + 1
})
}
columns.forEach(col => {
col.align = col.align || 'center'
})
props[key] = columns
} else {
props[key] = this[key]
}
})
const table = (
<a-table {...{ props, scopedSlots: { ...this.$scopedSlots } }} onChange={this.handleTableChange}>
{Object.keys(this.$slots).map(name => (
<template slot={name}>{this.$slots[name]}</template>
))}
</a-table>
)
return <div>{table}</div>
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
在我们的组件中,我们引入ant-design-vue/es/table/Table
,并在组件的 Props 中继承 Table 的所有属性,Object.assign({}, T.props,{//扩展属性})
,在渲染的时候,我们可以循环 Table 的 Props 属性,如果没有设置属性,我们自己给它设置一些默认属性,最终再把所有的属性绑定到 table 上,需要注意的是,在循环 Table 的 Props 属性时候,对于引用类型不可以直接进行修改,否则会陷入循环渲染。
这样,我们既保留了ant-design-vue/es/table/Table
所有可配置的属性,同时也添加了针对项目的默认属性,使用起来十分方便也易于扩展。
# 增删改查权限的处理
vue 权限管理很多人都说过,不过常见的都是路由权限,登录之后根据用户的权限动态生成路由。这是页面权限,现在系统的权限更变态,不止页面权限,还有页面里面的权限,也就是某些用户只能看不能编辑,某些用户只能新增不能删除等等,其实总结起来就是页面增删改查权限也得配置。
好嘛,需求来了就得开干,首先,我们得知道用户有哪些权限,其次,我们要知道页面上的操作需要哪些权限,如果用户有这个权限,我们就显示这个模块,否则,我们不显示这个。例如如果用户没有修改权限,我们就可以不显示修改按钮。这种功能我们使用 Vue 指令就很好完成,代码如下:
// config: ['GET./api/v1/cachet', 'PATCH./api/v1/users']
import config from './config'
// 判断按钮以及页面各个部分是否有权限,没有的话就会移除当前el
export default {
bind(el, binding) {
setTimeout(() => {
if (!config.includes(binding.value)) {
el.parentNode.removeChild(el)
}
}, 0)
}
}
2
3
4
5
6
7
8
9
10
11
12
然后我们在 main.js 中注册该指令:
import permissionDirective from './directives/permission'
Vue.directive('permission', permissionDirective)
2
3
然后在页面中可以这样使用:
<a-button v-permission="'DELETE./api/v1/users'">新建</a-button>