了解什么是pinia
1、Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。
2、一般情况下vue2用vuex,vue3用pinia,当然vue2也能用pinia。
Pinia 对比 Vuex
1、vuex核心概念:state、mutations、actions、getters、modules
2、pinia核心概念:state、actions、getters
3、pinia能更好的支持TypeScript的使用
4、pinia已经舍弃了mutation的这个用法,为了更方便理解和维护代码
一、安装
npm install pinia
// or
yarn add pinia
二、创建store目录--管理数据
创建store文件夹中的index.js文件引入创建pinia,抛出全局使用
//创建大仓库
import { createPinia } from 'pinia';
//createPinia方法可以用于创建大仓库
let store = createPinia();
//对外暴露,安装仓库
export default store;
三、在 main.ts 中引入
// 引入实例化上下文的api方法createApp
import { createApp } from 'vue'
// 引入App组件
import App from './App.vue'
//引入仓库
import store from './store'
// 创建app
const app = createApp(App)
app.use(store)
// 挂载
app.mount('#app');
四、创建modules目录--info.ts/info.js(pinia有两种用法)
在store目录下创建modules,方便管理不同功能块的数据
(1)、选择器API(用法一)
1、State 是 store 中存储数据的地方。通过定义 State,可以在 store 的任何位置访问和修改数据。
2、Getter 用来获取从 state 派生的数据,类似于 Vue 组件中的 computed 计算属性,可以通过 defineStore() 中的 getters 属性来定义它们。
3、Action 相当于组件中的方法,可以通过 defineStore() 中的 actions 属性来定义。
1、pinia在info.ts文件写法
//定义info小仓库
import { defineStore } from "pinia";
//第一个仓库:小仓库名字 第二个参数:小仓库配置对象
//defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库数据
let useInfoStore = defineStore("info", {
//存储数据:state,注意这里是函数和vuex不一样
state: () => {
return {
count: 99,
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
actions: {
//注意:函数没有context上下文对象
//没有commit、没有mutations去修改数据
updateNum(a: number) {
this.count += a;
}
},
getters: {
total() {
let result:any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
});
//对外暴露方法
export default useInfoStore;
2、在 vue 文件中使用
<template>
<div class="child">
<h1>{{ infoStore.count }}---{{infoStore.total}}</h1>
<button @click="updateCount">点击我修改仓库数据</button>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
console.log(infoStore);
//修改数据方法
const updateCount = () => {
//仓库调用自身的方法去修改仓库的数据
infoStore.updateNum(66);
};
</script>
3、假如 state 中有多个数据(拓展用法)
state: () => {
return {
count: 100,
name:'张三'
}
需要引入 storeToRefs,将结构的数据转为响应式
<template>
<div>
<h1>{{ name }}</h1>
<h1>{{ count }}</h1>
<button @click="handleChange">+20</button>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
import { storeToRefs } from 'pinia'
const mainStore = useInfoStore ()
// 直接结构得到的并非响应式数据
// const { count , name} = mainStore
// 用 pinia 的 storeToRefs包裹后,结构出来就是响应式的数据
const { count , name} = storeToRefs(mainStore)
const handleChange = () => {
count.value+=20
}
</script>
(2)、组合式API(用法二)
1、pinia在info.ts文件写法
//定义组合式API仓库
import { defineStore } from "pinia";
import { ref, computed,watch} from 'vue';
//创建小仓库
let useTodoStore = defineStore('todo', () => {
let todos = ref([{ id: 1, title: '吃饭' }, { id: 2, title: '睡觉' }]);
let arr = ref([1,2,3,4,5]);
const total = computed(() => {
return arr.value.reduce((prev, next) => {
return prev + next;
}, 0)
})
//务必要返回一个对象:属性与方法可以提供给组件使用
return {
todos,
arr,
total,
updateTodo() {
todos.value.push({ id: 4, title: '组合式API方法' });
}
}
});
export default useTodoStore;
在组合式api中:
ref() 就是 state 属性
computed() 就是 getters
function() 就是 actions
2、、在 vue 文件中使用
<template>
<div class="child1">
{{ infoStore.count }}
<p @click="updateTodo">{{ todoStore.arr }}{{todoStore.total}}</p>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
//引入组合式API函数仓库
import useTodoStore from "../../store/modules/todo";
let todoStore = useTodoStore();
//点击p段落去修改仓库的数据
const updateTodo = () => {
todoStore.updateTodo();
};
</script>
网友评论