引用位址:
https://github.com/vuejs/pinia
https://pinia.web3doc.top/
目前内容
1 Pinia
1.1 概述
1.2 核心概念
2 快速建構
2.1 利用 vite 建構項目
2.2 安裝 Pinia
3 Store
3.1 什麼是Store?
3.2 如何定義Store?
3.3 如何使用 Store?
3.4 解析通路Pinia容器中的資料
1.1 概述
Pinia 最初是在 2019 年 11 月左右重新設計使用 Composition API 。從那時起,最初的原則仍然相同,但 Pinia 對 Vue 2 和 Vue 3 都有效,并且不需要您使用組合 API。
Pinia 是 Vue 的存儲庫,它允許您跨元件/頁面共享狀态。如果您熟悉 Composition API,您可能會認為您已經可以通過一個簡單的 export const state = reactive({}). 這對于單頁應用程式來說是正确的,但如果它是伺服器端呈現的,會使您的應用程式暴露于安全漏洞。 但即使在小型單頁應用程式中,您也可以從使用 Pinia 中獲得很多好處:
- dev-tools 支援 跟蹤動作、突變的時間線 Store 出現在使用它們的元件中 time travel 和 更容易的調試
- 熱子產品更換 在不重新加載頁面的情況下修改您的 Store 在開發時保持任何現有狀态
- 插件:使用插件擴充 Pinia 功能
- 為 JS 使用者提供适當的 TypeScript 支援或 autocompletion 伺服器端渲染支援
1.2 核心概念
- Store
- State
- Getters
- Actions
- Plugins
2 快速建構
2.1 利用 Vite 建構Vue3 的項目
- 通過 指令npm init vite@latest 直接建構項目
- 這裡我選擇的是 vue-ts
- 進入目錄,還原依賴 npm install 或 npm i
- 運作項目和預覽
2.2 安裝 Pinia
用 NPM 包管理器安裝 Pinia:
npm install pinia
提示
如果您的應用使用 Vue 2,您還需要安裝組合 API:@vue/composition-api。 如果您使用 Nuxt,則應遵循這些說明。
建立一個 pinia執行個體并将其挂載在Vue 根執行個體:
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia'
// createApp(App).use(createPinia()).mount('#app')
// 建立 Pinia 執行個體
const pinia = createPinia();
const app = createApp(App)
// 把 Pinia 執行個體 挂載到 vue 根執行個體
app.use(pinia)
app.mount('#app')
3 Store
3.1 什麼是 Store ?
一個 Store (如 Pinia)是一個實體,它持有未綁定到您的元件樹的狀态和業務邏輯。換句話說,它托管全局狀态。
它有點像一個始終存在并且每個人都可以讀取和寫入的元件。
它有三個概念,state、getters 和 actions 并且可以安全地假設這些概念等同于元件中的“資料”、“計算”和“方法”。
3.2 如何定義 Store?
正常情況下,在項目中建立 store 檔案夾,專門存放 相關代碼
Store 是使用 defineStore() 定義的,并且它需要一個唯一名稱,作為第一個參數傳遞:
import { defineStore } from "pinia";
/**
* 1. 定義容器
* 建立檢索存儲執行個體的“useStore”函數
*
* @param id - 容器ID,必須是唯一
* @param options - 容器選項
*/
export const useMainStore = defineStore("main", {
// 類似于元件的 data ,用于存儲全局狀态
state: () => {
return { clickCount:100 };
},
// 類似于元件的Computed,用來封裝計算屬性,有緩存功能
getters: {},
// 類似于元件的 methods,封裝業務邏輯,修改state
actions: {},
});
3.3 如何使用 Store?
自定義一個元件,引用自定義 store
<template>
<h2>使用 自定義 store :{{ storeModel.clickCount }}</h2>
</template>
<script lang="ts" setup>
import { useMainStore } from "../store/useMain";
const storeModel = useMainStore();
console.log(storeModel.clickCount);
</script>
引用元件
<script setup lang="ts">
import StoreComponent from './components/StoreComponentDemo.vue';
</script>
<template>
<StoreComponent />
</template>
效果
3.4 解析通路Pinia容器中的資料
修改 useMainStore
import { defineStore } from "pinia";
export const useMainStore = defineStore("main", {
state: () => {
return {
clickCount:100,
bookName :"《挖空地球》",
bookAutor:"作者 張三"
}
}
});
修改元件
<template>
<h2>使用 自定義 store </h2>
<p>--------------------------------------</p>
<p>
<button @click="clickHandle">修改點選數</button>
</p>
<p>--------------------------------------</p>
<p>書籍名稱:{{ storeModel.bookName }}</p>
<p>書籍作者:{{ storeModel.bookAutor }}</p>
<p>點選次數:{{ storeModel.clickCount }}</p>
<hr>
<p>書籍名稱:{{ bookName }}</p>
<p>書籍作者:{{ bookAutor }}</p>
<p>點選次數:{{ clickCount }}</p>
</template>
<script lang="ts" setup>
import { useMainStore } from "../store/useMain";
const storeModel = useMainStore();
console.log(storeModel.clickCount);
// 這種寫法有問題,因為這樣拿到的資料不是響應式的,是一次性的
const { clickCount, bookAutor, bookName } = storeModel
const clickHandle = ()=>{
storeModel.clickCount++;
};
</script>
效果:
存在的問題:const { clickCount, bookAutor, bookName } = storeModel 不随着點選按鈕的點選,動态響應。
是以這種寫法:解析到的資料是一次性的,不是響應式的
針對上述問題(解決方式,利用 Pinia 元件 storeToRefs 方法,把解構出來的資料做 ref 做了響應代理):
- 引用 pinia 元件 import { storeToRefs } from "pinia";
- 改寫取值方法:const { clickCount, bookAutor, bookName } = storeToRefs(storeModel)
<template>
<h2>使用 自定義 store </h2>
<p>--------------------------------------</p>
<p>
<button @click="clickHandle">修改點選數</button>
</p>
<p>--------------------------------------</p>
<p>書籍名稱:{{ storeModel.bookName }}</p>
<p>書籍作者:{{ storeModel.bookAutor }}</p>
<p>點選次數:{{ storeModel.clickCount }}</p>
<hr>
<p>書籍名稱:{{ bookName }}</p>
<p>書籍作者:{{ bookAutor }}</p>
<p>點選次數:{{ clickCount }}</p>
</template>
<script lang="ts" setup>
import { storeToRefs } from "pinia";
import { useMainStore } from "../store/useMain";
const storeModel = useMainStore();
console.log(storeModel.clickCount);
// 這種寫法有問題,因為這樣拿到的資料不是響應式的,是一次性的
// const { clickCount, bookAutor, bookName } = storeModel
// 解決上述問題
// import { storeToRefs } from 'pinia'
const { clickCount, bookAutor, bookName } = storeToRefs(storeModel)
const clickHandle = ()=>{
storeModel.clickCount++;
};
</script>
持續更新ing