6
头图
This article is a reprint
Author: primary school student study
Link: https://juejin.cn/post/70491969677770980389

foreword

Pinia.js is a new generation of state manager, developed by members of the Vue.js team, so it is also considered to be the next generation of Vuex, namely Vuex5.x, and is also highly respected for use in Vue3.0 projects.

Pinia.js has the following features:

  • full typescript support;
  • Light enough, the compressed volume is only 1.6kb;
  • Remove mutations, only state, getters, actions (this is my favorite feature);
  • actions support synchronous and asynchronous;
  • There is no module nesting, only the concept of store, which can be used freely between stores and better code division;
  • There is no need to manually add the store, the store will be added automatically once it is created;

Install

npm install pinia --save
复制代码

Create Store

Create a new src/store directory and create index.ts under it, export the store

// src/store/index.ts

import { createPinia } from 'pinia'

const store = createPinia()

export default store
复制代码

Imported and used in main.ts.

// src/main.ts

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'

const app = createApp(App)
app.use(store)
复制代码

State

Define State

Create a user.ts under src/store

//src/store/user.ts

import { defineStore } from 'pinia'

export const useUserStore = defineStore({
  id: 'user',
  state: () => {
    return {
      name: '张三'
    }
  }
})

复制代码

get state

<template>
  <div>{{ userStore.name }}</div>
</template>

<script lang="ts" setup>
import { useUserStore } from '@/store/user'

const userStore = useUserStore()
</script>
复制代码

It can also be obtained in combination with computed.

const name = computed(() => userStore.name)
复制代码

State can also use destructuring, but using destructuring will make it unresponsive. In this case, you can use pinia's storeToRefs .

import { storeToRefs } from 'pinia'
const { name } = storeToRefs(userStore)
复制代码

modify state

You can modify the state directly as follows

userStore.name = '李四'
复制代码

But it is generally not recommended to do this. It is recommended to modify the state through actions, which can be accessed directly through this.

export const useUserStore = defineStore({
  id: 'user',
  state: () => {
    return {
      name: '张三'
    }
  },
  actions() {
    updateName(name) {
      this.name = name
    }
  }
})
复制代码
<script lang="ts" setup>
import { useUserStore } from '@/store/user'

const userStore = useUserStore()
userStore.updateName('李四')
</script>
复制代码

Getters

export const useUserStore = defineStore({
 id: 'user',
 state: () => {
   return {
     name: '张三'
   }
 },
 getters: {
   fullName: (state) => {
     return state.name + '丰'
   }
 }
})
复制代码
userStore.fullName // 张三丰
复制代码

Actions

asynchronous action

Action can support async/await syntax like writing a simple function, allowing you to cope with asynchronous processing scenarios happily.

export const useUserStore = defineStore({
  id: 'user',
  actions() {
    async login(account, pwd) {
      const { data } = await api.login(account, pwd)
      return data
    }
  }
})
复制代码

call each other between actions

The mutual calls between actions can be accessed directly with this.

 export const useUserStore = defineStore({
  id: 'user',
  actions() {
    async login(account, pwd) {
      const { data } = await api.login(account, pwd)
      this.setData(data) // 调用另一个 action 的方法
      return data
    },
    setData(data) {
      console.log(data)
    }
  }
})
复制代码

It is also relatively simple to call the actions in other stores in the action. After the corresponding store is introduced, the method of its action can be used.

// src/store/user.ts

import { useAppStore } from './app'
export const useUserStore = defineStore({
  id: 'user',
  actions() {
    async login(account, pwd) {
      const { data } = await api.login(account, pwd)
      const appStore = useAppStore()
      appStore.setData(data) // 调用 app store 里的 action 方法
      return data
    }
  }
})
复制代码
// src/store/app.ts

export const useAppStore = defineStore({
  id: 'app',
  actions() {
    setData(data) {
      console.log(data)
    }
  }
})
复制代码

data persistence

The plugin pinia-plugin-persist can assist in implementing data persistence.

Install

npm i pinia-plugin-persist --save
复制代码

use

// src/store/index.ts

import { createPinia } from 'pinia'
import piniaPluginPersist from 'pinia-plugin-persist'

const store = createPinia()
store.use(piniaPluginPersist)

export default store
复制代码

Then open persist in the corresponding store.

export const useUserStore = defineStore({
  id: 'user',

  state: () => {
    return {
      name: '张三'
    }
  },
  
  // 开启数据缓存
  persist: {
    enabled: true
  }
})
复制代码

image.png

The data is stored in sessionStorage by default, and the id of the store is used as the key.

custom key

You can also customize the key value in strategies and change the storage location from sessionStorage to localStorage.

persist: {
  enabled: true,
  strategies: [
    {
      key: 'my_user',
      storage: localStorage,
    }
  ]
}
复制代码

image.png

Persist part of the state

By default, all states will be cached. You can specify the fields to be persisted through paths, and others will not be persisted.

state: () => {
  return {
    name: '张三',
    age: 18,
    gender: '男'
  }  
},

persist: {
  enabled: true,
  strategies: [
    {
      storage: localStorage,
      paths: ['name', 'age']
    }
  ]
}
复制代码

Above we only persist name and age and change them to localStorage, while gender will not be persisted. If its state is sent to change, it will be lost when the page is refreshed, and it will return to the initial state, while name and age will not .

grateful

This sharing is over here. Thank you for reading. If this article is helpful to you, don't forget to give a thumbs up ❤️.

If there are any mistakes or deficiencies in this article, please correct me in the comment area!

Epilogue

I'm Lin Sanxin, an enthusiastic front-end rookie programmer. If you are motivated, like the front-end, and want to learn the front-end, then we can make friends and fish together haha, touch the fish group, add me, please note [Si No]

image.png


Sunshine_Lin
2.1k 声望7.1k 粉丝