Vue3组合式API实战:setup逻辑组织与响应式状态管理方案

Vue3的组合式API把同一业务逻辑的状态、计算属性、副作用集中在一起,解决了Options API在组件变大后代码按选项分散、复用困难的问题。本文从setup基础写法、响应式API选型、逻辑复用抽离到与Pinia的状态管理分工,给出组合式API项目的组织方法。

setup语法糖与基础写法

<script setup>是Vue3推荐的组件写法,顶层声明的变量和方法直接模板可用:

<script setup lang="ts">
import { ref, computed } from 'vue'

const count = ref(0)
const double = computed(() => count.value * 2)

function increment() {
  count.value++
}
</script>

<template>
  <button @click="increment">count is {{ count }}, double {{ double }}</button>
</template>

相比setup函数返回对象的老写法,<script setup>减少了样板代码,组件props通过defineProps声明,事件用defineEmits,并天然支持TypeScript泛型推导。

ref与reactive的选择标准

组合式API里的响应式状态有两类容器:ref包装单个值时通过.value访问,reactive包装嵌套对象且不需要.value。选型标准很简单:模板和逻辑中频繁替换整个值用ref,深层嵌套对象且结构固定用reactive。

import { ref, reactive } from 'vue'

const keyword = ref('')        // 搜索关键词,常被整体赋值
const filters = reactive({     // 复杂筛选对象,结构固定
  category: 'all',
  priceRange: [0, 1000],
})

reactive对象被解构后会丢失响应性,需要取值时使用toRefs转成ref集合;ref在模板中自动解包,不需要写.value,但在响应式对象中嵌套ref赋值也会被自动解包。

业务逻辑抽取与自定义组合函数

组合式API复用业务逻辑的核心是封装自定义组合函数useXxx,组件只负责编排:

// useCounter.ts
export function useCounter(initial = 0) {
  const count = ref(initial)
  const increment = () => count.value++
  const decrement = () => count.value--
  return { count, increment, decrement }
}

多个组件共用同一份分页、筛选、数据请求逻辑时,把状态与副作用一起封装成组合函数,能显著减少重复代码。抽函数时注意生命周期副作用要在函数内用onMounted等注册,避免在非setup上下文调用组合函数导致生命周期警告。

状态管理:Pinia与组合式API的配合

组件间共享状态用Pinia替代Vuex,store本身就用组合式API编写:

// stores/user.ts
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({ name: '', roles: [] as string[] }),
  getters: {
    isAdmin: (s) => s.roles.includes('admin'),
  },
  actions: {
    async fetchUser() {
      const data = await api.getProfile()
      this.name = data.name
      this.roles = data.roles
    },
  },
})

store里的state和getters对应组合式API的ref与computed,actions对应普通函数,心智模型一致。页面级状态继续放在组合函数里,跨页面共享的登录态、权限数据放store。

状态持久化与异步场景处理

刷新页面后state丢失时,用pinia-plugin-persistedstate插件把store写入localStorage,配置里按key区分store:

import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

export const useUserStore = defineStore('user', {
  state: () => ({ token: '' as string }),
  persist: { key: 'app-user' },
})

需要注意持久化只适合小体积可序列化数据,敏感信息不要存localStorage。异步请求竞态问题时在组合函数里加请求序号或AbortController,避免旧请求覆盖新响应。

组合式API迁移与性能注意点

Vue2项目迁移时优先迁移数据请求、筛选排序这类纯逻辑,模板和样式保持不动,降低回归风险。watch监听ref或reactive对象时注意deep参数会带来额外开销,大列表数据建议改用字段精确watch或useDebounceFn防抖。响应式代理对大数组的遍历性能也有影响,超大数据量优先用shallowRef配合手动触发更新。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/vue3-zu-he-shi-api-shi-zhan-setup-luo-ji-zu-zhi-yu-xiang/

(0)
小编小编
上一篇 48分钟前
下一篇 48分钟前

相关推荐