文章目录
一、安装
- npm:
> npm install pinia
- yarn:
> yarn add pinia
如果没有安装 yarn ,可以点击此处
二、项目引入
// 文件:main.ts 或 main.js
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");
把代码块内容复制到目标文件里面就好
三、Store
创建
// 文件:/src/store/user.js
import { defineStore } from 'pinia'
// 第一个参数是应用程序中 store 的唯一 id
// 定义store的固定格式为 usexxxStore
export const useUsersStore = defineStore('users', {
// 其它配置项
})
- 在项目src目录下新建store文件夹,用来存放我们创建的各种store,然后在该目录下新建user.ts文件,主要用来存放与user相关的store。
- 第一个参数是应用程序中 store 的唯一 id
- 定义store的固定格式为 usexxxStore ,xxx: 通常为第一个参数
使用
<script setup>
// 引入函数
import { useUsersStore } from "../store/user";
// 创建函数实例
const store = useUsersStore();
console.log(store);
</script>
四、属性
state
创建
import { defineStore } from 'pinia'
export const useUsersStore = defineStore("users", {
state: () => {
return {
name: "小张",
age: 25,
sex: "男",
};
},
});
使用
<template>
<h1>直接调用</h1>
<p>姓名:{{ store.name }}</p>
<p>年龄:{{ store.age }}</p>
<p>性别:{{ store.sex }}</p>
<h1>解析后使用</h1>
<p>姓名:{{ store.name }}</p>
<p>年龄:{{ store.age }}</p>
<p>性别:{{ store.sex }}</p>
</template>
<script setup >
// 引入函数
import { useUsersStore } from "../store/user";
// 引入 storeToRefs 函数
import {storeToRefs} for 'pinia'
// 创建实例
const store = useUsersStore();
// 需要用 storeToRefs 进行解析,否则会失去响应式
// 等同 vue 中的 toRefs()
const { name, age, sex } = storeToRefs(store);
console.log(store.$state)
</script>
- 如果我们想要修改store中的数据,可以直接重新赋值即可
- 如果在 script 标签里面调用,需要在调用 属性/函数 前面加 $
注意: 你不能完全替换掉 store 的 state,因为那样会破坏其响应性
方法
// 重置store
store.$reset()
// 批量修改数据
store.$patch({
name: "张三",
age: 100,
sex: "女",
});
// $patch 方法也接受一个函数来组合这种难以用补丁对象实现的变更。
cartStore.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
// 替换整个state对象
store.$state = {
counter: 666,
name: '张三'
}
// 你不能完全替换掉 store 的 state,因为那样会破坏其响应性。但是,你可以 patch 它。
// 这实际上并没有替换`$state`
store.$state = { count: 24 }
// 在它内部调用 `$patch()`:
store.$patch({ count: 24 })
getter
创建
import { defineStore } from 'pinia'
export const useUsersStore = defineStore("users", {
state: () => {
return {
name: "小张",
age: 25,
sex: "男",
};
},
getters: {
// 如果需要 state 中的值,需要把 state当参数传进去
getAddAge: (state) => {
return state.age + 100;
},
},
});
- 可以理解成 vue 中的 计算属性
- 推荐使用 箭头函数
- 默认接收 state 做为第一个参数
- getters 内函数本身不接收参数,可以通过返回一个函数来接收参数,但此getter将不被缓存
- 在setup组件内可以像访问state属性一样访问getter
// 如果用 this 调用,需要改为函数
getNum:function() {
return + this.age + 100;
}
注意: 如果需要 state 中的值,需要把 state当参数传进去
使用
<template>
<p>新年龄:{{ store.getAddAge }}</p>
</template>
<script setup>
import { useUsersStore } from "../src/store/user";
const store = useUsersStore();
</script>
getter中调用其他getter
export const useUsersStore = defineStore("users", {
state: () => {
return {
name: "小张",
age: 25,
sex: "男",
};
},
getters: {
getAddAge: (state) => {
return state.age + 100;
},
// js
getNameAndAge: function(){
return this.name + this.getAddAge; // 调用其它getter
},
// ts
getNameAndAge(): string {
return this.name + this.getAddAge; // 调用其它getter
},
},
});
getter传参
export const useUsersStore = defineStore("users", {
state: () => {
return {
age: 25,
};
},
getters: {
getAddAge: (state) => {
return (num) => state.age + num;
},
},
});
如需要传参需要在 return 里面添加一个 箭头函数 进行传参
actions
创建
import { defineStore } from 'pinia'
export const useUsersStore = defineStore("users", {
state: () => {
return {
name: "小张",
};
},
actions: {
saveName(name) {
this.name = name;
},
},
});
- 可以理解为 vue 中的 methods
- 可以通过 this 访问整个 store 实例
- 我们可以在这个方法做一些事情,如:修改 state 里的值
- 可以在一个actions内直接访问其它store的actions
使用
<template>
<button @click="saveName">点击之后修改name</button>
</template>
<script setup>
import { useUsersStore } from "../src/store/user";
const saveName = () => {
store.saveName("我是小张");
};
</script>
五、Pinia-模块化
创建
// 文件:store/user.js 用户文件
import { defineStore } from 'pinia'
const userStore = defineStore("user", {
state: () => {
return {
name: "小张",
};
},
});
export default userStore
// 文件: store/goods.js 商品文件
import { defineStore } from 'pinia'
const userStore = defineStore("goods", {
state: () => {
return {
name: "玩具",
};
},
});
export default userStore
// 文件: store/index.js 主文件
// 把需要的 store 文件引入
import user from "./user";
import goods from "./goods";
// 统一使用 usersStore 方法
export default function usersStore() {
return {
// 必须要函数形式调用一下
user:user(),
goods:goods()
}
}
- 把一个 Store 放在一个文件里面
- 之后创建一个主文件一起导出
使用
<template>
<div id='item'>
<h1>{{ user.name }}</h1>
<h1>{{ goods.name }}</h1>
</div>
</template>
<script setup>
// 引入 主文件
import usersStore from '../store'
// 解析成单个的 Store 文件
const { user, goods } = usersStore()
</script>
<style scoped>
/* #item { } */
</style>
六、Pinia-持久化存储
安装
- npm:
> npm install pinia-plugin-persistedstate
- yarn
> yarn add pinia-plugin-persistedstate
- pnpm:
> pnpm install pinia-plugin-persistedstate
创建
// 文件 main.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
- 需要先在 main.js 文件中注册
使用
import { defineStore } from 'pinia'
const usersStore = defineStore("goods", {
state: () => {
return {
name: "苹果",
price: '14'
};
},
// 所有数据持久化
persist:true
});
export default usersStore;
- 默认会将数据存储到本地
属性
import { defineStore } from 'pinia'
const usersStore = defineStore("goods", {
state: () => {
return {
name: "苹果",
price: '14'
};
},
persist: {
// enabled :数据是否持久化
// 参数: true false
enabled: true,
// key: 存储的名字,默认为当前 Store的 id
key: 'goods',
// strategies: 存储数据的位置,默认为 localStorage
// 参数:localStorage sessionStorage,
strategies: sessionStorage,
// paths : 表示数据持久状态的数组。
// 参数:
// []: 表示没有数据被持久化
// undefined或null: 表示整个数据被持久。
// ['name']: 表示只将 name 数据持久化
paths: []
}
});
export default usersStore;
按需存储数据位置
import { defineStore } from 'pinia'
const userStore = defineStore("goods", {
state: () => {
return {
fruit: "苹果",
price: '14'
};
},
persist: {
enabled: true,
key: 'goods',
strategies: [
{ key: 'fruit', storage: sessionStorage, paths: ['fruit'] },
{ key: 'price', storage: localStorage, paths: ['price'] }
],
}
});
export default userStore;