惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

月光博客
月光博客
人人都是产品经理
人人都是产品经理
Hugging Face - Blog
Hugging Face - Blog
有赞技术团队
有赞技术团队
阮一峰的网络日志
阮一峰的网络日志
罗磊的独立博客
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
大猫的无限游戏
大猫的无限游戏
博客园 - 司徒正美
S
SegmentFault 最新的问题
Jina AI
Jina AI
美团技术团队
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
WordPress大学
WordPress大学
爱范儿
爱范儿
博客园 - Franky
量子位
V
V2EX
Apple Machine Learning Research
Apple Machine Learning Research
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
雷峰网
雷峰网

Vue.js

AI 特效 shadcn-vue-admin 已升级至 vite8 我真的要放弃 Vue,改用 React 了 请问 vue3 的 onclick 和 @click 有什么区别 求推荐美观、功能全的 vue AI chat 组件 [求助贴] 有没有推荐的 vue3 页面设计器 大屏设计器(源码可以拿来二开的 开源 or 收费) 有没有大佬在正式项目里使用 rolldown 了 Vue 的 reactive 会有人专门用吗? 大佬们,想在 vue 中集成一个 excel,有什么方案? vue3 无法手动控制 keepalive 的缓存| fork 了独立的 keep-alive 组件|支持手动删除缓存或者添加缓存 WebStorm 写 个 v-for, cpu 就狂飙 Nuxt UI 4 可以免费用 Pro 了 Vue2 除了 ele-table-editor,还有没有其他“子表单(inline-formset)”的组件? 请问 vue 的 defineEmits 类型如何使用动态键名 VUE 开发求助 屎代码靠我自己骂已经不解气了,佬们来看个笑话 我的 mp4 播放不出来! 有一个 8K 行的 VUE 代码文件用什么 AI 可以解耦 求助 Vue 大佬,为什么使用 reactive 数据没有双向绑定? uniapp 求助 Vue3 编写的最佳实践是怎样的? 开发一款轻便简洁的论坛程序 VueConf 2025 所有演讲嘉宾及日程已确定, 7 月 12 日,深圳见! vue3+ELInput 无法输入的问题 想问一下 pinia 持久化到 localStorage 如何实现有效期 有什么适用于 Vue/Nuxt 的表单/问卷/试卷+设计器库么 vue_cli 用到 env 环境变量值特殊字符处理 统计基于 vue 的汽水音乐电脑版用了哪些开源组件 ant-design-vue 好像不怎么维护了, vue 有什么比较靠谱的 ui 组件库吗 关于二次封装 element-plus 组件库主题问题
用 reactive 來實現 oo 對象的封裝
mizuhashi · 2025-11-14 · via Vue.js

我不確定這是否是普遍的用法,但我發現 reactive 非常適合用來建立類似 OO 的封裝。

reactive會把 refs 展平,所以可以這麼寫:

function useClient() {
  const name = ref('Alice')
  const greeting = computed(() => `Hello ${name.value}`)

  function updateName(newName: string) {
    name.value = newName
  }

  return reactive({
    name,
    greeting,
    updateName
  })
}

在 component 裏:

const client = useClient()
client.greeting // => 'Hello Alice'

client.updateName('Bob')
client.greeting // => 'Hello Bob'

現在client管理它自己的狀態,其暴露的接口可以直接用在模板裏。

我們也可以組合這些對象和保留嚮應性:

function useOrder(client: ReturnType<typeof useClient>) {
  const createdBy = computed(() => `Created by ${client.name}`)

  // 你也可以在這裏調用 client.updateName

  return reactive({
    createdBy
  })
}

const client = useClient()
const order = useOrder(client)
order.createdBy // => 'Created by Alice'
client.updateName('Bob')
order.createdBy // => 'Created by Bob'

我覺得這是 vue 相對於其他庫特別的屬性,我只需要傳遞一個對象,而它擁有自己的狀態和方法。

在現實中,這些對象一般會基於後端數據,我們可以在後端數據的基礎上擴展狀態和方法。

async function useOrder(client: ReturnType<typeof useClient>) {
  const orderData = reactive(await fetchOrderData())

  const paid = ref(false)

  async function pay() {
    const res = await paymentAPI()
    paid.value = res.success
  }

  return reactive({
    ...toRefs(orderData), // 所有 orderData 的屬性會被暴露
    // 我們需要 toRefs 來保持嚮應性
    paid,
    pay
  })
}

現在給定一個 order ,我們可以直接在模板裏綁定order.paidorder.pay

本帖在 reddit 上的版本: https://www.reddit.com/r/vuejs/comments/1owezu4/reactive_as_an_object_encapsulation/