vue3笔记十七(Pinia)
生活随笔
收集整理的這篇文章主要介紹了
vue3笔记十七(Pinia)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1、pinia簡介
全局狀態管理工具
Pinia.js 有如下特點:
- 完整的 ts 的支持;
- 足夠輕量,壓縮后的體積只有1kb左右;
- 去除 mutations,只有 state,getters,actions;
- actions 支持同步和異步;
- 代碼扁平化沒有模塊嵌套,只有 store 的概念,store 之間可以自由使用,每一個store都是獨立的
- 無需手動添加 store,store 一旦創建便會自動添加;
- 支持Vue3 和 Vue2
官方文檔Pinia
git 地址 https://github.com/vuejs/pinia
2、安裝及注冊
2.1、安裝
yarn add pinia 或 npm install pinia2.2、注冊
// main.ts注冊 import { createApp } from 'vue' import App from './App.vue' import { createPinia } from 'pinia'const app = createApp(App) const store = createPinia()app.use(store) app.mount('#app')3、初始化Store倉庫
1、src下新建store文件夾
2、新建一個[name].ts文件
3、在新建的[name].ts文件下定義倉庫
4、新建一個store-namespace/index.ts文件用于名稱管理
4、pinia中state值修改的五種方式
<template><div><h1>pinia-----{{User.name}}------{{User.age}}</h1><button @click="change">change</button></div> </template><script setup lang="ts"> import { useUserInfo } from '@/store/User.ts'const User = useUserInfo()// 方式一:可以直接修改值,不同于vuex // const change = () => { // User.name = '哈哈' // User.age++ // }// 方式二:$patch方法對象形式修改 // const change = () => { // User.$patch({ // name: '李四', // age: 100 // }) // }// 方式三:$patch方法函數形式修改,內部可自定義邏輯修改 // const change = () => { // User.$patch((state) => { // state.name = '王五' // state.age++ // }) // }// 方式四:$state方法設置新對象替換整個store,必須修改整個state對象的所有屬性 // (但本人發現修改單個屬性也可以,并無其他影響) // const change = () => { // User.$state = { // name: '趙六', // age: 999, // } // }// 方式五:通過actions修改state值 const change = () => {User.setData() } </script>5、解構pinia中state值
<template><div><h4>原始值-----{{User.name}}------{{User.age}}</h4><h4>解構值-----{{name}} ----- {{age}}</h4><button @click="change">change</button></div> </template><script setup lang="ts"> import { useUserInfo } from '../store' import { storeToRefs } from 'pinia'const User = useUserInfo()// 1、pinia值直接解構,失去響應式 // const { name, age } = User// 2、使用storeToRefs方法解構數據為響應式 const { name, age } = storeToRefs(User)const change = () => {User.age++ // 或 age.value++ }</script> // storeToRefs源碼 // storeToRefs同toRefs一樣,給內部數據包裹一層toReffunction storeToRefs(store) {// See https://github.com/vuejs/pinia/issues/852// It's easier to just use toRefs() even if it includes more stuffif (isVue2) {// @ts-expect-error: toRefs include methods and othersreturn toRefs(store);}else {// 首先將store響應式對象轉化為普通對象,防止下面的toRef重復代理store = toRaw(store);// 最終return 這個 refsconst refs = {};for (const key in store) {const value = store[key];// 判斷屬性值是否是ref或reactive響應式對象,如果是拷貝到refs中,將其原始對象包裹toRef變為響應式對象if (isRef(value) || isReactive(value)) {// @ts-expect-error: the key is state or getterrefs[key] =// ---toRef(store, key);}}return refs;} }store轉化為普通對象后的屬性展示
6、actions、getters使用
actions既支持異步也支持同步方法
import { defineStore } from 'pinia' import { Names } from './store-namespace'type Result = {name: string,age: number }const Login = ():Promise<Result> => {return new Promise((resolve) => {setTimeout(() => {resolve({name: '王翠花',age: 19})}, 3000)}) }export const useUserInfo = defineStore(Names.User, {state: () => ({num: 100,user: <Result>{}}),actions: {// 異步方法async getLogin() {let res = await Login()this.user = resconsole.log(res)// actions中相互調用this.setNum(res.age)},// 同步方法setNum(val: number) {this.num = val},} })getters使用
import { defineStore } from 'pinia' import { Names } from './store-namespace'export const useUserInfo = defineStore(Names.User, {state: () => ({num: 100,}),getters: {// 寫法1 箭頭函數不能使用this,this指向已經變成undefined,修改請用statedoubleNum: (state) => state.num * 2,// 寫法2 普通函數形式中可使用this,但ts無法進行正確的類型推導,需定義返回值類型tripleNum(): number {return this.num * 3},// getters中相互調用numStr1(): string {return this.doubleNum + 'str'},}, })7、pinia API
$reset、$subscribe、$onAction <template><div><h4>actions-----{{User.info}} ---- {{User.num}}</h4><button @click="change">change</button><button @click="reset">reset</button><button @click="actionChange">actionChange</button></div> </template><script setup lang="ts"> import { useUserInfo } from '../store'const User = useUserInfo()const change = () => {User.info.name = '張三'User.info.age = 999User.num++ }const reset = () => {// $reset重置store到初始狀態,將state所有值重置回初始狀態User.$reset() }const actionChange = () => {User.setNum(789) }// 監聽state值的改變,只要state值改變都會走這個函數 User.$subscribe((args, state) => {console.log(args, state, 'state數據改變----') }, {// 組件銷毀后仍可監聽detached: true })// 當actions中函數被調用,觸發監聽 User.$onAction((args) => {console.log(args, 'actions調用--------------') }) </script>8、pinia 數據持久化插件
8.1、下載插件
npm i pinia-plugin-persist --save 或 yarn add pinia-plugin-persist8.2、在main.ts中引入
import { createApp } from 'vue' import App from './App.vue' import { createPinia } from 'pinia' // 持久化插件 import piniaPersist from 'pinia-plugin-persist' const store = createPinia() store.use(piniaPersist)const app = createApp(App) app.use(store) app.mount('#app')8.3、模塊中使用
import { defineStore } from 'pinia' import { Names } from './store-namespace'type Result = {name: string,age: number }export const useUserInfo = defineStore(Names.User, {state: () => ({info: <Result>{},num: 100,}),persist: {enabled: true, // 開啟存儲// strategies 設置存儲位置及存儲變量,不寫默認為sessionStorage中存儲所有數據strategies: [// storage 設置存儲到localStorage或sessionStorage中// paths 不寫則默認存儲所有數據,寫了只存儲指定變量數據(如下只對num做了數據持久化){storage: localStorage, paths: ['num']}]},getters: {},actions: {}, })原文鏈接:
https://xiaoman.blog.csdn.net/article/details/123338137
總結
以上是生活随笔為你收集整理的vue3笔记十七(Pinia)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python实现跨进程(跨py文件)通信
- 下一篇: 【LeetCode】螺旋矩阵旋转图像