1 Vue2專案中,Vuex狀態管理工具,幾乎可以說是必不可少的了。而在Vu3中,尤大大推薦我們使用pinia(拍你啊)進行狀態管理,咱得聽話,用就完了。
官網介紹:Pinia 是 Vue 的儲存庫,它允許您跨元件/頁面共用狀態
個人理解:在我看來就是變態版 vuex,聽說是為了尊重原作者,所以給改名了叫 pinia(拍你啊)
Vue3 + TS + Vite 專案
參考:Vue3.x 全家桶+vite+TS-搭建 Vue3.x 專案
參考:vue3 學習
npm create vite@latest my-vite-app --template vue-ts
npm install pinia
我們在 main.ts 主檔案中,引入 pinia 的createPinia 方法, 建立根儲存,以方便全域性呼叫。
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();
const app = createApp(App);
app.use(pinia);
app.mount("#app");
應用場景:
. 多個檢視依賴於同一狀態。
. 來自不同檢視的行為需要變更同一狀態。
我們需要用到 pinia 的defineStore() 方法,建立一個 store。
defineStore:
建立後編寫程式碼如下:
/src/store/piniaStore.ts
import { defineStore } from 'pinia'
export const useUsersStore = defineStore('pinia_id', {
})
我們在上一步已經引入了 pinia,並且在 store 檔案下建立了一個叫 piniaStore 的 store,接下來讓我們看看在元件裡如何呼叫
<script setup lang="ts">
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
console.log(store);
</script>
方法很簡單一個 useUsersStore 方法搞定,我們看一下列印內容:
$dispose: f $dispose()$id: "pinia_id"
$onAction: f ()
$patch: f $patch(partialStateOrMutator)
$reset: f Sreset()
$subscribe: Ssubscribe(callback, options2 = ) const removeSubscription = addSuoscription(suhotUpdate: (newStore) => f...]
也就這些哈,沒啥玩楞。
我們往 store 里加點資料來源 state 吧!
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
age: 20,
message:'我來存放公共資料哈!'
sex: "男",
};
},
});
回想一下 vuex 怎麼存取的
this.$store.state.全域性資料名稱
// 從vuex中按需匯入mapState函數
import { mapState } from 'vuex'
// 將全域性資料 因設為當前元件的計算屬性
computed: {
...mapState(['count'])
}
pinia 如何存取呢?
其實我們定義的 state 資料就在 useUsersStore 內,我們自行就可以直接拿到相關資料
<template>
<p>描述:{{ message }}</p>
<p>年齡:{{ age }}</p>
<p>性別:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const message = ref<string>(store.message);
const age = ref<number>(store.age);
const sex = ref<string>(store.sex);
</script>
當然我們也可以用 es6 解構賦值來優化一下
const { message, age, sex } = store;
我們使用 pinia 更想做到多元件公用統一資料,新建一個 Child.vue 其實用法很簡單直接呼叫使用即可
<template>
<p>我是一個子元素</p>
<p>描述:{{ message }}</p>
<p>年齡:{{ age }}</p>
<p>性別:{{ sex }}</p>
</template>
<script setup lang="ts">
import { ref } from "vue";
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const { message, age, sex } = store;
</script>
我們在回想一下 vuex 怎麼修改的
看看 pinia
其實如果想要修改修改 store 中的資料,可以直接重新賦值
<template>
<img alt="Vue logo" src="./assets/logo.png" />
<p>年齡:{{ age }}</p>
<button @click="changeAge">年齡不對</button>
</template>
<script setup lang="ts">
import child from './child.vue';
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
const { nage,} = store;
const changeAge = () => {
store.age = 26;
console.log(store);
};
</script>
列印可也看出。store 中 age 資料發生了改變,再看看,呦呵,頁面沒響應。
我們可能去監聽 store 資料變化然後重新整理頁面,但有個更好的方法等著我們
pinia 的storeToRefs 方法把我們的 state 變得具有響應
import { storeToRefs } from 'pinia';
const store = useUsersStore();
const { message, age, sex } = storeToRefs(store);
store 的$reset()方法為我們提供了 state 資料重置的可能
<button @click="onResetData">重置store</button>
const onResetData = () => {
store.$reset();
};
store.$patch({
message: "批次搞事情",
age: 100,
sex: "女",
});
store.$patch((state) => {
state.items.push({ message: 'shoes', quantity: 1 })
state.hasChanged = true
})
store.$state = { counter: 666, name: 'yup' }
Getter 用於對 Store 中的資料進行加工處理形成新的資料
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
age: 25,
sex: "男",
};
},
getters: {
getAddAge: (state) => {
return state.age + 100;
},
},
});
<template>
<p>新年齡:{{ store.getAddAge }}</p>
<button @click="patchStore">批次修改資料</button>
</template>
<script setup lang="ts">
import { useUsersStore } from "../src/store/piniaStore";
const store = useUsersStore();
// 批次修改資料
const patchStore = () => {
store.$patch({
age: 100,
sex: "女",
});
};
</script>
export const useUsersStore = defineStore("users", {
state: () => {
return {
age: 25,
sex: "男",
};
},
getters: {
getAddAge: (state) => {
return state.age + 100;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 呼叫其它getter
},
},
});
上文提到 getter 與計算屬性差不多,想想計算屬性怎麼傳遞的呢?
computed:{
getNewName(){
function (str){
return str+this.name
}
}
}
看一下 getter 的
<p>新年齡:{{ store.getAddAge(1100) }}</p>
getters: {
getAddAge: (state) => {
return (num: number) => state.age + num;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 呼叫其它getter
},
},
對資料進行邏輯加工,完成默寫特定的業務邏輯。和 vue 元件程式碼中的 methods 相似,存放一些處理業務邏輯的方法。
export const useUsersStore = defineStore("pinia_id", {
state: () => {
return {
message: "",
age: 25,
sex: "男",
name:'王'
};
},
getters: {
getAddAge: (state) => {
return (num: number) => state.age + num;
},
getNameAndAge(): string {
return this.name + this.getAddAge; // 呼叫其它getter
},
},
actions: {
saveName(name: string) {
this.name = name;
},
},
});
const saveName = () => {
store.saveName("我用來呼叫action內的方法");
};
至此文章結束!