10Pinia

Pinia

介绍

	vue专属的状态管理器,实现跨组件或页面共享状态

安装

	yarn add pinia
	npm install pinia

创建实例

vue3创建
	import {createApp} from 'App'
	import {createPinia} from 'Pinia'
	import App from './App.vue'
	coust pinia = createPinia()
	coust app = createApp(App)
	app.use(pinia)
	app.mount('#app')
vue2创建
	import {createPinia, PiniaVuePlugin} from 'Pinia'
	VUe.use(PiniaVuePlugin)
	coust pinia = createPinia()
	new Vue({
		el: '#app',
		pinia,
	})

Store

	保存状态和业务逻辑的实体,它并不是和组件树进行绑定,它承载这全局的状态,相当于一个永远存在的组件,全局的组件都可以对他实现读取与写入
	它有三个概念state、getter、action
	对应于组件的data(数据)、compured(计算属性)、methods(方法)
定义store
	store是通过defineStore()定义的
	要求: 名称唯一性
	常用写法: 返回的函数命名为use...
	import {defineStore} from 'Pinia'
	export const useAlertsStore = define('alerts', {
		// 其他配置
	})
	defineStore()第二参数接受Option对象和Setup函数

Option Store:
	export coust useCounterStore = defineStore('counter',{
		state: ()=>({count: 0}),
		getter: {
			double: (state)=> state.count * 2
		},
		actions: {
			increment() {
				this.count++
			},
		},
	})

Setup Store:
	ref() 等同于 state
	computed() 等同于 getters
	function() 等同于 actions
	export coust useCounterStore = defineStore('counter',() => {
		const count = ref(0)
		function increment() {
			count.value++
		}
		return {count increment}
	})
使用store
当通过<script setup></script>调用useStore()之前,store实例不会被创建
    <script setup>
        import { useCounterStore } from '@/stores/cpunter'
        const store = useCounterStore()
    </script>
    
当实例化后可直接访问store的state、getters、actions中定义的任何属性
例如:
	const doubleValue = computed(() => store.doubleCount)
	
但不可以通过解构的方式将store进行解构:store是一个用reactive包装的对象
错误示例:
	const {name, doubleCount} = store

为store提取属性保存响应,可使用storeToReds(),当只使用状态不调用任何action时
	<script setup>
		import { storeToRefs } from 'pinia'
		const stor = useCounterStore()
		const { name, doubleCount } = storeToRefs(store)
		// 你可以直接从 store 中解构 action,因为它们也被绑定到 store 上
		const { increment } = store
	</script>

state
使用state
state是store的核心,state被定义为一个初始化状态的函数,使得Pinia可同时支持服务端和客户端

如果使用vue2,在state中创建的数据与vue实例中的data遵循同样的规则,当你想添加新属性时需要调用Vue.set()
	import { defineStore } from 'pinia'
	const useStoreIdStore = defineStore('storeId', {
		state: ()=> {
			return {
				count: 0,
				name: 'EEEEE',
				isAdmin: false,
				items: [],
			}
		}
	})
	
TypeScript兼容
	const userStoreIdStore = defineStore('storeId', {
		state: () => {
			return {
				userList: [] as UserInfo[],
				user: null as UserInfo | null,
			}
		}
	})
	
	interface UserInfo {
		name: string
		age: number
	}
	
也可以通过接口直接定义state,并添加state的返回类型
	interface State() {
		userList: UserInfo
		user: UserInfo | null
	}
	
	const userStoreIdStore = defineStore('storeId', {
		state: (): State => {
			return {
				userList: [],
				user: null,
			}
		}
	})
	
	interface UserInfo {
		name: string
		age: number
	}
访问state
	const store = userStoreIdStore()
	store.count++
重置state
	const store = userStoreIdStore()
	store.$reset()
选项式API
通过mapState()辅助函数将state属性映射为计算属性
例如:
	import { mapState } from 'pinia'
	import { userCounterStore } from '../stores/counter'
	
	export default {
		computed: {
			// 与store.count 中读取的数据相同
			...mapState(useCounterStore, ['count'])
			// 将其注册为this.myOwnName
			...mapState(useCounterStor, {
				myOwnName: 'count',
				double: store => stor.count*2
				// 可以传递函数
				magicValue(store) {
					return: store.someGetter + this.count + this.double
				}
			})
		}
	}
	
修改state:可以通过mapWritableState()
	import { mapWritableStore } from 'pinia'
	import { useCounterStore } from '../stores/counter'
	
	export default {
		computed: {
			// 与store.count 中读取的数据相同
			...mapWritableState(useCounterStore, ['count'])
			 // 将其注册为this.myOwnName
			...mapWritableState(useCounterStor, {
				myOwnName: 'count',
				// 此处不可以传递函数
			})
		}
	}
变更state
直接改变
	例如:state.count++
	
调用$patch
	允许用一个state补丁对象同时更改多个属性
	state.$patch({
		count: state.count + 1,
		age: 120,
		name: 'DIO',
	})
	$patch 方法也接受一个函数来组合这种难以用补丁对象实现的变更
	state.$patch((state) => {
		state.items.push({name: 'shoes', quantity: 1})
		state.hasChanged = true
	})
替换state
store的state不能被完全的替换,会影响响应性
	store.$state = { count: 24 } // 此种方法实际上并没有去替换state
可以通过patch实现变更
	store.$patch({
		count: 24
	})
也可以通过变更pinia实例的state来设置整个应用的初始state
pinia.state.value = {}
监听state
$subscribe()方法可监听state变化
与watch()区别: $subscribe()在patch后只会触发一次
    carStore.$subscribe((mutation, state) => {
		 // import { MutationType } from 'pinia'
          mutation.type // 'direct' | 'patch object' | 'patch function'
          // 和 cartStore.$id 一样
          mutation.storeId // 'cart'
          // 只有 mutation.type === 'patch object'的情况下才可用
          mutation.payload // 传递给 cartStore.$patch() 的补丁对象。

          // 每当状态发生变化时,将整个 state 持久化到本地存储。
          localStorage.setItem('cart', JSON.stringify(state))
    })
    
默认情况下会绑定到添加他们的组件上,当组件卸载后,他们将自动的删除
如果想组件卸载后依旧保留可以将{detached: true}作为第二参数
	<script setup>
		const someStore = useSomeStore()
		
		someStore.$subscribe(callback, { detached: true })
	</script>
	
在pinia实例上监听整个state
watch(
	pinia.state,
	(state) => {
		localStorage.setItem('cart', JSON.stringify(state))
	}
)

Getters

定义Getters
Getters完全等同于store的state的计算值
可以在defineStore()中getters属性来定义

export const userStore  = defineStore('main', {
	 state: () => ({
	 	count: 0,
	 }),
	 getters: {
	 	doubleCount: (state) => state.count * 2,
	 },
})

getter使用其他的getter:必须定义返回类型,通过this访问整个store实例
export const userStore = defineStore('main', {
	state: () => ({
		count: 0,
	}),
	getters: {
		doubleCount(state) {
			return state.count * 2
		},
		// 返回类型必须明确设置
		doublePluOne() : number {
			return this.doubleCount + 1
		}
	}
})
使用getters
<script setup>
	import { userStore } from './counterStore'
	const store = userStore()
</script>
<template>
	<p>{{ store.doubleCount }}</p>
</template>
向getter传递参数
getter相当于计算属性,不可以向他们取传递参数,可以通过getter返回一个函数,通过函数接收参数

export const useUserListStore = defindeStore('userList', {
	getters: {
		getUserId: (store) => {
			return (userId) => state.user.find((user) => user.id = userId)
		}
	}
})

使用
<script setup>
    import { storeToRefs } from 'pinia'
    import { useUserListStore } from './store'
    const userList = useUserListStore()
    const { getUserId } = storeToRefs(userList)
</script>

<template>
	{{ getUserId(2) }}
</template>
访问其他store的getter
import { useOthreStore } from './other-store'


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值