使用pinia的原因:
pinia 它像vuex一样它允许你跨组件/页面 共享状态
相对来说比vuex更加方便 使用 piniaToRefs就可以全局快乐的让共享状态变成响应数据美滋滋
更容易的调试
- 在不重新加载页面的情况下修改您的 Store
- 在开发时保持任何现有状态
如何使用 下载嘿嘿
呀用户
yarn add pinia
or npm 用户
npm install pinia
创建一个 pinia(根存储)并将其传递给应用程序: 在vue3中
import { createApp } from "vue";
import App from "./App.vue";
import { createPinia } from "pinia";
const pinia = createPinia();
createApp(App).use(router).use(pinia).mount("#app");
在vue2中 您还需要安装一个插件并将创建的pinia注入应用程序的根目录:
import { createPinia, PiniaVuePlugin } from 'pinia'
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
new Vue({
el: '#app',
// 其他选项...
// ...
// 注意同一个 `pinia` 实例可以在多个 Vue 应用程序中使用
// 同一个页面
pinia,
})
这样就做好简单的安装拉拉
那么pinia有什么概念呢
一个Store是一个实体,它持有未绑定到您的组件树的状态和业务逻辑。这个实体可以托管全局状态
他有三个小小的概念state、getters 和 actions 并且可以安全地假设这些概念等同于组件中的“数据”、“计算”和“方法”。
state 是 store 的核心部分 我们通常从定义应用程序的状态开始(简单来说全局中的数据拉)
import { defineStore } from "pinia";
export const overViewStore= defineStore("overViewStore", {
/**
* 存储全局状态
* 1.必须是箭头函数: 为了在服务器端渲染的时候避免交叉请求导致数据状态污染
* 和 TS 类型推导
*/
state: () => {
return {
pageIndex: 0, //当前应用页面
};
},
/**
* 用来封装计算属性 有缓存功能 类似于computed
*/
getters: {},
/**
* 编辑业务逻辑 类似于methods
*/
actions: {
// 方法
changePageIndex(val){
this.pageIndex = val
}
},
});
默认情况下,您可以通过 store
实例访问状态来直接读取和写入状态:
const store = useStore()
store.pageIndex++
重置状态 您可以通过调用 store 上的 $reset()
方法将状态 重置 到其初始值:
const store = useStore()
store.$reset()
来举个例子把 在使用setup的情况下如何使用
import {overViewStore} from "@/store/useOverViewStore.js"
import {
storeToRefs
} from "pinia"
const overView = overViewStore();
//yizhong
const {pageIndex} = storeToRefs(overView);
pageIndex.value ++;
//2
overView.pageIndex++
不使用setup()
import { mapState } from 'pinia'
import { useCounterStore } from '../stores/counterStore'
export default {
computed: {
// 允许访问组件内部的 this.counter
// 与从 store.counter 读取相同
...mapState(useCounterStore, {
myOwnName: 'counter',
// 您还可以编写一个访问 store 的函数
double: store => store.counter * 2,
// 它可以正常读取“this”,但无法正常写入...
magicValue(store) {
return store.someGetter + this.counter + this.double
},
}),
},
}
可修改状态
如果您希望能够写入这些状态属性(例如,如果您有一个表单),您可以使用 mapWritableState()
代替。 请注意,您不能传递类似于 mapState()
的函数:
import { mapWritableState } from 'pinia'
import { useCounterStore } from '../stores/counterStore'
export default {
computed: {
// 允许访问组件内的 this.counter 并允许设置它
// this.counter++
// 与从 store.counter 读取相同
...mapWritableState(useCounterStore, ['counter'])
// 与上面相同,但将其注册为 this.myOwnName
...mapWritableState(useCounterStore, {
myOwnName: 'counter',
}),
},
}
订阅状态
可以通过 store 的 $subscribe()
方法查看状态及其变化,类似于 Vuex 的 subscribe 方法。 与常规的 watch()
相比,使用 $subscribe()
的优点是 subscriptions 只会在 patches 之后触发一次(例如,当使用上面的函数版本时)。
cartStore.$subscribe((mutation, state) => {
// import { MutationType } from 'pinia'
mutation.type // 'direct' | 'patch object' | 'patch function'
// 与 cartStore.$id 相同
mutation.storeId // 'cart'
// 仅适用于 mutation.type === 'patch object'
mutation.payload // 补丁对象传递给 to cartStore.$patch()
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem('cart', JSON.stringify(state))
})
Getters
Getter 完全等同于 Store 状态的 计算值。 它们可以用 defineStore()
中的 getters
属性定义。 他们接收“状态”作为第一个参数以鼓励箭头函数的使用:
export const useStore = defineStore('main', {
state: () => ({
counter: 0,
}),
getters: {
doubleCount: (state) => state.counter * 2,
},
})
有setup的
import { useCounterStore } from '../stores/counterStore'
export default {
setup() {
const counterStore = useCounterStore()
return { counterStore }
},
computed: {
quadrupleCounter() {
return counterStore.doubleCounter * 2
},
},
}
没有setUp的
import { mapState } from 'pinia'
import { useCounterStore } from '../stores/counterStore'
export default {
computed: {
// 允许访问组件内的 this.doubleCounter
// 与从 store.doubleCounter 中读取相同
...mapState(useCounterStore, ['doubleCount'])
// 与上面相同,但将其注册为 this.myOwnName
...mapState(useCounterStore, {
myOwnName: 'doubleCounter',
// 您还可以编写一个访问 store 的函数
double: store => store.doubleCount,
}),
},
}
actions说白了是可以异步的修改方法
(偷懒中不想写了)