Vue使用pinia管理數(shù)據(jù)pinia持久化存儲問題
Vue使用pinia管理數(shù)據(jù)
Vue3 + TS
步驟:
在main.ts中注冊 pinia
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)
創(chuàng)建文件store/modules/home.ts,用于管理home模塊的數(shù)據(jù)
import { defineStore } from 'pinia'
const useHomeStore = defineStore('home',{
state:()=>({
name:'tony'
})
})
export default useHomeStore
創(chuàng)建store/index.ts統(tǒng)一管理所有的模塊
import useHomeStore from './modules/home'
const useStore = () => {
return {
home:useHomeStore()
}
}
export default useStore
測試
import useStore from '@/store'
const { home } = useStore()
console.log(home.tony)
實(shí)際操作:使用 Pinia 獲取頭部分類導(dǎo)航
在store/modules/home.ts中提供 state 和 actions
const useHomeStore = defineStore('home',{
state:() =>({
categoryList:[]
}),
actions:{
aysnc getAllCategory(){
const {data} = await rquest.get('/home/category/head')
this.categoryList = data.result
}
}
})
在Layout/index.vue中發(fā)送請求
<script setup lang="ts">
import useStore from '@/store'
const { home } = useStore()
home.getAllCategory()
</script>
TS 類型聲明文件
定義類型聲明
在src\types\api\home.d.ts中定義數(shù)據(jù)類型
// 分類數(shù)據(jù)單項(xiàng)類型
export interface Goods {
desc: string;
id: string;
name: string;
picture: string;
price: string;
title: string;
alt: string;
};
export interface Children {
id: string;
name: string;
picture: string;
goods: Goods[];
};
export interface Category {
id: string;
name: string;
picture: string;
children: Children[];
goods: Goods[];
};
// 分類數(shù)據(jù)列表類型
export type CategoryList = Category[];
類型出口統(tǒng)一
新建 src\types\index.d.ts
// 統(tǒng)一導(dǎo)出所有類型文件 export * from "./api/home";
應(yīng)用
修改store/modules/home.ts,給 axios 請求增加泛型
import { defineStore } from "pinia";
import request from "@/utils/request";
import type { CategoryList } from "@/types";
const useHomeStore = defineStore("home", {
state: () => ({
categoryList: [] as CategoryList,
}),
actions: {
async getAllCategory() {
const {data} = await request.get("/home/category/head");
this.categoryList = data.result;
},
},
});
export default useHomeStore;
Axios 二次封裝
src\utils\request.ts
-import axios from "axios";
+import axios, { type Method } from "axios";
const instance = axios.create({
baseURL: "xxx",
timeout: 5000,
});
// 添加請求攔截器
instance.interceptors.request.use(
function (config) {
// 在發(fā)送請求之前做些什么
return config;
},
function (error) {
// 對請求錯(cuò)誤做些什么
return Promise.reject(error);
}
);
// 添加響應(yīng)攔截器
instance.interceptors.response.use(
function (response) {
return response;
},
function (error) {
// 對響應(yīng)錯(cuò)誤做點(diǎn)什么
return Promise.reject(error);
}
);
+ // 后端返回的接口數(shù)據(jù)格式
+ interface ApiRes<T = unknown> {
+ msg: string;
+ result: T;
+ }
+/**
+ * axios 二次封裝,整合 TS 類型
+ * @param url 請求地址
+ * @param method 請求類型
+ * @param submitData 對象類型,提交數(shù)據(jù)
+ */
+export const http = <T>(method: Method, url: string, submitData?: object) => {
+ return instance.request<ApiRes<T>>({
+ url,
+ method,
+ // ?? 自動(dòng)設(shè)置合適的 params/data 鍵名稱,如果 method 為 get 用 params 傳請求參數(shù),否則用 data
+ [method.toUpperCase() === "GET" ? "params" : "data"]: submitData,
+ });
+};
export default instance;
使用store/modules/home.ts
import { defineStore } from 'pinia'
-import request from "@/utils/request";
+import { http } from "@/utils/request";
const useHomeStore = defineStore('home',{
state:()=>({
name:'tony'
}),
actions: {
async getAllCategory() {
- const res = await request.get<ApiRes<CategoryList>>("/home/category/head");
+ // 使用起來簡潔很多
+ const res = await http<CategoryList>("GET", "/home/category/head");
this.categoryList = res.data.result;
},
},
})
export default useHomeStore
pinia 持久化存儲
目標(biāo): 通過 Pinia 插件快速實(shí)現(xiàn)持久化存儲。
插件文檔:點(diǎn)擊查看
用法
安裝
yarn add pinia-plugin-persistedstate # 或 npm i pinia-plugin-persistedstate
使用插件
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' const pinia = createPinia(); pinia.use(piniaPluginPersistedstate); app.use(pinia);
模塊開啟持久化
const useHomeStore = defineStore("home",()=>{
...
},
// defineStore 第三個(gè)參數(shù)
{
// 添加配置開啟 state/ref 持久化存儲
// 插件默認(rèn)存儲全部 state/ref
persist: true,
}
);
常見疑問
Vue2 能不能用 Pinia 和 持久化存儲插件。
- 可以使用,需配合 @vue/composition-api 先讓 Vue2 老項(xiàng)目支持 組合式API。
- Pinia 能在 組合式API 中使用。
模塊做了持久化后,以后數(shù)據(jù)會(huì)不會(huì)變,怎么辦?
- 先讀取本地的數(shù)據(jù),如果新的請求獲取到新數(shù)據(jù),會(huì)自動(dòng)把新數(shù)據(jù)覆蓋掉舊的數(shù)據(jù)。
- 無需額外處理,插件會(huì)自己更新到最新數(shù)據(jù)。
進(jìn)階用法(按需持久化所需數(shù)據(jù))
需求:不想所有數(shù)據(jù)都持久化處理,能不能按需持久化所需數(shù)據(jù),怎么辦?
可以用配置式寫法,按需緩存某些模塊的數(shù)據(jù)。
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state: () => {
return {
someState: 'hello pinia',
nested: {
data: 'nested pinia',
},
}
},
// 所有數(shù)據(jù)持久化
// persist: true,
// 持久化存儲插件其他配置
persist: {
// 按需存儲 state/ref
// 修改存儲中使用的鍵名稱,默認(rèn)為當(dāng)前 Store的 id
key: 'storekey',
// 修改為 sessionStorage,默認(rèn)為 localStorage
storage: window.sessionStorage,
// ??按需持久化,默認(rèn)不寫會(huì)存儲全部
paths: ['nested.data'],
},
})
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue中watch監(jiān)聽第一次不觸發(fā)、深度監(jiān)聽問題
這篇文章主要介紹了Vue中watch監(jiān)聽第一次不觸發(fā)、深度監(jiān)聽問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10
前端框架Vue父子組件數(shù)據(jù)雙向綁定的實(shí)現(xiàn)
Vue項(xiàng)目中經(jīng)常使用到組件之間的數(shù)值傳遞,實(shí)現(xiàn)的方法很多,但是原理上基本大同小異。這篇文章將給大家介紹Vue 父子組件數(shù)據(jù)單向綁定與Vue 父子組件數(shù)據(jù)雙向綁定的對比從而認(rèn)識雙向綁定2021-09-09
element ui el-date-picker組件默認(rèn)值方式
這篇文章主要介紹了element ui el-date-picker組件默認(rèn)值方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Vue+Element UI+Lumen實(shí)現(xiàn)通用表格分頁功能
這篇文章主要介紹了Vue+Element UI+Lumen實(shí)現(xiàn)通用表格分頁功能,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-02-02
vue.js實(shí)現(xiàn)只能輸入數(shù)字的輸入框
這篇文章主要為大家詳細(xì)介紹了vue.js實(shí)現(xiàn)只能輸入數(shù)字的輸入框,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10
Vue使用Intersection?Observer檢測元素是否展示
Intersection?Observer?是一個(gè)瀏覽器原生的?API,用于異步觀察目標(biāo)元素與其祖先元素或頂部視口之間的交叉狀態(tài)變化,本文就來聊聊如何使用Intersection?Observer檢測元素是否展示吧2024-11-11
vue項(xiàng)目element?UI?版本升級過程遇到的問題及解決方案
這篇文章主要介紹了vue項(xiàng)目element?UI?版本升級過程遇到的問題及解決方案,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
vue發(fā)送驗(yàn)證碼計(jì)時(shí)器防止刷新實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了vue發(fā)送驗(yàn)證碼計(jì)時(shí)器防止刷新實(shí)現(xiàn)詳解,<BR>有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
vue2.6.10+vite2開啟template模板動(dòng)態(tài)編譯的過程
這篇文章主要介紹了vue2.6.10+vite2開啟template模板動(dòng)態(tài)編譯,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-02-02

