You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Composition API封装模态框逻辑如何实现各组件独立响应式状态

问题根因

你当前的实现是将openModal响应式变量直接定义在modal.ts的模块顶层,ES 模块本身是单例模式,所有导入该模块的组件都会共享同一份响应式状态,因此任意组件调用切换方法都会全局修改状态,导致所有模态框同步触发。

解决方案:编写函数式 Composable

将模态框逻辑封装为可执行的工厂函数,每次调用函数时都会初始化独立的响应式状态,保证每个组件使用的状态完全隔离:

// modal.ts 实现代码
import { ref } from 'vue'

export function useModal() {
  // 状态定义在函数内部,每次调用都会生成新的响应式变量
  const openModal = ref(false)
  /**
   * 切换模态框状态
   * @param status 可选参数,传入时直接设置为指定状态,不传则取反
   */
  const toggleModal = (status?: boolean) => {
    openModal.value = status ?? !openModal.value
  }
  return { openModal, toggleModal }
}
组件使用示例

每个需要使用模态框的组件单独调用useModal()生成自身的状态即可:

<script setup lang="ts">
import { useModal } from './modal.ts'
import CustomModal from './CustomModal.vue'

// 生成当前组件专属的模态框状态
const { openModal, toggleModal } = useModal()
// 如果同一个组件内需要多个模态框,多次调用即可
const { openModal: openSecondModal, toggleModal: toggleSecondModal } = useModal()
</script>

<template>
  <button @click="toggleModal()">打开第一个模态框</button>
  <CustomModal v-if="openModal" @close="toggleModal(false)" />

  <button @click="toggleSecondModal()">打开第二个模态框</button>
  <CustomModal v-if="openSecondModal" @close="toggleSecondModal(false)" />
</template>
注意事项
  • 所有需要组件独立维护的响应式状态都要放在useModal函数内部,不要在函数外部、模块顶层定义可变的共享状态
  • 嵌套模态框场景下,父子组件分别调用useModal()生成的状态天然隔离,不会出现联动问题

内容的提问来源于stack exchange,提问作者Sensanaty

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 19:09:03