手把手在nuxt3中使用useState

243 阅读2分钟

前言

无论是在 vue还是 react 项目,我们势必会遇到 跨组件传输数据的场景, vue2 可以使用 vuex, vue3 可以使用 pinia; 在 nuxt3中,又给我们提供了一种额外的方式, useState

在 nuxt3中,如果不使用 useState 或者 pinia 则需要写比较 【多/深】 的 事件eventprops

nuxt@3+

场景:

image.png

我们左侧的 导航在切换的时候,右侧内容需要动态刷新, 需要知道我们左侧点击的 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),这一点很重要。

学习累了吧,来充充电~