成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

可愛簡(jiǎn)約又輕量的Pinia,你確定不用它嗎?

開發(fā) 前端
Pinia.js是由Vue.js團(tuán)隊(duì)核心成員開發(fā)的新一代狀態(tài)管理器,使用Composition Api進(jìn)行重新設(shè)計(jì)的,也被視為下一代Vuex。Pinia是一個(gè)Vue的狀態(tài)管理庫(kù)。

1 寫在前面

Pinia.js是由Vue.js團(tuán)隊(duì)核心成員開發(fā)的新一代狀態(tài)管理器,使用Composition Api進(jìn)行重新設(shè)計(jì)的,也被視為下一代Vuex。Pinia是一個(gè)Vue的狀態(tài)管理庫(kù),允許跨組件、跨頁(yè)面進(jìn)行全局共享狀態(tài),也由于其設(shè)計(jì)的簡(jiǎn)潔性、和對(duì)typescript的良好支持,取代Vuex指日可待。

或許,你在想在vue3中Composition API完全可以使用響應(yīng)式變量進(jìn)行全局共享狀態(tài),為什么還需要Pinia呢?其實(shí)你忽略的一點(diǎn),你這樣做在單頁(yè)面進(jìn)行應(yīng)用是完全可以的,但是如果頁(yè)面時(shí)服務(wù)端進(jìn)行渲染呈現(xiàn)的,那么就會(huì)出現(xiàn)安全漏洞。

Pinia的優(yōu)點(diǎn)有:

  • 完全支持Typescript,不需要進(jìn)行復(fù)雜的配置
  • 移除了“天下苦秦久矣”的mutations,不需要再區(qū)分同步異步去使用不同的方法,actions同時(shí)支持同步和異步,這樣形成了state、getters、actions三劍客格局
  • 支持服務(wù)端渲染
  • 不再需要套娃??了,沒有模塊嵌套,只有簡(jiǎn)簡(jiǎn)單單可以自由使用的store概念,形成了更好的代碼分割體驗(yàn)
  • 相比于Vuex更加輕量的設(shè)計(jì),壓縮代碼打包的體積

總而言之,Pinia不僅可愛,還簡(jiǎn)單輕量易上手。

2 開始使用

安裝Pinia

$ yarn add pinia
$ npm i pinia
$ pnpm i pinia

創(chuàng)建Store

根據(jù)Pinia官方給的格式建議,我們可以在src目錄下創(chuàng)建store目錄,再在其下創(chuàng)建index.ts文件作為store的全局配置文件,并導(dǎo)出store,方便全局掛載。


//src/store/index.ts
import {App} from "vue"
import {createPinia} from "pinia"

const store = createPinia()

export function setupStore(app:App<Element>){
app.use(store)
}

export {store}

在main.ts文件中進(jìn)行全局掛載store文件:

//src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import {setupStore} from "@stores/index"

const app = createApp(App);
// 掛載store
setupStore(app)
app.mount("#app")

簡(jiǎn)單示例

先定義一個(gè)counter的store狀態(tài)管理文件。

//src/store/modules/counter.ts
import {defineStore} from "pinia"

export const useCounterStore = defineStore("counter",{
state:()=>{
return {
count:0
}
},
actions:{
increment(){
this.count++
}
}
})

而后在vue文件進(jìn)行使用:

<template>
<div>count:{{counter.count}}</div>
</template>
<script lang="ts" setup>
import { useCounterStore } from '@store/modules/counter';

const counter = useCounterStore();
counter.count++
counter.$patch({count:counter.count})
counter.increment()
</script>

顯示結(jié)果

3State 數(shù)據(jù)狀態(tài)

定義state狀態(tài)

在使用倉(cāng)庫(kù)狀態(tài)數(shù)據(jù)前,你需要先使用defineStore()進(jìn)行定義一個(gè)倉(cāng)庫(kù),需要使用唯一的名字進(jìn)行命名。

//src/store/modules/counter.ts
import {defineStore} from "pinia"

export const useCounterStore = defineStore("counter",{
state:()=>{
return {
count:0
}
}
})

使用state狀態(tài)

在pinia中,state是使用函數(shù)進(jìn)行定義,并返回初始化數(shù)據(jù),這樣可以允許pinia作為服務(wù)端和客戶端進(jìn)行使用。

我們已經(jīng)定義了一個(gè)store倉(cāng)庫(kù),使用useStore()進(jìn)行獲取倉(cāng)庫(kù)state數(shù)據(jù)。

<template>
<div>count:{{count}}</div>
<div>doubleCount:{{doubleCount}}</div>
</template>
<script lang="ts" setup>
import { useCounterStore } from '@store/modules/counter';
const counter = useCounterStore();
//使用computed獲取響應(yīng)式數(shù)據(jù)
const doubleCount = computed(()=>counter.count*2);

const {count} = counter;
</script>

需要注意的是,在導(dǎo)入store使用state狀態(tài)時(shí),直接進(jìn)行解構(gòu)會(huì)使得變量失去響應(yīng)式。上面的數(shù)據(jù)中,count變量是失去了響應(yīng)式的,它的值一直恒定不變。對(duì)此,應(yīng)該像composition API使用props一樣,從pinia中導(dǎo)出storeToRefs進(jìn)行獲取響應(yīng)式數(shù)據(jù)。

const counter = useCounterStore();
const {count} = storeToRefs(counter)

對(duì)此,count現(xiàn)在轉(zhuǎn)為響應(yīng)式的數(shù)據(jù)了,這樣將會(huì)把store中的state變量成了響應(yīng)式,storeToRefs將會(huì)自動(dòng)跳過所有的actions和不需要進(jìn)行響應(yīng)式處理的屬性。

修改state狀態(tài)

通常,你可以通過store實(shí)例進(jìn)行直接獲取和修改state數(shù)據(jù),可以使用store.$reset()進(jìn)行重置state的數(shù)據(jù)回復(fù)到初始值。

import { useCounterStore } from '@stores/modules/counter';
const counter = useCounterStore();
counter.count++;

當(dāng)然,你還可以通過使用pinia的內(nèi)置API即$patch()進(jìn)行更新,它允許你在同一時(shí)間進(jìn)行多個(gè)數(shù)據(jù)的改變。$patch()允許你去組合多個(gè)改變的值,可以像數(shù)組進(jìn)行增刪改查。

import { useTodosStore } from "@stores/modules/todos";
const todosStore = useTodosStore()
todosStore.$patch(state=>{
state.todos.push({
name:"yichuan",
age:18
})
state.isTrue = true
})

$patch()允許你去組合多個(gè)改變的值,可以像數(shù)組進(jìn)行增刪改查。

替換state的值,可以通過設(shè)置$state的值進(jìn)行替換store中的state值。

store.$state = {counter:666, name:"onechuan"}

當(dāng)然也可以通過pinia的實(shí)例去改變整個(gè)state的值。

pinia.state.value= {}

但是,一般不建議直接修改state的值,Pinia中建議使用actions方法去修改和管理state的值。

監(jiān)聽state狀態(tài)變化

訂閱state的值:你可以通過store的$subscribe()方法去觀察state的改變,類似于subscribe方法。與常規(guī)watch()相比,使用$subscribe()的優(yōu)勢(shì)在于,在補(bǔ)丁發(fā)布后,訂閱只會(huì)觸發(fā)一次。

numerStore.$subscribe((mutation,state)=>{
mutation.counter
mutation.name
mutation.isAdmin
localStorage.setItem("numer",JSON.stringify(state))
})

默認(rèn)情況下,狀態(tài)訂閱被綁定到添加它們的組件上(如果存儲(chǔ)在組件的setup()中)。這就以為著當(dāng)組件被卸載的時(shí)候,將自動(dòng)移除。如果你想再組件被移除后繼續(xù)保持它們,可以通過設(shè)置{detached:true}作為第二個(gè)參數(shù)來從當(dāng)前組件中分離狀態(tài)訂閱。

const someStore = useSomeStore()
someStore.$subscribe(callback, { detached: true })

4Getters

getters與store狀態(tài)的computed的值完全相同,可以通過defineStore()中的getters屬性來定義,它們通過接收state作為箭頭函數(shù)的第一個(gè)參數(shù)。

export const useStore = defineStore('counter', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})

絕大多數(shù)情況,getters將只依賴于state,然而,它們也有可能需要去使用其它的getters。因此,在定義一個(gè)普通函數(shù)時(shí),我們可以通過這個(gè)函數(shù)訪問整個(gè)store實(shí)例,但需要定義返回類型的類型。由于ts中的已知的限制,并不影響使用箭頭函數(shù)定義的getter和不使用this。

import {defineStore} from "pinia"

export const useNumerStore = defineStore("numer",{
state:()=>({
counter:0,
name:"numer",
isAdmin:true
}),
getters:{
doubleCount(state){
return state.counter * 2
},
// 當(dāng)使用this的時(shí)候,必須準(zhǔn)確地設(shè)置返回值的類型
doublePlusOne():number{
return this.counter * 2 + 1
}
}
})

當(dāng)然你也可以通過計(jì)算屬性去獲取多個(gè)getters,需要通過this去獲取任意的其他getter。

export const useStore = defineStore("main",{
state:()=>({
counter:0
}),
getters:{
doubleCount:state=>state.counter * 2,
doubleCountPlusOne(){
return this.doubleCount + 1
}
}
})

getter只是在幕后的計(jì)算屬性,因此不能向其傳遞任何參數(shù)。但是你可以從getter返回一個(gè)函數(shù)來接收任何參數(shù)。

export const useStore = defineStore('main', {
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
},
})

在組件使用:

<div>用戶:{{getUserById(1)}}</div>

const numerStore = useNumerStore()
const {getUserById} = numerStore

注意,當(dāng)這樣做時(shí),getter不再被緩存,它們只是您調(diào)用的函數(shù)。不過,您可以在getter本身中緩存一些結(jié)果,這并不常見,但應(yīng)該會(huì)證明更高效.

export const useStore = defineStore('main', {
getters: {
getActiveUserById(state) {
const activeUsers = state.users.filter((user) => user.active)
return (userId) => activeUsers.find((user) => user.id === userId)
},
},
})

獲取其它store的getters,要使用另一個(gè)store getter,你可以直接在getter中使用它,其實(shí)和在vue文件中使用差別不大。

import { useOtherStore } from './other-store'

export const useStore = defineStore('main', {
state: () => ({
// ...
}),
getters: {
otherGetter(state) {
const otherStore = useOtherStore()
return state.localData + otherStore.data
},
},
})

5Actions

actions等價(jià)于組件中的方法,它們可以在defineStore()中進(jìn)行定義actions屬性,并且可以完美地去定義業(yè)務(wù)邏輯。

export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
actions: {
increment() {
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
},
})

在上面的代碼中,我們可以看到actions有點(diǎn)類似getters,但事實(shí)上是有所不同的。

  • 相同點(diǎn):actions和getters都可以全類型支持來訪問整個(gè)store實(shí)例。
  • 不同點(diǎn):actions操作可以是異步的,可以在其中等待任何api調(diào)用甚至其他操作。

注意,只要你得到了一個(gè)Promise,你使用的庫(kù)并不重要,你甚至可以使用本地的fetch函數(shù)(僅適用于瀏覽器):

import { mande } from 'mande'

const api = mande('/api/users')

export const useUsers = defineStore('users', {
state: () => ({
userData: null,
// ...
}),

actions: {
async registerUser(login, password) {
try {
this.userData = await api.post({ login, password })
showTooltip(`Welcome back ${this.userData.name}!`)
} catch (error) {
showTooltip(error)
// let the form component display the error
return error
}
},
},
})

同樣的,action也可以像state和getters進(jìn)行相互使用,action可以通過this直接訪問。

// src/store/user.ts
export const useUserStore = defineStore({
"user",
state: () => ({
userData: null
}),
actions:{
async login(account, pwd) {
const { data } = await api.login(account, pwd)
this.setData(data) // 調(diào)用另一個(gè) action 的方法
return data
},
setData(data) {
this.userData = data
}
}
})

也可以在action 里調(diào)用其他 store 里的 action,引入對(duì)應(yīng)的 store 后即可訪問其內(nèi)部的方法了。

// 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) // 調(diào)用 app store 里的 action 方法
return data
}
}
})
// src/store/app.ts
export const useAppStore = defineStore({
"app",
state:()=>{
userData: null
},
actions: {
setData(data) {
this.userData = data
}
}
})

6 參考文章

《Pinia官方文檔》

《新一代狀態(tài)管理工具,Pinia.js 上手指南》

7 寫在最后

本篇文章是在閱讀文檔和相關(guān)文章進(jìn)行學(xué)習(xí)總結(jié)得來,是在公司進(jìn)行應(yīng)用生產(chǎn)前的實(shí)驗(yàn),對(duì)于能力強(qiáng)的大佬應(yīng)該是小意思,從vuex過渡可以直接上手。Pinia是很好的狀態(tài)管理,簡(jiǎn)潔輕量易上手。在進(jìn)行總結(jié)文章的時(shí)候,也做了一些代碼實(shí)踐,但是不免會(huì)出現(xiàn)一些紕漏。

責(zé)任編輯:姜華 來源: 前端萬(wàn)有引力
相關(guān)推薦

2020-05-25 19:44:58

LubuntuLubuntu 20.

2021-06-08 11:15:10

Redis數(shù)據(jù)庫(kù)命令

2018-04-17 11:47:06

if代碼參數(shù)

2025-06-10 08:10:00

VLANIP網(wǎng)絡(luò)

2023-06-27 08:41:35

DapperSQL語(yǔ)句

2021-07-16 22:49:50

PiniaVuex替代品

2021-01-08 09:44:23

Faceboo隱私數(shù)據(jù)安全

2020-10-16 09:40:18

順序Spring AOPHTTP

2022-04-15 14:31:02

鴻蒙操作系統(tǒng)

2024-01-08 08:23:08

OpenCV機(jī)器學(xué)習(xí)計(jì)算機(jī)視覺

2020-08-25 18:52:22

人工智能機(jī)器人技術(shù)

2023-11-23 10:21:37

2018-03-28 14:37:43

商務(wù)辦公

2024-04-19 13:17:40

PostgreSQLSQL數(shù)據(jù)庫(kù)

2022-02-08 11:45:03

PiniaVuex前端

2012-03-01 11:20:45

2023-02-27 09:03:23

JavaCAS

2021-08-26 05:27:57

Swift 監(jiān)聽系統(tǒng)泛型

2024-03-14 11:06:37

JavaScript引擎探索

2021-03-11 15:13:26

Python開發(fā)編輯器
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 国产福利在线视频 | 草草草久久久 | 91久久夜色精品国产网站 | 国产高清视频在线观看 | 久久999| 亚洲欧美精品 | 久久小视频 | 欧美a级成人淫片免费看 | 日本aa毛片a级毛片免费观看 | 欧洲一区二区视频 | 午夜网址 | 欧美www在线 | 久久精品国产亚洲一区二区 | 久久亚洲视频网 | 亚洲国产视频一区 | 激情 亚洲 | 一区二区三区四区视频 | 亚洲成人精品国产 | 日韩av看片 | 亚洲精品欧美 | 欧美一区二区三区四区视频 | av av在线 | 精品一区二区三区免费视频 | 成人欧美一区二区三区白人 | 久草热8精品视频在线观看 午夜伦4480yy私人影院 | 丁香婷婷在线视频 | 亚洲精品99999 | 久久久久久久亚洲精品 | 视频三区 | 亚洲一区精品在线 | 99re在线视频 | 在线日韩欧美 | 国产精品久久久久aaaa | 亚洲一区二区成人 | 免费视频一区二区 | 国产精品久久网 | 欧美日韩1区2区3区 欧美久久一区 | 日韩福利 | 久久久成人网 | 看片一区| 国产精品免费一区二区 |