Pinia是基于Vue 3的Composition API构建的,这使得它更加灵活和可组合。它比vuex更加轻量级,更容易入手、更灵活。但是vuex相比pinia更加成熟、更加稳定、更加强大。如果你的项目不是很繁琐,或者使用vuex比较费劲不防试用下pinia。
安装
npm install pinia
创建pinia文件
和vuex的index.js目录一样,自己可以选择文件加创建,只要引入路径正确就可以。
import { defineStore } from 'pinia' //引入pinia
// 参数1 :dong是应用程序中store的唯一id,不能重复
export const useStore = defineStore("dong", {
state: () => ({
msg: "这是pinia的数据",
name: "豆豆",
age: 10,
count: 10,
hero: {
name: "vn",
type: "adc",
}
}),
// 类似于计算属性
getters: {
addCount: (state) => {
return state.count * 2
}
},
// 可以异步
actions: {
increment() {
this.count++
},
},
})
main.js引入
import {
createApp
} from "vue";
import App from "./App.vue";
import router from "./router";
// 引入pinia
import { createPinia } from "pinia";
// 引入elementPlus
import ElementPlus from "element-plus";
import 'element-plus/dist/index.css'
import locale from 'element-plus/lib/locale/lang/zh-cn'
const app = createApp(App);
app.use(router);
app.use(createPinia());
app.use(ElementPlus, {
locale
});
app.mount("#app");
在组件中使用
首先我们需要引入pinia创建的js文件
// 引入store
import {useStore} from "@/pinia/index.js"
const store = useStore()
读写
直接store.name 就可以获取store里的值
getters里的值也是一样的,如果出现没有变化的情况 可以配合computed 使用
<p>{{store.name}}--{{store.msg}}</p>
调用actions方法
store.increment()
或者直接在标签里调用
<el-button type="primary" @click="store.increment()">调用</el-button>
完整代码
<template>
<div class="dong">
<h2>pinia的使用</h2>
<h3 class="h3">state 读和写</h3>
<p>{{store.name}}--{{store.msg}}</p>
<el-button type="primary" @click="stateSet1">写一个</el-button>
<el-button type="primary" @click="stateSet2">写多个</el-button>
<p>{{store.name}}---{{store.age}}</p>
<hr />
<h3 class="h3">getters使用 直接store.addCount</h3>
<p>{{store.count}}</p> <el-button type="primary" @click="stateSetCount">修改</el-button>
<p>*2 {{store.addCount}}</p>
<hr>
<h3 class="h3">actions使用 直接@click="store.increment()" 可以执行一部</h3>
<el-button type="primary" @click="store.increment()">调用</el-button>
<p>{{store.count}}</p>
<hr>
<h3 class="h3">订阅Store内数据的变化 $subscribe</h3>
<p>类型:{{depData.type}}</p>
<p>key:{{depData.key}}</p>
<p>newV:{{depData.newV}}</p>
<p>oldV:{{depData.oldV}}</p>
<hr>
<el-button type="primary" @click="depAddCount">count++</el-button>
<el-button type="primary" @click="resetStore">store重置</el-button>
<p>{{store.count}}</p>
</div>
</template>
<script setup>
import {reactive} from "vue"
// 引入store
import {useStore} from "@/pinia/index.js"
const store = useStore()
// 修改state信息
// 修改单个
const stateSet1 = ()=>{
// 修改单个
store.name = "熊猫"
console.log(store)
}
// 修改多个
const stateSet2 = ()=>{
store.$patch({
name: "大象",
age:"45",
msg:"我是$patch改变的"
})
}
// 修改count getters反应
const stateSetCount = ()=>{
store.count = 40
}
let depData = reactive({
key:"",
newV:"",
oldV:"",
type:""
})
//订阅Store内数据的变化
store.$subscribe((mutations, state) => {
console.log(mutations)
depData.type = mutations.type
// 修改单个和修改多个不一样
if(mutations.type == "direct"){
depData.key = mutations.events.key
depData.newV = mutations.events.newValue
depData.oldV = mutations.events.oldValue
}
});
// addcount++
const depAddCount = ()=>{
store.count++
}
// reset 重置到默认值
const resetStore = ()=>{
store.$reset()
}
</script>
<style lang="less" scoped>
.dong{
width: 100%;
height: 100%;
background: #fff;
font-size: 18px;
.h3{
font-size: 20px;
}
}
</style>