在涉及到權限控制的應用中,常常遇到這樣的需求:根據用戶角色判斷某個組件(例如某個刪除按鈕、標籤頁)是否須要顯示。最直接的解決方法就是利用v-if
或者v-show
對這種組件挨個判斷。vue
<template>
<div>
<button v-if='user.type === "admin"'>管理員纔可見的按鈕</button>
<button v-if='user.type === "user"'>普通用戶纔可見的按鈕</button>
</div>
</template>
<script>
import { useState } from 'vuex';
export default {
computed: {
...useState(['user']) //存儲的user信息
}
}
</script>
複製代碼
編寫已封裝好業務邏輯的組件,好比組件ButtonForAdmin
:vuex
<template>
<button v-if='user.type === "admin"'>管理員纔可見的按鈕</button>
</template>
<script>
import { useState } from 'vuex';
export default {
computed: {
...useState(['user']) //存儲的user信息
}
}
</script>
複製代碼
這種方法能夠必定程度上減輕代碼重複度,缺點是當項目中每有一個不一樣的組件須要實現該需求時都要封裝一遍。bash
爲了讓每一個不一樣的組件均可以複用一個邏輯,能夠使用slot
機制並使用傳參的方式統一判斷用戶角色:ui
<template>
<div>
<slot v-if='roles.indexOf(user.type) !== -1'></slot>
</div>
</template>
<script>
import { useState } from 'vuex';
export default {
props: {
roles: {
type: Array, //在哪些用戶角色時可見
default() {
return [];
}
}
},
computed: {
...useState(['user']) //存儲的user信息
}
}
</script>
複製代碼
這個方法能夠經過slot
機制對任何傳入組件並經過傳入的參數統一判斷是否須要顯示,但此方法依然優缺點:因爲slot
不能做爲組件根元素,使用該組件會比原來多增長一個DOM
元素,並影響原來的樣式。this
<script>
import { useState } from 'vuex';
export default {、
name: 'role-limit',
props: {
roles: {
type: Array, //在哪些用戶角色時可見
default() {
return [];
}
}
},
computed: {
...useState(['user']) //存儲的user信息
},
render() {
const slot = this.$slots.default;
if (roles.indexOf(this.user.type) !== -1) {
return slot;
}
return null; //不渲染內容
}
}
</script>
複製代碼
使用Vue.Component()註冊爲全局組件後,可在項目中隨意經過用戶角色控制某個組件的顯示:spa
<template>
<div>
<role-limit :roles='["admin"]'>
<button>管理員纔可見的按鈕</button>
</role-limit>
<role-limit :roles='["user"]'>
<button>普通用戶纔可見的按鈕</button>
</role-limit>
</div>
</template>
複製代碼