S.W. Tsai
S.W. Tsai

Reputation: 35

How to use @casl/vue with pinia

I'm currently using @casl/ability with Vue 3 but I can't figure out how to make it work with Pinia.

Here's what my app.js looks like:

import { createApp } from "vue"
const app = createApp({})

// pinia
import pinia from "./store"
app.use(pinia)

// casl
import { abilitiesPlugin } from "@casl/vue"
import ability from "./cacl/ability"
app.use(abilitiesPlugin, ability, {
    useGlobalProperties: true
})

// ...

app.mount('#app')

And here's what my ability.js looks like:

import { defineAbility } from "@casl/ability"
import { useMainStore } from "../store/main"

const ability = defineAbility((can, cannot) => {
    const store = useMainStore()
    if (store.user.role === "admin") {
        can("read", "Post")
    }
    // ...
})

export default ability

And I'm getting this error: enter image description here

I've checked Pinia's documentation about Using a store outside of a component but I'm not quite sure what I am doing wrong here? (P.S. Pinia is working as expected for the rest of my project. I'm just not sure how to make it work here.)

Upvotes: 0

Views: 588

Answers (1)

Nekudotayim
Nekudotayim

Reputation: 181

maybe you better define rules in pinia. To use ability there you have to make it available inside the store (similar to vue-router):

main.js:

import { abilitiesPlugin } from "@casl/vue";
import { createMongoAbility } from "@casl/ability";

const ability = createMongoAbility();
app.use(abilitiesPlugin, ability);
pinia.use(({ store }) => {
  store.ability = markRaw(ability);
});

In store.js you are able to access ability now like this:

actions: {
  initCasl() {
    const builder = new AbilityBuilder(this.ability);
    if (this.user.role === "admin") {
      builder.can("read", "Post")
    }
    this.ability.update(builder.rules);
  }
}

Upvotes: 1

Related Questions