我在 vue cli 项目中使用@casl/vue插件进行用户权限管理,如casl plugin author sample(vue-blog)的这个示例 repo 所示。这是我的代码
ability.js
export default (store) => {
const ability = store.getters.ability
ability.update(store.state.rules);
return store.subscribe((mutation) => {
switch (mutation.type) {
case 'ROOT_LOGIN_SUCCESS':
var formattedRules = [];
if (mutation.payload.permissions.length > 0) {
formattedRules = mutation.payload.permissions.map(perm => {
let formattedObj = {};
formattedObj.actions = perm.substr(0, perm.indexOf(' '));
formattedObj.subject = perm.substr(perm.indexOf(' ') + 1);
return formattedObj;
})
}
console.log(formattedRules)
ability.update(formattedRules);
break
case 'ROOT_LOGOUT_SUCCESS':
ability.update([{actions: 'read', subject: 'all'}])
break
}
})
}
我rules
从rest-api获取登录和格式化并将其保存为localStorage
casl/vue 格式{actions: 'someAction', subject: 'someSubject'}
。这是
storage.js
export default (options) => (store) => {
if (localStorage.state) {
const storedState = JSON.parse(localStorage.state)
store.replaceState(Object.assign(store.state, storedState))
}
return store.subscribe((mutation, state) => {
if (options.destroyOn && options.destroyOn.indexOf(mutation.type) !== -1) {
return localStorage.removeItem('state')
}
const newState = options.storedKeys.reduce((map, key) => {
map[key] = state[key]
return map
}, {});
localStorage.state = JSON.stringify(newState)
})
}
和store.js
/*
* FOR USER PERMISSIONS MANAGEMENT ON UI */
import {Ability} from '@casl/ability'
import abilityPlugin from "@/shared/store/ability"
import storage from "@/shared/store/storage";
...
export default new Vuex.Store({
plugins: [
storage({
storedKeys: ['token', 'rules'],
destroyOn: ['ROOT_LOGOUT_SUCCESS']
}),
abilityPlugin
],
...
mutations: {
ROOT_LOGIN_SUCCESS(state, data) {
let formattedRules = [];
if (data.permissions.length > 0) {
formattedRules = data.permissions.map(perm => {
let formattedObj = {};
formattedObj.actions = perm.substr(0, perm.indexOf(' '));
formattedObj.subject = perm.substr(perm.indexOf(' ') + 1);
return formattedObj;
})
}
state.rules = formattedRules;
state.token = data.token;
},
ROOT_LOGOUT_SUCCESS(state) {
state.rules = [];
},
},
...
getters: {
ability() {
return new Ability()
}
},
}
main.js
/*
* FOR USER PERMISSIONS MANAGEMENT ON UI */
import {abilitiesPlugin, Can} from '@casl/vue'
Vue.use(abilitiesPlugin, store.getters.ability)
Vue.component('Can', Can);
在 Vue 组件模板中,我像这样使用它
index.vue
<v-btn
v-if="$can('delete', 'department')"
color="error"
dark
@click="uiShowConfirm({content: 'Are you sure?',
callBack: deleteConfirmed})"
>
<v-icon class="mr-2">mdi-delete</v-icon>
Delete
</v-btn>