前言
无论是在 vue
还是 react
项目,我们势必会遇到 跨组件传输数据的场景, vue2 可以使用 vuex
, vue3 可以使用 pinia
; 在 nuxt3
中,又给我们提供了一种额外的方式, useState
在 nuxt3中,如果不使用 useState 或者 pinia 则需要写比较 【多/深】 的
事件event
和props
nuxt@3+
场景:
我们左侧的 导航在切换的时候,右侧内容需要动态刷新, 需要知道我们左侧点击的 index
, 如果使用 useState
应该怎么解决
nav-panel.vue
<template>
<div class="flex flex-col gap-3">
<div
v-for="(item, index) in navList"
:key="index"
@click="onChange(index)"
>
<div class="flex shrink-0 items-center gap-3">
<component :is="item.icon"></component>
<div>{{ item.text }}</div>
</div>
<div class="shrink-0 px-2 py-[2px] text-sm" v-if="index === 1 && count > 0">
{{ count > 99 ? '99+' : count }}
</div>
</div>
</div>
</template>
<script setup>
const props = defineProps({
tabIndex: Number,
count: Number
})
const emits = defineEmits(['change'])
/**
* 当前选择的nav item
*/
const currentIndex = useState('currentIndex', () => 0)
// 可以使用 事件 将值抛出去,给父组件,然后再传递给其他 【兄弟】组件
const onChange = (index) => {
currentIndex.value = index
emits('change', index)
}
</script>
兄弟组件/更深层的组件
dashbord.vue
<template>
<div>
<div>{{currentIndex}}</div>
<button @click="onUpdate">在兄弟组件中更新 nav 组件中的值</button>
</div>
</template>
<script setup>
// 直接这样使用即可
const currentIndex = useState('currentIndex')
watch(currentIndex, () => {
// 如果发生变化,可以使用 watch监听。
})
const onUpdate = () => {
// 直接更新即可 - 侧边导航栏会跟随变化
currentIndex.value = 2
}
</script>
场景2
初始化深度的数据对象
const state = useState('deep-state-data', () => shallowRef({
deep: '非响应式',
obj: {
a: 1,
b: 2
}
}))
小结
useState
是 SSR 友好的状态共享工具,它不是 vue3里面的语法糖,属于 Nuxt3 中的,注意甄别useState
在简单的项目/场景,比较快速的解决我们需要跨组件传递的需求useState
返回的是一个Ref
所以,使用的时候有.value
useState
数据将被序列化为 JSON,所以它不包含任何无法序列化的内容,例如类class
、函数(function
)或符号(symbols
),这一点很重要。
学习累了吧,来充充电~