Pinia.js 有如下特点:
- 完整的 ts 的支持;
- 足够轻量,压缩后的体积只有1kb左右;
- 去除 mutations,只有 state,getters,actions;
- actions 支持同步和异步;
- 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
- 无需手动添加 store,store 一旦创建便会自动添加;
- 支持Vue3 和 Vue2
官方文档:Piniahttps://pinia.vuejs.org/
1、在vue3项目中安装
yarn add pinia
npm install pinia
2、vue3中引入使用
import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from 'pinia'
const store = createPinia()
let app = createApp(App)
app.use(store)
app.mount('#app')
3、在vue2中使用
import { createPinia, PiniaVuePlugin } from 'pinia'
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
new Vue({
el: '#app',
// other options...
// ...
// note the same `pinia` instance can be used across multiple Vue apps on
// the same page
pinia,
})
在项目中如何使用
1、在src新建store目录,src/store/user.ts
创建Names.ts用来定义仓库的name 也是id 唯一
names.ts
export const enum Names {
User = "USER",
Test = "TEST"
}
user.ts
import { defineStore } from 'pinia'
import { Names } from "./Name"
// name 名称 也是id,是必要的 Pania 使用它来将商店连接到 devtools。将返回的函数命名为use...是可组合项之间的约定,以使其使用习惯。
export const useUserStore = defineStore(Names.User, {
// state 箭头函数 返回一个对象在对象里面定义
state: () => {
return {
userName: '张三三',
age: 18
}
},
// computed 修饰一些值
getters: {
},
// methods 可以做同步 异步都可以 提交state
actions: {
setAge(num: number) {
this.age = num
}
}
})
2、在组件中使用,修改state的5中方法
usePinia.vue
<template>
<div>
<h1>我是pinia:{{ userStore.userName }}--{{ userStore.age }}</h1>
<button @click="changeState">change-state</button>
</div>
</template>
<script setup lang="ts">
import { useUserStore } from '../../Store/user'
// 使用pinia
const userStore = useUserStore()
// 修改state的5中方法
/* //方式一:userStore.age++
let changeState = () => {
userStore.age++
}
*/
/* //方法二:userStore.$patch({userName: '我是沙雕',age: 58})
let changeState = () => {
userStore.$patch({ userName: '我是沙雕', age: 58 })
}
*/
/* // 方法三:工厂函数方式
let changeState = () => {
userStore.$patch((state) => {
// 处理逻辑后修改
state.age++
if (userStore.age > 20) {
state.userName = '你是一个美女'
}
state.age = userStore.age
})
}
*/
/* // 方案四:$state您可以通过将store的属性设置为新对象来替换store的整个状态 缺点就是必须修改整个对象的所有属性
// 一般使用不多
let changeState = () => {
userStore.$state = {
age: 388,
userName: '修改了张三'
}
}
*/
// 方案五: 定义Actions 在actions 中直接使用this就可以指到state里面的值
let changeState = () => {
userStore.setAge(789)
}
</script>
<style scoped>
</style>
3、pinia直接解构会导致失去响应性的
let { userName, age } = userStore
let changeState = () => {
userStore.age++
}
console.log(userName,age)
修改userStore.age的值,元数据会改变的,但是解构的userName,age不会改变,由于解构失去了响应性
4、可以使用storeToRefs 解决由于解构失去的响应性
// 使用 storeToRefs 可以解决因为解构导致失去的响应性
let { userName, age } = storeToRefs(userStore)
console.log("解构", userName, age)
let changeState = () => {
userStore.age++
}
其原理跟toRefs 一样的给里面的数据包裹一层toref
源码 通过toRaw使store变回原始数据防止重复代理
循环store 通过 isRef isReactive 判断 如果是响应式对象直接拷贝一份给refs 对象 将其原始对象包裹toRef 使其变为响应式对象
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)