全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-20 8 分钟 ✍️ juanwangdev

状态复用

Vue 状态复用指将组件状态逻辑抽取为可复用的单元,在多个组件间共享状态和行为。

Composables 复用

基础 Composable

JavaScript
// composables/useCounter.js
import { ref, computed } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)
  
  const doubleCount = computed(() => count.value * 2)
  
  const increment = () => {
    count.value++
  }
  
  const decrement = () => {
    count.value--
  }
  
  return {
    count,
    doubleCount,
    increment,
    decrement
  }
}

组件中使用

vue
<script setup>
import { useCounter } from '@/composables/useCounter'

const { count, doubleCount, increment, decrement } = useCounter(10)
</script>

<template>
  <div>
    <p>Count: {{ count }}</p>
    <p>Double: {{ doubleCount }}</p>
    <button @click="increment">+</button>
    <button @click="decrement">-</button>
  </div>
</template>

每个组件调用 useCounter() 会创建独立的状态实例,互不影响。

共享状态 Composable

模块级单例

JavaScript
// composables/useSharedState.js
import { ref } from 'vue'

// 模块级变量,所有组件共享同一实例
const sharedCount = ref(0)

export function useSharedState() {
  const increment = () => {
    sharedCount.value++
  }
  
  return {
    sharedCount,
    increment
  }
}

多组件共享

vue
<!-- ComponentA.vue -->
<script setup>
import { useSharedState } from '@/composables/useSharedState'

const { sharedCount, increment } = useSharedState()
</script>

<!-- ComponentB.vue -->
<script setup>
import { useSharedState } from '@/composables/useSharedState'

const { sharedCount } = useSharedState()
</script>

模块级变量在应用生命周期内只初始化一次,多组件共享同一状态。

Provide / Inject

祖先组件 Provide

vue
<!-- Parent.vue -->
<script setup>
import { provide, ref } from 'vue'

const theme = ref('light')

provide('theme', {
  current: theme,
  toggle: () => {
    theme.value = theme.value === 'light' ? 'dark' : 'light'
  }
})
</script>

后代组件 Inject

vue
<!-- Child.vue -->
<script setup>
import { inject } from 'vue'

const { current, toggle } = inject('theme')
</script>

<template>
  <div :class="current">
    <button @click="toggle">切换主题</button>
  </div>
</template>

provide/inject 适用于深层组件通信,避免逐层传递 props。

组合使用场景

Composable + Provide

JavaScript
// composables/useAuth.js
import { ref, provide, inject } from 'vue'

const SymbolKey = Symbol('auth')

export function createAuthProvider(user) {
  const currentUser = ref(user)
  
  const login = (userData) => {
    currentUser.value = userData
  }
  
  const logout = () => {
    currentUser.value = null
  }
  
  provide(SymbolKey, {
    currentUser,
    login,
    logout
  })
}

export function useAuth() {
  return inject(SymbolKey)
}

对比选择

方案适用场景状态共享类型安全
Composables逻辑复用可选
Provide/Inject深层组件通信
Pinia/Vuex全局状态管理

注意事项

  • Composable 函数必须以 use 开头,遵循 Vue 命名约定
  • 共享状态需注意避免意外修改导致组件间状态污染
  • provide/inject 不适合高频更新状态,性能较差
  • 复杂应用建议使用 Pinia 等状态管理库

要点总结

  • Composables 是 Vue 3 推荐的状态复用方案,逻辑与状态可一并复用
  • 模块级变量实现共享状态,多组件共享同一实例
  • provide/inject 适用于祖先-后代组件通信
  • 简单逻辑用 Composables,全局状态用 Pinia

存放路径: articles/VUE/进阶/过度动画与状态复用/状态复用.md

📝 发现内容有误?点击此处直接编辑

← 上一篇 列表过渡
下一篇 → 过度动画基础
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库