JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.3/vue.min.js"></script>
<div id="app">
<ul>
<li v-for="post in posts">{{ post.title }} <a href="#" v-if="$gate.allow('update', 'post', post)">Edit</a></li>
</ul>
<a href="#" v-if="$gate.allow('create', 'post')">Create a new post</a>
</div>
JavaScript
class PostPolicy
{
static create(user)
{
return user.role === 'editor';
}
static view(user, post)
{
return true;
}
static delete(user, post)
{
return user.id === post.user_id;
}
static update(user, post)
{
return user.id === post.user_id;
}
}
class Gate
{
constructor(user)
{
this.user = user;
this.policies = {
post: PostPolicy
};
}
before()
{
return this.user.role === 'owner';
}
allow(action, type, model = null)
{
if (this.before()) {
return true;
}
return this.policies[type][action](this.user, model);
}
deny(action, type, model = null)
{
return ! this.allow(action, type, model);
}
}
let user = {name: 'Gege', role: 'editor', id: 1};
Vue.prototype.$gate = new Gate(user);
new Vue({
el: '#app',
data() {
return {
posts: [
{id: 1, title: 'Post 1', user_id: 1},
{id: 2, title: 'Post 2', user_id: 2},
{id: 3, title: 'Post 3', user_id: 1},
{id: 4, title: 'Post 4', user_id: 1},
{id: 5, title: 'Post 5', user_id: 2},
]
}
}
})