前言
Vue2的时候,Vuex可以说是必备的,它作为一个状态管理工具,给我们带来了极大的 方便,Vue3推出后,虽然相对于Vue2很多东西都变了,但是核心的东西还是没有太大的变化。
优点
- Vue2和Vue3都支持,这让我们同时使用Vue2和Vue3的前端同学都能很快上手。
- pinia中只有state、getter、action,不需要用到Vuex中的Mutation。
- pinia中action支持同步和异步,Vuex不支持。
- 同时支持Typescript,毕竟我们Vue3都推荐使用TS来编写。
- 无需创建各个模块嵌套,pinia中的每个store都是独立的,互相不影响
内容
安装依赖
yarn add pinia
# 或者使用 npm
npm install pinia
main.js
import { createPinia } from 'pinia'
app.use(createPinia())
actiondemo.js
import { defineStore } from 'pinia'
export const useActionStore = defineStore('action', {
state: () => ({
counter: 3,
count:0
}),
actions: {
increment() {
this.counter++;
},
incrementTrad(val) {
this.count += val;
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
},
})
counter.js
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return { count, doubleCount, increment }
})
main.js
import { defineStore } from 'pinia';
import { useCounterStore } from './counter';
export const useStore = defineStore('main', {
state: () => {
return {
counter: 0,
users: [
{ id: 1, name1: "123+" ,active:true},
{ id: 2, name2: "456+" ,active:false},
{ id: 3, name3: "789+" ,active:true }]
}
},
getters: {
// 箭头函数
doubleCount: (state) => state.counter * 2,
// 普通函数
doubleCountPlusOne() {
// 自动完成 ✨
return this.doubleCount + 1
},
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
getActiveUserById(state) {
const activeUsers = state.users.filter((user) => user.active)
return (userId) => activeUsers.find((user) => user.id === userId)
},
otherGetter(state) {
const cunterStore = useCounterStore()
return state.counter + cunterStore.count
},
},
})
store.js
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
// 推荐使用 完整类型推断的箭头函数
state: () => {
return {
// 所有这些属性都将自动推断其类型
counter: 0,
name: 'Eduardo',
isAdmin: false,
items:['太','美']
}
},
})
demo.vue
<script setup>
import { storeToRefs } from "pinia";
import { useStore } from "../stores/store.js";
const store = useStore();
console.log(store);
let { counter, name, isAdmin ,items} = storeToRefs(store) ;
// 修改
const changeMyName = () => {
name.value = "我替换了!!!";
};
// 重置
const resetStore=()=>{
store.$reset()
}
const allChange=()=>{
// 第一种
store.$patch({
// counter:counter.value+1+'我是修改1',
counter:counter.value+1,
name:'我是修改2'
})
// 第二种
// store.$patch((state) => {
// state.items.push('我是添加');
// state.isAdmin = true;
// });
}
// 通过赋值一个对象替换对应的属性
const stateChange = () => {
store.$state = { counter: 666, name: "Paimon" };
};
store.$subscribe((mutation, state) => {
console.log(state, "subscribe");
// 每当它发生变化时,将整个状态持久化到本地存储
localStorage.setItem("store", JSON.stringify(state));
});
</script>
<template>
<div>
<h1>pinia数据的调用</h1>
<div>{{ counter }}</div>
<div>{{ name }}</div>
<div>{{ isAdmin }}</div>
<button @click="changeMyName">修改name</button>
<button @click="resetStore">重置所有内容</button>
<button @click="allChange">批量修改</button>
<button @click="stateChange">整体替换一个store</button>
<div v-for="(i, index) in items" :key="index">{{ i }}</div>
</div>
</template>
demo_two.vue
<script setup>
import { onMounted, getCurrentInstance } from "vue";
import { storeToRefs } from "pinia";
import { useStore } from "../stores/main";
import { useActionStore } from "../stores/actiondemo";
const store = useStore();
const actionStore = useActionStore();
let { counter, count } = storeToRefs(actionStore);
const requestChange = () => {
getGroomList().then((res) => {
console.log(res);
});
};
const addOne = () => {
actionStore.increment();
};
const addOneTradition = () => {
actionStore.incrementTrad(2);
};
console.log(store.doubleCount, "doubleCount");
console.log(store.doubleCountPlusOne, "doubleCountPlusOne");
console.log(store.getUserById(2), "getUserById");
console.log(store.getUserById(1), "getactiveUsers");
console.log(store.getActiveUserById(1), "getActiveUserById");
console.log(store.otherGetter, "otherGetter");
</script>
<template>
<div>
<div>demo_two</div>
<div>
<button @click="requestChange">发起请求</button>
<h1>action</h1>
<div>{{ counter }}</div>
<div>{{ count }}</div>
<button
@click="
addOne();
addOneTradition();
"
>
加1
</button>
</div>
</div>
</template>
这种组合式编程的思想更重要,pinia无非就是以下3个大点:
- state
- getters
- actions