持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第22天,点击查看活动详情
1.Tabs 标签页显示隐藏
1.1 项目描述
今天接到一个需求,新增产品开通状况,有套餐的显示,没有套餐隐藏。给我的第一个感觉就是判断后端后端返回的数据,如果数据为空,也就是数组的长度为0的时候不显示,这样就可以了。
1.2代码
<el-tab-pane label="产品开通状况" v-if="this.productData.length!==0" name="productsState">
<products-state :id="id"></products-state>
</el-tab-pane>
data(){
return{
productData:[],
}
}
methods:{
getOpenList() {
let param = this.$route.query
ProductService.openList({businessId: param.id}).then((res) => {
this.productData = res.data;
});
},
}
这样固然可以解决,但是又重复请求了接口,增加了不必要的消耗,应该还有其他更好的方案。
1.3代码优化
这里更改了v-if的判断,新增了showTab事件,通过showTab的ture还是false进行判断,然后传到v-if里面做判断显示还是隐藏。
<el-tab-pane label="产品开通状况" v-if="showProductData" name="productsState">
<products-state @showTab="getproducts" :id="id"></products-state>
</el-tab-pane>
data () {
return {
showProductData:true,
}
},
getproducts(e){
this.showProductData = e //这里将获取到的true/false传给showProductData
},
然后在子组件的接口里面做判断,最后还是利用数组的长度进行判断。
【注意】如果子组件内容中包含一些搜索之类的需求,最好不要用这个优化方案,有bug,这里不在展示。这种情况下推荐第一种方案。
methods: {
getOpenList() {
this.query.businessId = this.$route.query.id
this.loading.list = true;
ProductService.openList(this.query).then((res) => {
this.tableData = res.data;
this.page = res.page;
//这里是关键
if (res.data.length > 0) {
this.$emit('showTab', true)
} else {
this.$emit('showTab', false)
}
this.loading.list = false;
});
},
}
1.4 效果
2. v-permission权限控制
背景:在一些后台管理系统,我们可能需要根据用户角色进行一些操作权限的判断,很多时候我们都是粗暴地给一个元素添加
v-if / v-show来进行显示隐藏,但如果判断条件繁琐且多个地方需要判断,这种方式的代码不仅不优雅而且冗余。针对这种情况,我们可以通过全局自定义指令来处理。
需求:自定义一个权限指令,对需要权限判断的 Dom 进行显示隐藏。
2.1 新建一个文件夹directive
里面包含index.js和permission.js文件,基本上就是固定模板,直接拿来用即可
文件index.js 将permission转为install
import permission from './permission'
const install = function (Vue) {
Vue.directive('permission', permission)
}
if (window.Vue) {
window['permission'] = permission
Vue.use(install); // eslint-disable-line
}
permission.install = install
export default permission
文件permission.js,这里的内容不太一样,但大差不差,灵活运用
//下面会带上封装代码
import LoginAdminUtil from '@/utils/loginAdminUtil'
export default {
inserted (el, binding, vnode) {
const { value } = binding
if (value && value instanceof Array && value.length > 0) {
const hasPermission = LoginAdminUtil.validatePermission(value)
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`使用方式: v-permission="['admin','editor']"`)
}
}
}
loginAdminUtil.js
let LoginAdminUtil = {
save (loginAdmin) {
console.log('token', loginAdmin.token)
if (loginAdmin.token) {
localStorage.setItem('token', loginAdmin.token)
}
if (loginAdmin.tokenSecret) {
localStorage.setItem('tokenSecret', loginAdmin.tokenSecret)
}
console.log(loginAdmin)
let loginAdminStore = {
id: loginAdmin.id,
remoteAddr: loginAdmin.remoteAddr,
remoteAddrHash: md5(loginAdmin.remoteAddr),
realName: loginAdmin.realName,
superAdmin: loginAdmin.superAdmin,
permissions: loginAdmin.permissions
}
let loginAdminStoreStr = Base64.encode(JSON.stringify(loginAdminStore))
localStorage.setItem('loginAdmin', loginAdminStoreStr)
},
validatePermission (permissionCode) {
if (!LoginAdminUtil._loginAdmin) {
LoginAdminUtil._loginAdmin = LoginAdminUtil.get()
}
let loginAdmin = LoginAdminUtil._loginAdmin
// console.log('loginAdmin', loginAdmin)
if (loginAdmin.superAdmin) {
return true
}
// console.log('loginAdmin.permissions', loginAdmin.permissions)
if (loginAdmin.permissions) {
const hasPermission = loginAdmin.permissions.some(role => {
return permissionCode.includes(role)
})
return hasPermission
} else {
return false
}
},
_loginAdmin: undefined
}
export default LoginAdminUtil
2.2 在main.js中用use方法使用permission
import permission from './directive/Permission'
Vue.use(permission)
2.3在模板中使用v-permission
<!-- 普通销售看不到销售总览 -->
<el-tab-pane label="销售总览" name="salesall"
v-permission="['tydata-sell-stat-overview']" >
<FinanceSalesall></FinanceSalesall>
</el-tab-pane>
其中tydata-sell-stat-overview是后端给的code,通过这个code来控制权限。