pinia快速上手使用

安装

yarn add pinia
// 或者使用 npm
npm install pinia

在main.ts中挂载到应用上:

import { createApp } from 'vue'
import { createPinia } from 'pinia' //主要代码

import App from '@/App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia()) //主要代码
app.use(router)

app.mount('#app')

定义store

注意:action 可以是异步的,你可以在它们里面 await 调用任何 API,以及其他 action

src目录下创建 stores 目录,用于存储 store,如下:
在这里插入图片描述
counter.ts:

import { ref, computed } from 'vue'
import { defineStore } from 'pinia'

//defineStore():
//第一个参数:独一无二的名字,storeId
//第二个参数:函数或对象
export const useCounterStore = defineStore('counter', () => {
/**
 * ref() 就是 state 属性
 * computed() 就是 getters
 * function() 就是 actions,action中可以使用异步函数
 */
 	//state:
 	const count = ref(0)
 	const name = ref('')
 	//getter:
 	const getCount = computed<number>(() => {
		return count.value
	})
	//actions:
	const increment = () => {
		count.value++
	}
	const updateName = async (val: string) => {
		try {
			//demoPromise 是一个 promise
			name.value = await demoPromise(val)
		} catch (error) {
			return error
		}
	}
	//暴露state、computed、actions;否则无法使用
	return {count,getCount,increment,updateName }
})

使用Store

  1. <script setup>调用useStore()之前,store 实例是不会被创建的
  2. store是一个用reactive包装的对象,这意味着不需要使用 .value

使用方法:

//在模板中使用:
<template>
	<h1>pinia的使用</h1>
	<h2>count:{{ store.count }}---{{ store.getCount }}</h2>
	<h2>name:{{ store.name }}</h2>
	<button @click="store.increment">使用store自带的方法使count递增</button>
</template>
//在<script setup> 中使用:
import { useCounterStore } from '@/stores/counter'
const store = useCounterStore()
const handleIncrement = () => {
//直接更改state,不通过action:
	store.count++
//通过action修改state:
	increment()
}

解构store

错误的用法:

//count 的响应式被破坏,无论如何更改都不会变,始终保持初始值
const { count } = store

正确的用法:

  • 使用 storeToRefs() 不会破坏响应式,它会为每一个响应式属性创建引用
  • storeToRefs() 只能解构出 state、getter;不能解构 action
  • storeToRefs() 解构出来的state、getter需要使用 .value 获取值
  • action 可以直接被解构,无需使用任何工具
const { name, count } = storeToRefs(store)
const { increment } = store
const interval = setInterval(() => {
	name.value += '=='
	count.value++
}, 2000)
setTimeout(() => {
	clearInterval(interval)
}, 10000)

重置state

store.$reset()

变更state

  1. 方法一:store.count++
  2. 方法二:action
  3. 方法三:store.$patch()

$patch(): 可以传递一个函数或对象;主要用于同一事件改变多个属性

const handleUpdate = () => {
	store.$patch({
		age: 30,
		address: '美国',
	})
}
const handleUpdateList = () => {
	store.$patch(state => {
		state.list.push('my')
		state.flag = true
	})
}
// 实际上并没有替换`$state`
store.$state = { count: 24 }

监听state — $subscribe()

  1. $subscribe()监听state的变化,通过 $patch() 一次改变多个数据,$subscribe() 只会被触发一次
  2. 第一个参数:监听回调
  3. 第二个参数(可选):配置对象,如{detached: true}(此订阅器即便在组件卸载之后仍会被保留)
store.$subscribe(
	(mutation, state) => {
		/**
		 * mutation.type:
		 * 'direct':正常修改,如count++、increment()
		 * 'patch object':$patch(对象)
		 * 'patch function':$patch(函数)
		 *
		 * mutation.storeId: 使用defineStore()定义store中的id,如:defineStore
		 * 
		 * mutation.payload:
		 *  只有 mutation.type === 'patch object'的情况下才可用,$patch() 的补丁对象
		 */
		console.log(mutation)
	},
	{
		// detached: true, //此订阅器即便在组件卸载之后仍会被保留
	}
)

监听 action — $onAction()

  1. 监听器会被绑定到添加它们的组件上(如果 store 在组件的 setup() 内)
  2. 当组件被卸载时,它们也会被自动删除
  3. $onAction中的回调函数会在action 本身之前执行
  4. 第一个参数:监听回调
  5. 第二个参数(可选):false – 组件卸载后,监听器自动删除;true — 组件卸载后,监听器仍然保留
let actionCounter = ref(0)
// name: action名称
// store:store实例,类似someStore
// args:传递给action的参数数组
// after:在action 返回或解决后的钩子
// onErro:action 抛出错误或 reject 时执行一个回调函数
const onAction = store.$onAction(({ name, store, args, after, onError }) => {
	actionCounter.value++
	console.log(name)
	console.log(store)
	console.log(args)
	const startTime = Date.now()
	console.log('触发时间:', startTime)
	after(result => {
		console.log('结束时间:', Date.now())
	})
	onError(error => {
		console.warn('发生错误的时间:', Date.now())
	})
})
watch(actionCounter, () => {
	// 手动删除监听器
	console.log('删除侦听器')
	onAction()
})
// 此订阅器即便在组件卸载之后仍会被保留
store.$onAction(() => {}, true)

手动删除监听器:
onAction()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值