1、已获取当前账号的操作配置权限(arr),在每个页面中有对应的效果
1)可以通过自定义指令,来对相对应的标签进行操作。
2)表单操作部分权限逻辑处理在封装的组件中
1)按钮等(自定义指令):
// 按钮权限指令必须加在dom元素(例如:span),不能加在<template></template>上
Vue.directive('btnPermission', {
// 当被绑定的元素插入到 DOM 中时……
inserted: function(el, binding, vnode, oldVnode) {
// console.warn(el)
// console.warn(binding.value.code)
// console.log(router.history.current.meta.btn)
var code = binding.value.code
var arr = router.history.current.meta.btn
if (arr && arr.length > 0) {
var flag = arr.findIndex(function(value, index, arr) {
return value.componentCode === code
})
if (flag === -1) {
el.parentNode.removeChild(el)
}
} else {
// 当前页面没有按钮,直接删除所有按钮
el.parentNode.removeChild(el)
}
}
})
// 当没有某个按钮权限时,显示的元素
Vue.directive('btnNoPermission', {
inserted: function(el, binding, vnode, oldVnode) {
var code = binding.value.code
var arr = router.history.current.meta.btn
if (arr && arr.length > 0) {
var flag = arr.findIndex(function(value, index, arr) {
return value.componentCode === code
})
if (flag !== -1) {
el.parentNode.removeChild(el)
}
}
}
})
html使用:
<template slot="dictName" slot-scope="text, record">
<!-- 判断是没有该权限--》删除操作 -->
<!-- 有该权限会显示 -->
<span v-btnPermission="{code: 'DataDictionary_settingItems'}">
<a v-if="record.validStatus===1" @click="settingData(record)">{{ record.dictName }}</a>
<span v-else>{{ record.dictName }}</span>
</span>
<!-- 判断是有该权限--》删除操作 -->
<!-- 无权限时所要显示的 -->
<span v-btnNoPermission="{code: 'DataDictionary_settingItems'}">
<span>{{ record.dictName }}</span>
</span>
</template>
2)封装的组件
<template>
<span>
<span v-if="btnList.length > 0">
<a @click="func(btnList[0].funcName, btnList[0].funcArgs)">{{ btnList[0].name }}</a>
<a-divider v-if="btnList.length > 1" type="vertical" />
</span>
<span v-if="btnList.length > 1">
<a @click="func(btnList[1].funcName, btnList[1].funcArgs)">{{ btnList[1].name }}</a>
<a-divider v-if="btnList.length > 2" type="vertical" />
</span>
<span v-if="btnList.length === 3">
<a @click="func(btnList[2].funcName, btnList[2].funcArgs)">{{ btnList[2].name }}</a>
</span>
<a-dropdown v-if="btnList.length > 3">
<a class="ant-dropdown-link">
更多 <a-icon type="down" />
</a>
<a-menu slot="overlay">
<template v-for="(item, index) in btnList">
<a-menu-item v-if="index > 1" :key="item.code">
<a @click="func(item.funcName, item.funcArgs)">{{ item.name }}</a>
</a-menu-item>
</template>
</a-menu>
</a-dropdown>
</span>
</template>
<script>
export default {
name: 'KTableBtn',
props: {
// 列表中某一条数据的对象
record: {
type: Object,
default: () => {},
required: true
},
// 列表中所有可能出现的按钮数组
// 按钮对象示例
// {
// code: 'GoodsList_putOnShelves', // 按钮code
// flag: record.saleStatus === 0, // 按钮是否显示的逻辑(表达式或function返回值)
// name: '上架', // 按钮名称
// funcName: 'handleSaleStatus', // 点击按钮调用的方法名称
// funcArgs: [1, false, record] // 点击按钮调用的方法所需的参数数组
// }
btnArr: {
type: Function,
required: true
}
},
data() {
return {
metaBtnList: [],
btnList: []
}
},
watch: {
'record': {
deep: true,
handler(val) {
this.createBtn()
}
}
},
created() {
this.createBtn()
},
methods: {
createBtn() {
this.btnList = []
// 从路由中拿到当前页面拥有的按钮权限列表metaBtnList
this.metaBtnList = this.$route.meta.btn
// 生成某条数据可以显示的按钮列表btnList
var arr = this.btnArr(this.record)
for (const item of arr.values()) {
var btnPermission = this.metaBtnList.findIndex(e => {
return e.componentCode === item.code
})
if (item.flag && btnPermission !== -1) {
this.btnList.push(item)
}
}
},
func(funcName, arr) {
this.$emit('btnClick', funcName, arr)
}
}
}
</script>
父组件使用:
html:
<span slot="action" slot-scope="text,record">
<k-table-btn :btnArr="btnArr" :record="record" @btnClick="btnClick" />
</span>
js:
// 表格操作按钮参数配置
btnArr: record => {
return [
{
code: 'DataDictionary_settingItems',
flag: 'record.validStatus===1',
name: '配置数据项',
funcName: 'settingData',
funcArgs: [record]
},
{
code: 'DataDictionary_edit',
flag: 'true',
name: '编辑',
funcName: 'editor',
funcArgs: [record]
},
{
code: 'DataDictionary_del',
flag: 'true',
name: '删除',
funcName: 'delet',
funcArgs: [record]
}
]
},
// 触发表格操作按钮
btnClick(funcName, arr) {
this[funcName](...arr) // 触发对应的方法
},
总结:通过获取当前账号的全部权限code,和对应的具体的code作比较
2、面包屑导航/:id丢失问题
难点:面包屑导航二级三级,二级携带/:id丢失不存在,解决。三级跳到二级,此时三级路由中如果有二级的id,可以在item.redirect('''''''''/:id)的冒号之后拼接上对应的id(id从当前页面路由中获取);也可以存在localStroage中
if (redirect) {
// 是否携带参数(进对/:key有效,页面路由携带query还是会丢失,暂时无解决方法)
const startPos = redirect.indexOf(':')
if (startPos !== -1) {
const key = redirect.substring(startPos + 1,)
redirect = redirect.replace(':' + key, this.$route.params[key])
}
this.$router.push(redirect)
return
}
3、key和keep-alive 路由跳转同路由但参数不同是页面刷新问题
// keep-alive 组件缓存
// key 组件key不同会让组件完整触发生命周期钩子(key不同,会强制替换元素而不是复用。会复用元素)
// key不会影响keep-alive
<div id="app">
<keep-alive :include="cachedViews">
<router-view :key="key" />
</keep-alive>
</div>
computed: {
key() {
return this.$route.name ? this.$router.name + +new Date() : this.$route + +new Date()
}