持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第2天,点击查看活动详情 当Vue3成为正式版后,pinia作为一个全新的状态管理库是尤大主要强推的项目, 还有就是与vuex相比较来说pinia拥有了更简单的api,更少的规范等等。 这也是我为什么来学习的原因啦~ 虽然算不上尤大的粉,但也是我的崇拜者~😜
pinia 优点
1、支持vue2、vue3;
2、抛弃mutations操作,只有state、getters和actios;
3、不需要嵌套模块,符合Vue3 的Composition api;
4、完整的ts支持;
5、代码简洁;
使用
-
所用技术栈:
vue3 + ts + vite构建基础上使用pinia -
安装:
yarn add pinia -
创建文件
src目录下创建store文件夹s
tore文件夹中创建index.ts文件 -
目的: 定义状态容器和数据、修改容器中的
state、仓库中action的使用 -
用法:
index.ts文件中需要从pinia中引入defineStore1、
defineStore需要传递两个参数 id名称(string类型) 、 配置项(Obiect类型)2、
id名称必填,不然会报错3、配置项是一个对象,其中有以下属性
export const mainStore = defineStore('main', { state: () => { return {} }, geeters: {}, actions: {} })①
state: 定义需要被监听的数据变化②
getters:计算属性 计算属性存在缓存的,当多次调用未修改的数据,其实getters里面是只调用了一次的(比较好的性能优化)③
actions:可以在里面写复杂的逻辑业务 -
改
store中数据的几种方式:
在需要使用这些数据的页面里面进行操作
首先需要利用storeToRefs将store里面的数据解构为响应式数据
import {mainStore} from './store/index'
import {storeToRefs} from 'pinia' // 利用storeToRefs将store里面的数据解构为响应式数据
const store = mainStore();
const {helloWord, count, phoneHide} = storeToRefs(store);
1、直接对store中数据进行修改
let handleAdd = () => {
store.count++; // 改变的是状态数据
store.helloWord = store.helloWord === 'jxx' ? 'hello word' : 'jxx';
}
2、 通过$patch传递对象进行多数据修改。其实也可以通过第一种方式对数据进行改变,不过官方给出的建议是在进行多数据改变的时候尽量使用此方法,因为此方法是经过官方优化的。
let handlePatch = ()=> {
store.$patch({
count:store.count+2,
helloWord: store.helloWord === 'jxx' ? 'hello word' : 'jxx'
})
}
3、使用$patch 传递函数 常用于处理复杂逻辑
let handleMethod = () => {
store.$patch((state) => { // state为数据仓库中的state
state.count++;
state.helloWord = state.helloWord === 'jxx' ? 'hello word' : 'jxx';
})
}
4、通过store中的actions 常用于业务逻辑及其复杂,需要写在actions里面
actions: {
// 不能使用箭头函数,this会指向最外层
handleAction() {
this.count++;
this.helloWord = 'jxx' ? 'hello word' : 'jxx';
}
}
具体代码
main.ts的代码
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
const pinia = createPinia()
const app = createApp(App);
app.use(pinia);
app.mount('#app')
index.ts文件
import {defineStore} from 'pinia'
// defineStore 需要传递两个参数 id名称 、 配置项
export const mainStore = defineStore('main', {
state: () => { // 定义数据
return {
helloWord: 'hello word',
count: 0,
phone: '15639549985',
}
},
getters: {// 计算属性 是有缓存的 如果多次调用数据并没有改变 那么其实是只调用一次的(性能优化)
phoneHide(state) { // 如果不传state,那么通过this也是可以获取phone的值的 但是ts无法对数据类型进行推导会报错 解决:phoneHide(): String {}
return state.phones.toString().replace(/^(\d{3})\d{4}(\d{4})$/,'$1****$2')
}
}, // 监听数据变化
// 4、第四种 业务逻辑及其复杂,需要写在actions里面
actions: {
// 不能使用箭头函数,this会指向最外层
handleAction() {
this.count++;
this.helloWord = 'jxx' ? 'hello word' : 'jxx';
}
}
})
App.vue中测试一下
<template>
<div>
<div>{{helloWord}}</div>
<button @click="handleAdd()">+</button>
<button @click="handlePatch()">+2</button>
<button @click="handleMethod()">+1</button>
<button @click="handleActions()">+1actions</button>
<div>{{count}}</div>
<div>{{phoneHide}}</div>
</div>
</template>
<script setup lang="ts">
import {mainStore} from './store/index'
import {storeToRefs} from 'pinia' // 利用storeToRefs将store里面的数据解构为响应式数据
const store = mainStore();
const {helloWord, count, phoneHide} = storeToRefs(store);
// 状态值修改的几种方式
// 1、第一种
let handleAdd = () => {
store.count++; // 改变的是状态数据
store.helloWord = store.helloWord === 'jxx' ? 'hello word' : 'jxx';
}
// 2、第二种$patch 传递对象
// 好处:多数据修改(官方给出此方法经过优化,适用于多数据改变)
let handlePatch = ()=> {
store.$patch({
count:store.count+2,
helloWord: store.helloWord === 'jxx' ? 'hello word' : 'jxx'
})
}
// 3、第三种$patch 传递函数 常用于处理复杂逻辑
let handleMethod = () => {
store.$patch((state) => { // state为数据仓库中的state
state.count++;
state.helloWord = state.helloWord === 'jxx' ? 'hello word' : 'jxx';
})
}
// 4、第四种 通过actions
let handleActions = () => {
store.handleAction()
}
</script>
<style lang="scss">
</style>