国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

我回了橙子建站的驗(yàn)證碼上海疫情最新情況

我回了橙子建站的驗(yàn)證碼,上海疫情最新情況,濟(jì)寧網(wǎng)站建設(shè)優(yōu)化,已有網(wǎng)站怎么做后臺VueX 簡介 Vue官方:狀態(tài)管理工具 狀態(tài)管理是什么 需要在多個組件中共享的狀態(tài)、且是響應(yīng)式的、一個變,全都改變。 例如一些全局要用的的狀態(tài)信息:用戶登錄狀態(tài)、用戶名稱、地理位置信息、購物車中商品、等等 這時(shí)候我們就需要這么一個工…

VueX 簡介

Vue官方:狀態(tài)管理工具

狀態(tài)管理是什么

需要在多個組件中共享的狀態(tài)、且是響應(yīng)式的、一個變,全都改變。

例如一些全局要用的的狀態(tài)信息:用戶登錄狀態(tài)、用戶名稱、地理位置信息、購物車中商品、等等

這時(shí)候我們就需要這么一個工具來進(jìn)行全局的狀態(tài)管理,Vuex就是這樣的一個工具。

單頁面的狀態(tài)管理

View–>Actions—>State

視圖層(view)觸發(fā)操作(action)更改狀態(tài)(state)響應(yīng)回視圖層(view)

多頁狀態(tài)管理

vuex store對象屬性介紹

vue3 中的 setup 在 beforecreate 和 created 前執(zhí)行,此時(shí) vue對象還未被創(chuàng)建,沒有了之前的this,所以此處我們需要用到另一種方法來獲取到 store 對象。

import { useStore } from 'vuex' // 引入useStore 方法
const store = useStore()  // 該方法用于返回store 實(shí)例
console.log(store)  // store 實(shí)例對象

1.?state

存放數(shù)據(jù)的地方

state: {
? count: 100,
? num: 10
},

可以在 state 中直接進(jìn)行數(shù)據(jù)變化的操作,但Vue不建議這么做。因?yàn)閷τ趘ue開發(fā)工具 devtools 來說,直接在state中進(jìn)行數(shù)據(jù)改變,devtools是跟蹤不到的。vuex中希望通過 action(進(jìn)行異步操作)或是 mutations(同步操作)來進(jìn)行數(shù)據(jù)改變的操作,這樣在 devtools 中才能直接觀察出數(shù)據(jù)的變化以及記錄,方便開發(fā)者調(diào)試。

另外,在vue3 中對state 中對象新增屬性或刪除時(shí),不再需要通過?vue.set()?, 或是?vue.delete()?來進(jìn)行對象的響應(yīng)式處理了,直接新增的對象屬性已經(jīng)具有響應(yīng)式

2.?mutations

vuex的store狀態(tài)更新的唯一方式:提交 mutation

同步操作可以直接在mutatuions中直接進(jìn)行

mutions 主要包含2部分:

  1. 字符串的事件類型 (type)

  2. 一個**回調(diào)函數(shù)(handler)**該回調(diào)函數(shù)的第一個參數(shù)是 state

    mutations: {
    // 傳入 state
    increment (state) {
    state.count++
    }
    }

template 中通過?$store.commit('方法名')?觸發(fā)

// 導(dǎo)入 useStore 函數(shù)
import { useStore } from 'vuex'
const store = useStore()
store.commit('increment')

mution 的參數(shù)與傳參方法

mution 接收參數(shù)直接寫在定義的方法里邊即可接受傳遞的參數(shù)

// ...state定義count
mutations: {sum (state, num) {state.count += num}
}

通過 commit 的payload 進(jìn)行參數(shù)傳遞

使用?store.commit('mution中函數(shù)名', '需要傳遞的參數(shù)' )?在commit里添加參數(shù)的方式進(jìn)行傳遞

<h2>{{this.$store.state.count}}</h2>
<button @click="add(10)">++</button>
...
<script setup>
// 獲取store實(shí)例,獲取方式看上邊獲取store實(shí)例方法
const add = (num) => {store.commit('sum', num)
}
</script>

mution 的提交風(fēng)格

前面提到了 mution 主要包含 type 和 回調(diào)函數(shù) 兩部分, 和通過commit payload的方式進(jìn)行參數(shù)傳遞(提交),下面我們可以

用這種方式進(jìn)行 mution 的提交

const add = (num) => {store.commit({type: 'sum',  // 類型就是mution中定義的方法名稱num})
}...
mutations: {sum (state, payload) {state.count += payload.num}
}

?3.?actions

異步操作在action中進(jìn)行,再傳遞到mutation

action基本使用如下:

action 中定義的方法默認(rèn)參數(shù)為**?context?上下文**, 可以理解為 store 對象

通過 context 上下文對象,拿到store,通過?commit?觸發(fā) mution 中的方法,以此來完成異步操作

...
mutations: {sum (state, num) {state.count += num}
},
actions: {// context 上下文對象,可以理解為storesum_actions (context, num) {setTimeout(() => {context.commit('sum', num)  // 通過context去觸發(fā)mutions中的sum}, 1000)}
},

在template 中通過dispatch?調(diào)用action 中定義的sum_action 方法

// ...template
store.dispatch('sum_actions', num)

通過 promise 實(shí)現(xiàn)異步操作完成,通知組件異步執(zhí)行成功或是失敗。

// ...
const addAction = (num) => {store.dispatch('sum_actions', {num}).then((res) => {console.log(res)}).catch((err) => {console.log(err)})
}

sun_action方法返回一個promise,當(dāng)累加的值大于30時(shí)不再累加,拋出錯誤。

 actions: {sum_actions (context, payload) {return new Promise((resolve, reject) => {setTimeout(() => {// 通過 context 上下文對象拿到 countif (context.state.count < 30) {context.commit('sum', payload.num)resolve('異步操作執(zhí)行成功')} else {reject(new Error('異步操作執(zhí)行錯誤'))}}, 1000)})}},

4.?getters

類似于組件的計(jì)算屬性

import { createStore } from 'vuex'export default createStore({state: {students: [{ name: 'mjy', age: '18'}, { name: 'cjy', age: '22'}, { name: 'ajy', age: '21'}]},getters: {more20stu (state) { return state.students.filter(item => item.age >= 20)}}
})

使用 通過$store.getters.方法名?進(jìn)行調(diào)用

//...template
<h2>{{$store.getters.more20stu}}</h2> // 展示出小于20歲的學(xué)生

getters 的入?yún)? getters 可以接收兩個參數(shù),一個是?state, 一個是自身的?getters?,并對自身存在的方法進(jìn)行調(diào)用。

getters: {more20stu (state, getters) { return getters.more20stu.length}
}

getters 的參數(shù)與傳參方法

上面是getters固定的兩個參數(shù),如果你想給getters傳遞參數(shù),讓其篩選大于 age 的人,可以這么做

返回一個 function 該 function 接受 Age,并處理

getters: {more20stu (state, getters) { return getters.more20stu.length},moreAgestu (state) {return function (Age) {return state.students.filter(item =>item.age >= Age)}}// 該寫法與上邊寫法相同但更簡潔,用到了ES6中的箭頭函數(shù),如想了解es6箭頭函數(shù)的寫法// 可以看這篇文章 https://blog.csdn.net/qq_45934504/article/details/123405813?spm=1001.2014.3001.5501moreAgestu_Es6: state => {return Age => {return state.students.filter(item => item.age >= Age)}}
}

使用

//...template
<h2>{{$store.getters.more20stu}}</h2> // 展示出小于20歲的學(xué)生
<h2>{{$store.getters.moreAgestu(18)}}</h2> // 通過參數(shù)傳遞, 展示出年齡小于18的學(xué)生

5.?modules

當(dāng)應(yīng)用變得復(fù)雜時(shí),state中管理的變量變多,store對象就有可能變得相當(dāng)臃腫。

為了解決這個問題,vuex允許我們將store分割成模塊化(modules),而每個模塊擁有著自己的state、mutation、action、getters等

在store文件中新建modules文件夾

在modules中可以創(chuàng)建單一的模塊,一個模塊處理一個模塊的功能

store/modules/user.js 處理用戶相關(guān)功能

store/modules/pay.js 處理支付相關(guān)功能

store/modules/cat.js 處理購物車相關(guān)功能

// user.js模塊
// 導(dǎo)出
export default {namespaced: true, // 為每個模塊添加一個前綴名,保證模塊命明不沖突 state: () => {},mutations: {},actions: {}
}

最終通過?store/index.js?中進(jìn)行引入

// store/index.js
import { createStore } from 'vuex'
import user from './modules/user.js'
import user from './modules/pay.js'
import user from './modules/cat.js'
export default createStore({modules: {user,pay,cat}
})

在template中模塊中的寫法和無模塊的寫法大同小異,帶上模塊的名稱即可

<h2>{{$store.state.user.count}}</h2>store.commit('user/sum', num) // 參數(shù)帶上模塊名稱
store.dispatch('user/sum_actions', sum)


?

一、使用vuex

vuex的安裝:

npm i vuex

vuex的配置,@/store/index.js:

import {createStore} from 'vuex'//導(dǎo)入createStore構(gòu)造函數(shù)
export default createStore({ state:{ //Vuex的狀態(tài),實(shí)際上就是存數(shù)據(jù)的地方person:{name:'jack',age:200}},getters:{ //提供獲取Vux狀態(tài)的方式, 注意在組件中調(diào)用時(shí)getPerson是以屬性的方式被訪問getPerson(state){return state.person}},mutations:{ //提供直接操作Vuex的方法,注意mutations里的方法中不能有任何異步操做ageGrow(state, value){//第一個參數(shù)state為Vuex狀態(tài);第二個參數(shù)為commit函數(shù)傳來的值state.person.age += value}},actions:{ //提供通過mutations方法來簡介操作Vuex的方法ageGrow(context, value){ //第一個參數(shù)context為上下文,提供一些方法;第二個參數(shù)為dispatch函數(shù)傳來的值context.commit('ageGrow', value)}}, 
})

在@/main.js中引入:

import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')

在組件中使用Vuex:

<template><h1>名字:{{person.name}}--年齡:{{person.age}}</h1><input type="text" v-model="value"><button @click="ageGrow(value)">增加年齡</button><!-- 在input框輸入一個數(shù)字,點(diǎn)擊按鈕,可以看到年齡發(fā)生變化,說明Vuex正常工作 -->
</template><script>import {useStore} from 'vuex' import {ref} from 'vue'export default {setup(){const store = useStore()    //獲取store對象let person = store.getters.getPerson    //從組件中獲取狀態(tài)(數(shù)據(jù))person 方式一// let person = store.state.person      //從組件中獲取狀態(tài)(數(shù)據(jù))person 方式二let value = ref('輸入年齡的增量')function ageGrow(ageGrowth){ageGrowth = parseInt(ageGrowth)if(isNaN(ageGrowth)){ageGrowth = 0}store.dispatch('ageGrow', ageGrowth)//通過dispatch來調(diào)用actions里的'ageGrow'方法,參數(shù)為ageGrowth//actions的方法又會通過commit來調(diào)用mutations里的方法,從而引起狀態(tài)(數(shù)據(jù))的變化//也可以在組件里跳過dispatch actions,直接store.commit}return {person, value,ageGrow}}}
</script>
<style></style>

小結(jié):安裝完vuex之后,首先要用creatRouter構(gòu)造函數(shù)創(chuàng)建一個router對象,并在main.js中引入這個對象。然后在組件中,通過userStore方法來獲取這個router對象,進(jìn)一步通過getter或者state可以得到Vuex狀態(tài)(數(shù)據(jù)),通過dispatch->actions->mutations->state的數(shù)據(jù)傳送方式可以操作和改變Vuex的狀態(tài)(數(shù)據(jù))

2. Module

Vuex官方原話:“由于使用單一狀態(tài)樹,應(yīng)用的所有狀態(tài)會集中到一個比較大的對象。當(dāng)應(yīng)用變得非常復(fù)雜時(shí),store 對象就有可能變得相當(dāng)臃腫?!?/p>

什么叫單一狀態(tài)樹呢,其實(shí)就是上文中的state對象。在Vuex的基本使用中,我們使用state對象來存儲Vuex的狀態(tài),state對象里面可以嵌套其他的對象,它是一個樹形的結(jié)構(gòu),而且這個state對象是唯一的,所有的狀態(tài)都要存儲在這一個對象里。因此,我們稱之為單一狀態(tài)樹。
這種單一狀態(tài)樹的弊端是顯而易見的,對于中大型項(xiàng)目來說,要托管給Vuex的狀態(tài)有很多,把這些海量的數(shù)據(jù)如果都塞到一個文件里面的一個對象里面,未免顯得過于臃腫,不管是開發(fā)起來還是維護(hù)起來都會有很多不變。
對此,官方給出了解決方案:
?

“為了解決以上問題,Vuex 允許我們將 store 分割成模塊(module)?。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進(jìn)行同樣方式的分割”

2.1 vuex中模塊化的基本使用

vuex的模塊化沒什么難理解的,就是把store給拆開,一個對象拆成多個對象,一個文件拆成多個文件,并且彼此可以擁有獨(dú)立的命名空間。
道理很簡單,所以直接看樣例:

文件結(jié)構(gòu)

├──src├── components│   └── Test.vue└── store├── index.js└── modules├── male.js└── female.js

index.js

import {createStore} from 'vuex'
import female from './modules/female'   //導(dǎo)入模塊
import male from './modules/male'       //導(dǎo)入模塊
export default createStore({ modules:{   //使用模塊female,male}
})

male.js

export default {namespaced:true,    //namespaced:true代表該模塊帶有獨(dú)立命名空間state:{             //否則,默認(rèn)是處于全局命名空間,就和非模塊化一樣personList:[{name:'張飛', id:'004'},{name:'武則天', id:'005'},{name:'秀吉', id:'006'},]},mutations:{addMutation(state, value){      //往personList中添加一個人state.personList.push(value)},removeMutaion(state, value){    //往personList中刪除一個人state.personList = state.personList.filter((el) => el.id != value.id)}},actions:{addAction(context, value){setTimeout(() => {context.commit('addMutation', value) // ->'male/addMutation'}, 1000);},removeAction(context, value){context.commit('removeMutaion', value)}},getters:{personList(state){return state.personList}}
}

female.js

export default {namespaced:true,    //namespaced:true代表該模塊帶有獨(dú)立命名空間state:{             //否則,默認(rèn)是處于全局命名空間,就和非模塊化一樣personList:[{name:'李白', id:'001'},{name:'孫尚香', id:'002'},{name:'大喬', id:'003'},]},mutations:{addMutation(state, value){      //往personList中添加一個人state.personList.push(value)},removeMutaion(state, value){    //往personList中刪除一個人state.personList = state.personList.filter((el) => el.id != value.id)}},actions:{addAction(context, value){setTimeout(() => {context.commit('addMutation', value) // ->'female/addMutation'}, 1000);},removeAction(context, value){context.commit('removeMutaion', value)}},getters:{personList(state){return state.personList}}
}

Test.vue

<template><h1>女人:</h1><li v-for="femalePerson in femalePersons" :key="femalePerson.id">{{femalePerson.name}}<button @click="addToMale(femalePerson)">添加到男人</button></li><h1>男人:</h1><li v-for="malePerson in malePersons" :key="malePerson.id">{{malePerson.name}}<button @click="addToFemale(malePerson)">添加到女人</button></li><!-- 有兩個列表,分布是男人和女人,通過點(diǎn)擊按鈕可以把列表中的某些項(xiàng)添加到另一個列表中 --><!-- 建議粘貼復(fù)制并運(yùn)行代碼,這樣更直觀 -->
</template><script>import { computed } from '@vue/runtime-core';import {useStore} from 'vuex'export default {setup(){let store = useStore()let malePersons = computed(() => store.getters['male/personList']) //通過getter獲取statelet femalePersons = computed(() => store.state.female.personList)   //直接獲取statefunction addToMale(person){store.dispatch('male/addAction', person)store.dispatch('female/removeAction', person)//如果模塊中namespaced === true,那么要在方法名前面添加模塊的邏輯路徑//index.js里使用的模塊為路徑的起點(diǎn)。//比如index里面有一個moduleA,moduleA有一個子模塊moduleB,module有一個action是actionx//那么調(diào)用方式為 store.dispatch('moduleA/moduleB/actionx', value)}function addToFemale(person){store.dispatch('female/addAction', person)store.dispatch('male/removeAction', person)}return {malePersons,femalePersons,addToMale,addToFemale}}}
</script>
<style></style>

2.2 在命名空間中訪問全局內(nèi)容

什么是全局內(nèi)容?不在同一個模塊中的內(nèi)容就是全局內(nèi)容。
比如,對于上文中的female模塊來說,male模塊中的getters state action mutations就是全局內(nèi)容,接下來將會講解如何在一個模塊中訪問到全局內(nèi)容。
為了便于理解,我創(chuàng)造了一個新的樣例:

├──src├── components│   └── Test.vue└── store├── index.js└── modules├── moduleA.js└── moduleB.js

index是所有的模塊的根,moduleA和moduleB是兩個子模塊,接下來要做的事情就是在index.js、moduleA.js、moduleB.js中寫一些getters state action mutations,最終達(dá)成的效果是在index中訪問moduleA的內(nèi)容,在moduleA中訪問moduleB的內(nèi)容,在moduleB中訪問index的內(nèi)容。
Test.vue:

<template><li> {{rootModule.name}}---{{rootModule.num}} <button @click="rootClick">rootAction---A++</button> </li><li> {{moduleA.name}}---{{moduleA.num}} <button @click="aClick">moduleAction---B++</button> </li><li> {{moduleB.name}}---{{moduleB.num}} <button @click="bClick">moduleAction---root++</button> </li><!-- 點(diǎn)擊root,moduleA數(shù)字加一;點(diǎn)擊moduleA,moduleB數(shù)字加一;點(diǎn)擊moduleB,root數(shù)字加一 --><button @click="store.dispatch('globalAction')">觸發(fā)全局action</button>
</template><script>import {useStore} from 'vuex'export default {setup(){let store = useStore()console.log(store.getters);let rootModule = store.getters['moduleB/rootStateThroughModuleB'].info //通過moduleB的getters獲得root的狀態(tài)let moduleA = store.getters['moduleAStateThroughRoot'].info            //通過root的getters獲得moduleA的狀態(tài)let moduleB = store.getters['moduleA/moduleBStateThroughModuleA'].info //通過moduleA的getters獲得moduleB的狀態(tài)// let moduleB = store.state.moduleB.info// let moduleA = store.state.moduleA.info// let rootModule = store.state.infofunction rootClick(){store.dispatch('addAction', 1)}    //調(diào)用root中的action,改變的是moduleA的狀態(tài)function aClick(){store.dispatch('moduleA/addAction', 1)}//調(diào)用moduleA中的action,改變的是moduleB的狀態(tài)function bClick(){store.dispatch('moduleB/addAction', 1)}//調(diào)用moduleB中的action,改變的是root的狀態(tài)return {rootModule,moduleA,moduleB,rootClick,aClick,bClick,store}}}
</script>
<style></style>

3. vuex的typescript用法

vuex的typescript用法其實(shí)就是把state加上ts里的類型限制

3.1 不使用模塊化

store文件

// store.ts
import { InjectionKey } from 'vue'
import { createStore, Store } from 'vuex'// 為 store state 聲明類型
export interface State {count: number
}// 定義 injection key
export const key: InjectionKey<Store<State>> = Symbol()export const store = createStore<State>({state: {count: 0}
})

在main.ts里引入

// main.ts
import { createApp } from 'vue'
import { store, key } from './store'const app = createApp({ ... })// 傳入 injection key
app.use(store, key)app.mount('#app')

在組件中使用useStore()獲取store,將上述 injection key 傳入 useStore 方法可以獲取類型化的 store。

// vue 組件
import { useStore } from 'vuex'
import { key } from './store'export default {setup () {const store = useStore(key)store.state.count // 類型為 number}
}

在每個組件中都導(dǎo)入key有些重復(fù)且麻煩,我們可以將useStore()封裝成myUseStore()

// 在store.ts增加下面幾行
import { useStore } from 'vuex'
export function myUseStore () {return useStore(key)
}

3.2 使用模塊化

store/index.ts

import { createStore, Store  } from 'vuex'
import moduleA from './modules/moduleA'
import moduleB from './modules/moduleB'
import { InjectionKey } from 'vue'//模塊A state的類型
interface moduleAState {name:string,age:number
}//模塊B state的類型
interface moduleBState {id:string,adult:boolean
}//vuex state類型
interface State{moduleA:moduleAState,moduleB:moduleBState 
}//如果使用模塊化的話,在createStore參數(shù)里面就不要寫state了,否則會報(bào)錯
export const key: InjectionKey<Store<State>> = Symbol()
export const store =  createStore<State>({// state:{}, //不可以加這一行,否則報(bào)錯modules: {moduleA,moduleB}
})

在組件中訪問:

// vue 組件
import { useStore } from 'vuex'
import { key } from './store'export default {setup () {const store = useStore(key)store.state.moduleA// 類型為 moduleAStatestore.state.moduleB// 類型為 moduleBState}
}

Pinia 簡介?

Pinia是vue生態(tài)里Vuex的替代者,一個全新的vue狀態(tài)管理庫。在Vue3成為正式版以后,尤雨溪強(qiáng)勢推薦的項(xiàng)目就是Pinia。
那先來看看Pinia比Vuex好的地方,也就是Pinia的五大優(yōu)勢。

可以對Vue2和Vue3做到很好的支持,也就是老項(xiàng)目也可以使用Pinia。
拋棄了Mutations的操作,只有state、getters和actions.極大的簡化了狀態(tài)管理庫的使用,讓代碼編寫更加容易直觀。
不需要嵌套模塊,符合Vue3的Composition api ,讓代碼更加扁平化。
完整的TypeScript支持。Vue3版本的一大優(yōu)勢就是對TypeScript的支持,所以Pinia也做到了完整的支持。如果你對Vuex很熟悉的化,一定知道Vuex對TS的語法支持不是完整的(經(jīng)常被吐槽)。
代碼更加簡潔,可以實(shí)現(xiàn)很好的代碼自動分割。Vue2的時(shí)代,寫代碼需要來回翻滾屏幕屏幕找變量,非常的麻煩,Vue3的Composition api完美了解決這個問題。 可以實(shí)現(xiàn)代碼自動分割,pinia也同樣繼承了這個優(yōu)點(diǎn)。

安裝和配置Pinia

安裝和配置Pinia非常簡單,像其他Vue插件一樣,Pinia需要通過yarn或npm進(jìn)行安裝并且與Vue應(yīng)用程序進(jìn)行綁定,可以使用以下命令進(jìn)行安裝:

yarn add pinia
# 或者使用 npm
npm install pinia
?

在安裝完P(guān)inia包之后,需要在main.ts文件中導(dǎo)入createPinia函數(shù)并將Pinia插件與Vue應(yīng)用程序綁定,如下所示:

import { createApp } from 'vue';
import { createPinia } from 'pinia';
import App from './App.vue';const app = createApp(App);const pinia = createPinia();
app.use(pinia);app.mount('#app');

使用 createPinia() 函數(shù)創(chuàng)建并初始化Pinia插件實(shí)例,將其與Vue應(yīng)用程序綁定使用app.use(pinia)。至此,我們就可以使用Pinia來管理Vue應(yīng)用程序的狀態(tài)了。

Pinia的核心

Store

Store是 Pinia 中管理狀態(tài)的核心概念。它相當(dāng)于一個 Vue 組件中的狀態(tài),但是 Store是一個獨(dú)立的模塊。

Store 是用 defineStore() 定義的,它的第一個參數(shù)要求是一個獨(dú)一無二的名字,這個名字 ,也被用作 id ,是必須傳入的, Pinia 將用它來連接 store 和 devtools。為了養(yǎng)成習(xí)慣性的用法,將返回的函數(shù)命名為 use… 是一個符合組合式函數(shù)風(fēng)格的約定。

defineStore() 的第二個參數(shù)可接受兩類值:Setup 函數(shù)或 Option 對象。
定義Store的示例代碼:

import { defineStore } from 'pinia'// 你可以對 `defineStore()` 的返回值進(jìn)行任意命名,但最好使用 store 的名字,
同時(shí)以 `use` 開頭且以 `Store` 結(jié)尾。
(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一個參數(shù)是你的應(yīng)用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {// 其他配置...
})
  • defineStore( ) 方法的第一個參數(shù):相當(dāng)于為容器起一個名字。注意:這里的名字必須唯一,不能重復(fù)。
  • defineStore( ) 方法的第二個參數(shù):可以簡單理解為一個配置對象,里邊是對容器倉庫的配置說明。當(dāng)然這種說明是以對象的形式。
  • state 屬性: 用來存儲全局的狀態(tài)的,這里邊定義的,就可以是為SPA里全局的狀態(tài)了。
  • getters屬性: 用來監(jiān)視或者說是計(jì)算狀態(tài)的變化的,有緩存的功能。
  • actions屬性: 對state里數(shù)據(jù)變化的業(yè)務(wù)邏輯,需求不同,編寫邏輯不同。說白了就是修改state全局狀態(tài)數(shù)據(jù)的。
    ?

State

State 是 store 中存儲數(shù)據(jù)的地方。通過定義 State,可以在 store 的任何位置訪問和修改數(shù)據(jù)。

在 Pinia 中,state 被定義為一個返回初始狀態(tài)的函數(shù)。這使得 Pinia 可以同時(shí)支持服務(wù)端和客戶端。
定義State的示例代碼如下:

import { defineStore } from 'pinia'const useStore = defineStore('storeId', {// 為了完整類型推理,推薦使用箭頭函數(shù)state: () => {return {// 所有這些屬性都將自動推斷出它們的類型count: 0,name: 'Eduardo',isAdmin: true,items: [],hasChanged: true,}},
})

Getter

Getter 用來獲取從 state 派生的數(shù)據(jù),類似于 Vue 組件中的 computed 計(jì)算屬性??梢酝ㄟ^ defineStore() 中的 getters 屬性來定義它們。推薦使用箭頭函數(shù),并且它將接收 state 作為第一個參數(shù):

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

Action


Action 相當(dāng)于組件中的 方法。它們可以通過 defineStore() 中的 actions 屬性來定義;Action 是一種將異步操作封裝在 store中的方式,它是一個可以被調(diào)用的函數(shù),也可以接收參數(shù)并修改 store 中的狀態(tài)。 Action應(yīng)該始終是同步的,并返回一個 Promise 對象,以便在處理異步操作時(shí)能夠很好地處理結(jié)果。

Pinia 中的 Action 由 defineStore 創(chuàng)建,可以通過在 actions 中定義它們來使用它們。例如,下面是一個 store 中的 Action 定義:

import { defineStore } from 'pinia'export const myStore = defineStore('myStore',{ state: () => ({message: 'Hello',}),actions: {async fetchMessage() {const response = await fetch('http://127.0.0.1:5173/message')const data = await response.json()this.message = data.message},},
})

在上面的示例中,我們?yōu)?myStore 定義了一個 Action , fetchMessage() ,它會從后臺 API 中獲取數(shù)據(jù),并更新 store 中的狀態(tài)。然后,我們可以從組件或其他 Action 中調(diào)用該 Action :

import { useStore } from 'pinia'export default {setup() {const store = useStore('myStore')function handleClick() {store.fetchMessage()}return {handleClick,}},
}

創(chuàng)建和使用Pinia

創(chuàng)建Pinia

前面我們已經(jīng)安裝和配置好了Pinia,在創(chuàng)建Pinia之前,為了代碼的統(tǒng)一管理和可維護(hù)性,我們依然先創(chuàng)建一個store文件夾,然后在來創(chuàng)建相關(guān)的Pinia,具體步驟如下

  1. 在src文件夾下新建store文件夾,后面所有涉及需要Pinia進(jìn)行狀態(tài)管理的代碼都放在該文件夾下
  2. 在store文件夾下新建movieListStore.js文件,創(chuàng)建完成后,打開該文件
  3. 在movieListStore.js文件中引入Pinia中的defineStore 方法
    ?
import { defineStore } from 'pinia'

創(chuàng)建defineStore 對象,定義一個useMovieListStore用于接收defineStore創(chuàng)建的對象,并將其通過export default 導(dǎo)出

 const useMovieListStore = defineStore('movie',{ state: () => ({isShow: true,movies: [],}),getters: {getIsShow() {return this.isShow},getMovies() {return this.movies},},actions: {setIsShow(value) {this.isShow = value},async fetchMovies() {const response = await fetch('https://api.movies.com/movies')const data = await response.json()this.movies = data},},
})
export default useMovieListStore 

注意:
這里需要注意,官方建議我們在定義鉤子函數(shù)時(shí),建議使用use開頭Store結(jié)尾的命名方式來對上面創(chuàng)建的對象進(jìn)行命名,如上面的useMovieListStore

使用Pinia

前面我們已經(jīng)創(chuàng)建好了Pinia,接下來,我們就可以在組件中使用了。
在Vue組件中使用store,我們需要通過 useStore() 函數(shù)訪問store的實(shí)例。
在Vue組件中使用Pinia的步驟如下

1 先使用 import 引入Pinia 中的 useStore

import { useStore } from 'pinia'

2? 創(chuàng)建useStore對象

const store = useStore('movie')
  1. 在需要獲取狀態(tài)的地方通過上面定義的store.getIsShow()獲取狀態(tài)
return {isShow: store.getIsShow(),
}

Menu.vue中完整的示例代碼如下:

<template><nav><ul><li v-show="isShow">{{ $route.name }} </li><li><router-link to="/">Home</router-link></li><li><router-link to="/movies">Movies</router-link></li></ul></nav>
</template><script>
import { defineComponent } from 'vue'
import { useStore } from 'pinia'export default defineComponent({name: 'Menu',setup() {const store = useStore('movie')return {isShow: store.getIsShow(),}},
})
</script>

Pinia的Setup Store方式定義 Store
Setup Store與Option Store稍有不同,它與 Vue 組合式 API 的 setup 函數(shù) 相似,我們通過傳入一個函數(shù),該函數(shù)定義了一些響應(yīng)式屬性和方法,并且返回一個帶有我們想暴露出去的屬性和方法的對象。示例代碼如下:

export const useCounterStore = defineStore('counter', () => {const count = ref(0)function increment() {count.value++}return { count, increment }
})

在 Setup Store 中:

  • ref() 就是 state 屬性
  • computed() 就是 getters
  • function() 就是 actions

pinia在API里的使用

?1.$reset :重置到初始值

這個 $reset 可以將 state 的數(shù)據(jù)初始到初始值,比如我們有一個數(shù)據(jù),點(diǎn)擊按鈕改變了,然后我們可以通過這個 API ,將數(shù)據(jù)恢復(fù)到初始狀態(tài)值。

??2.$subscribe:監(jiān)聽 state 數(shù)據(jù)變化

$subscribe 使用來監(jiān)聽的,監(jiān)聽 state 數(shù)據(jù)的變化,只要 state 里面的數(shù)據(jù)發(fā)生了變化,就會自動走這個函數(shù)。

? ?3.$onAction:一調(diào)用 actions 就觸發(fā)

這個看名字就很好理解了吧,就是 action 一調(diào)用就會被觸發(fā)。

它里面只有一個參數(shù) args。寫一下關(guān)鍵代碼吧。

Pinia 與 VueX的區(qū)別與優(yōu)缺點(diǎn):

pinia和vuex的區(qū)別
(1)pinia它沒有mutation,他只有state,getters,action【同步、異步】使用他來修改state數(shù)據(jù)
?(2)pinia他默認(rèn)也是存入內(nèi)存中,如果需要使用本地存儲,在配置上比vuex麻煩一點(diǎn)

?(3)pinia語法上比vuex更容易理解和使用,靈活。
?(4)pinia沒有modules配置,沒一個獨(dú)立的倉庫都是definStore生成出來的

?(5)pinia state是一個對象返回一個對象和組件的data是一樣的語法
?

Vuex 和 Pinia 的優(yōu)缺點(diǎn)
Pinia的優(yōu)點(diǎn)

完整的 TypeScript 支持:與在 Vuex 中添加 TypeScript 相比,添加 TypeScript 更容易
極其輕巧(體積約 1KB)
store 的 action 被調(diào)度為常規(guī)的函數(shù)調(diào)用,而不是使用 dispatch 方法或 MapAction 輔助函數(shù),這在 Vuex 中很常見
支持多個Store
支持 Vue devtools、SSR 和 webpack 代碼拆分
Pinia的缺點(diǎn)

不支持時(shí)間旅行和編輯等調(diào)試功能? ?

Vuex的優(yōu)點(diǎn)

  • 支持調(diào)試功能,如時(shí)間旅行和編輯
  • 適用于大型、高復(fù)雜度的Vue.js項(xiàng)目

Vuex的缺點(diǎn)

  • 從 Vue 3 開始,getter 的結(jié)果不會像計(jì)算屬性那樣緩存
  • Vuex 4有一些與類型安全相關(guān)的問題

何時(shí)使用Pinia,何時(shí)使用Vuex


個人感覺:,由于Pinea是輕量級的,體積很小,它適合于中小型應(yīng)用。它也適用于低復(fù)雜度的Vue.js項(xiàng)目,因?yàn)橐恍┱{(diào)試功能,如時(shí)間旅行和編輯仍然不被支持。
將 Vuex 用于中小型 Vue.js 項(xiàng)目是過度的,因?yàn)樗亓考壍?#xff0c;對性能降低有很大影響。因此,Vuex 適用于大規(guī)模、高復(fù)雜度的 Vue.js 項(xiàng)目。
?

Vue3使用Vuex_vue3 vuex官網(wǎng)_BigJF的博客-CSDN博客

Vue3中Vuex的使用_vue3中使用vuex_普通網(wǎng)友的博客-CSDN博客

Vue3之Vuex_vue3的vuex_開longlong了嗎?的博客-CSDN博客

Vue3中使用Pinia詳解_九仞山的博客-CSDN博客

pinia和vuex的區(qū)別 Vuex 和 Pinia 的優(yōu)缺點(diǎn) 何時(shí)使用Pinia,何時(shí)使用Vuex_pinia和vuex區(qū)別_more名奇妙的博客-CSDN博客

http://aloenet.com.cn/news/46193.html

相關(guān)文章:

  • 上海松江區(qū)網(wǎng)站建設(shè)鄭州seo外包平臺
  • 網(wǎng)站推廣服務(wù)合同模板2023年4月疫情恢復(fù)
  • 網(wǎng)站窗口建設(shè)活動營銷推廣方案
  • 怎么給網(wǎng)站做鏈接今日國際新聞?wù)畻l
  • 虎門仿做網(wǎng)站搜索引擎優(yōu)化方案
  • 簡單個人博客模板網(wǎng)站網(wǎng)站內(nèi)容管理系統(tǒng)
  • 京東網(wǎng)站建設(shè)步驟關(guān)鍵詞排名關(guān)鍵詞快速排名
  • 做網(wǎng)站獨(dú)立云服務(wù)器什么意思網(wǎng)址大全瀏覽器
  • 網(wǎng)站建設(shè)平臺漢龍網(wǎng)頁制作官方網(wǎng)站
  • 自己做的個人網(wǎng)站無法備案廣東東莞今日最新消息
  • 新手學(xué)做網(wǎng)站必備軟件seo技術(shù)培訓(xùn)課程
  • 網(wǎng)站支付功能怎么做全自動推廣引流軟件免費(fèi)
  • 日本做暖網(wǎng)站推廣網(wǎng)站要注意什么
  • 寧德住房和城鄉(xiāng)建設(shè)部網(wǎng)站怎樣做網(wǎng)絡(luò)推廣營銷
  • 新網(wǎng)站怎么做權(quán)重國際新聞軍事最新消息
  • 廣東網(wǎng)站制作百度客服人工電話24小時(shí)
  • 拼多多網(wǎng)站分析百度網(wǎng)站登錄
  • 做類似交易貓的網(wǎng)站如何優(yōu)化網(wǎng)頁
  • 六安網(wǎng)站建設(shè)哪家靠譜線下推廣宣傳方式有哪些
  • 網(wǎng)站眾籌該怎么做公眾號軟文是什么意思
  • 忍不住在樓道里面做免費(fèi)網(wǎng)站千萬不要學(xué)網(wǎng)絡(luò)營銷
  • 網(wǎng)站下方一般放什么原因宣傳推廣策略
  • 計(jì)算機(jī)專業(yè)里面哪個專業(yè)最好攀枝花seo
  • 營銷型網(wǎng)站一套東莞seo網(wǎng)站優(yōu)化排名
  • 哈爾濱住房和城鄉(xiāng)建設(shè)廳網(wǎng)站品牌推廣方案怎么寫
  • 鐵道部網(wǎng)上訂票網(wǎng)站素材網(wǎng)站分析案例
  • 家居飾品網(wǎng)站建設(shè)論文怎么在百度上推廣自己的產(chǎn)品
  • 動態(tài)網(wǎng)站與靜態(tài)網(wǎng)站的區(qū)別北京百度seo服務(wù)
  • 020模版網(wǎng)站制作網(wǎng)絡(luò)營銷的推廣方式
  • 51自學(xué)網(wǎng)官方網(wǎng)站百度廣告電話號碼