【Vue3】搭建Pinia环境及其基本使用

下载

npm i pinia

引入并注册

App.vue

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
// 1. 引入
import { createPinia } from 'pinia'

const app = createApp(App)
// 2. 创建
const pinia = createPinia()
// 3. 注册
app.use(pinia)
app.mount('#app')

存储数据

Store是一个保存 状态、业务逻辑 的实体,每个组件都可以 读取、写入它。
Store有三个概念:state、getter、action,相当于组件中的:data、computed和methods。

首先创建count.ts文件,路径为 src/store/count

使用defineStore定义store,第一个参数为store名,第二个参数为配置对象。
配置对象中的state表示状态,其return的对象中是所有变量,getters可以理解为computed,actions中定义动作函数,函数中可以修改state的值。具体代码如下:

// count.ts

import { defineStore } from 'pinia'

// 定义并暴露一个store
// 命名规范同Hook
export const useCountStore = defineStore('count',{
	// 状态
	state(){
		// 声明变量
		return { sum: 6, name: '田本初', age: 23 }
	},
	// 计算(可以理解为computed)
	getters:{
		// 可以通过this修改,this就是当前store
		addAge():number{
			return this.age + 3
		},
		// 也可以通过参数state修改
		doubleSum: state => state.sum * 2
	},
	// 动作
	actions:{}
})

读取、使用数据

state中定义数据,getters可以对state中的数据进行计算,并返回一个新数据。
使用数据时有两种方式:「store.变量名」 和 「store.$state.变量名」
第一种更简洁,所以更加推荐第一种写法。

// 读取出定义时暴露出的store
import { useCountStore } from '@store/count'

const countStore = useCountStore()
// 使用state数据
<div>{{ countStore.sum }}</div> // 6
// 或者
<div>{{ countStore.$state.sum }}</div> // 6

// 使用getters数据
<div>{{ countStore.addAge }}</div> // 26
<div>{{ countStore.doubleSum }}</div> // 12

如何简便的使用数据

如下写法过于繁琐,如果只想通过 sum、name、age表达变量,需要将它们解构。

<div>{{ countStore.sum }}</div>
<div>{{ countStore.name }}</div>
<div>{{ countStore.age }}</div>

解构需要注意:由于countStore是响应式数据,不可直接解构使用其中的数据,这会使数据丢失响应式,所以需要使用 toRefs。

<template>
	<div>{{ sum }}</div>
	<div>{{ name }}</div>
	<div>{{ age }}</div>
	<div>{{ doubleSum }}</div>
</template>

<script>
	import { useCountStore } from '@store/count'
	import { toRefs } from 'vue'
	
	const countStore = useCountStore()
	// 将countStore中的全部数据变为响应式
	const { sum, name, age, doubleSum } = toRefs(countStore)
</script>

但是 toRefs 并不是最好的解决方式,它会把store中所有值全部变成响应式,如actions函数和一些其他属性。
如果只想修改store中的数据为响应式,需要使用 storeToRefs

<template>
	<div>{{ sum }}</div>
	<div>{{ name }}</div>
	<div>{{ age }}</div>
	<div>{{ doubleSum }}</div>
</template>

<script>
	import { useCountStore } from '@store/count'
	// 引入storeToRefs
	import { storeToRefs } from 'pinia'
	
	const countStore = useCountStore()
	const { sum, name, age, doubleSum } = storeToRefs(countStore)
</script>

修改数据的三种方式

方式一:修改单个数据

不同于Vuex,正如官方文档中说的「Pinia是一个更符合直觉的状态管理工具」,Pinia可以直接修改store中的数据。

<template>
	<div>{{ countStore.sum }}</div>
	// 或者
	<div>{{ countStore.$state.sum }}</div>
</template>

<script>
	import { useCountStore } from '@store/count'
	const countStore = useCountStore()
	
	// 比如当前函数直接修改store的state,可以生效
	const handler = () => {
		countStore.sum += 10
	}
</script>

方式二:批量修改数据

语法:store.$patch({变量名:新值})

<template>
	<div>{{ countStore.sum }}</div>
	<div>{{ countStore.name }}</div>
	<div>{{ countStore.age }}</div>
</template>

<script>
	import { useCountStore } from '@store/count'
	const countStore = useCountStore()
	
	const handler = () => {
		// $patch可以同时修改state中多个数据
		countStore.$patch({
			sum: 100,
			name: '田公路',
			age: 24
		})
	}
</script>

如果多次修改单个数据,会发现进行了多次修改。
在这里插入图片描述
如果是批量修改,只进行一次变更,所以需要修改多个数据时,推荐使用$patch进行批量修改。
在这里插入图片描述

方式三:通过actions进行修改

需要在store的actions中定义「动作函数」,使用数据的组件中调用该函数,如果进行相对复杂的操作,并非只修改数据,如:判断以及其他逻辑,更推荐使用actions。

定义actions函数

import { defineStore } from 'pinia'

export const useCountStore = defineStore('count',{
	state(){
		return { sum: 6, name: '田本初', age: 23 }
	},
	// 动作
	actions:{
		// this是当前store
		changeName(value){ this.name = value }
	}
})

调用函数,修改数据

<template>
	<div>{{ countStore.name }}</div>
</template>

<script>
	import { useCountStore } from '@store/count'
	const countStore = useCountStore()
	
	const handler = () => {
		// 直接调用actions中的处理函数,并传入参数
		countStore.changeName('田公路')
	}
</script>

store.$subscribe

可以理解为watch,当store中的数据发生了改变,会调用。
它接受一个函数作为参数,该函数有两个参数,分别为mutate和state,mutate是本次修改信息,state是所有数据。

store.$subscribe((mutate,state)=>{
	// 处理函数
})

组合式写法(推荐)

实际开发中更推荐使用组合式写法,Hooks写法。

定义存储数据

import { reactive } from 'vue'
import { defineStore } from 'pinia'

export const useCountStore = defineStore('count',()=>{
	// 这里的state同上述写法
	const state = reactive({sum: 6, name: '田本初', age: 23})
	// changeName相当于在actions中定义的函数
	const changeName = value => {
		state.name = value
	}
	// 一定要return
	return { state, changeName }
})

读取使用数据

import { useCountStore } from '@/store/count'
import { storeToRefs } from 'pinia'

// 读取
const countStore = useCountStore()
const { sum, name, age } = storeToRefs(countStore)

// 使用
<div>{{ sum }}</div>
Pinia 是 Vue.js 的状态管理库,它在 Vue 3 中得到了原生支持。Pinia 是基于 Composition API 设计的,相比于 Vue 2 的 Vuex,Pinia 更简洁、更容易使用,并且拥有了更好的 TypeScript 支持。 要使用 Pinia,首先需要安装它: ```bash npm install pinia ``` 然后,在你的 Vue 3 应用中引入并使用 Pinia: ```javascript import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) // 创建 Pinia 实例 const pinia = createPinia() // 将 Pinia 实例添加到 Vue 应用中 app.use(pinia) app.mount('#app') ``` 接下来,你可以定义你的 store。一个基本的 Pinia store 包含了状态、getters、actions 和选项: ```javascript // src/stores/counter.js import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => { return { count: 0 } }, getters: { doubleCount: (state) => state.count * 2, }, actions: { increment() { this.count++ }, }, }) ``` 在组件中使用 store 的步骤如下: ```vue <template> <div> <p>Count is: {{ counterStore.count }}</p> <p>Double count is: {{ counterStore.doubleCount }}</p> <button @click="counterStore.increment">Increment</button> </div> </template> <script> import { defineComponent } from 'vue' import { useCounterStore } from '../stores/counter' export default defineComponent({ setup() { const counterStore = useCounterStore() return { counterStore, } }, }) </script> ``` 通过以上步骤,你可以在 Vue 3 应用中成功地使用 Pinia 进行状态管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

田本初

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值