Search code examples
vue.jsvuexvue-composition-apipiniavue-options-api

Can you use Pinia in Composition API's <script setup> tags?


Background

I'm creating an App in Vue3 using Composition API. I decided to use <script setup> tags for all my components and views because I wanted to use the most up to date syntax for my app in Vue3's Composition API.

Confusion

However, when looking through the docs, I noticed that Pinia is designed to be used inside setup() inside of <script> tags? I thought the setup() function was a way to enable Composition API features inside an older Options API app?

I naturally assumed that Pinia would be designed to work natively within <script setup> as it is recommended as the state management tool for all new Vue3 projects. In the main Vue.js docs, they use <script setup> for their sample of Composition API.

Question

So I guess I have two parts to the questions:

  1. Why would they design Pinia to integrate only with Options API <script> instead of Composition API <script setup>?

  2. How do you use Pinia with <script setup> and is there documentation for this?

I could also be ignorant to something, but if anyone could offer some clarity to this I'd be grateful so I would not have to refactor all my components to Options API with a setup() function.


Solution

  • <script setup> is only a syntax sugar for Composition API with setup(). Anything that you can do with setup() can be done with <script setup>. <script setup> helps you write code almost like standard JavaScript, instead of having to follow the Vue-specific syntax.

    I'm not sure why you thought Pinia can only be integrated with Options API. In <script setup> you can use Pinia like the following:

    Your component.vue file:

    <script
      setup
      lang="ts">
      import {useStore} from './store'
      const store = useStore()
    </script>
    <template>
      <p>{{store.text}}</p>
    </template>
    

    Your store.ts file:

    import {defineStore} from 'pinia'
    export const useStore = defineStore('main', {
      state: () => (<{
        text : string
      }>{
        text: 'This is some text'
      })
    })