← 返回文章列表
Vue·766 次阅读

Options API 迁移 Composition API 的常见问题

Options API 迁移 Composition API 的常见问题

把几个中后台项目迁完后,收集了团队成员问得最多的问题,统一答复。

1. watch 还是 watchEffect

  • watch(source, cb):惰性,明确指定侦听源,回调能拿到新旧值,适合"数据变了做某件事"
  • watchEffect(cb):立即执行一次,自动收集回调内用到的响应式依赖,适合"依赖什么不确定、只想保持效果同步"
watch(postId, async (newId, oldId) => {
  post.value = await fetchPost(newId)
})

watchEffect(() => {
  console.log('当前文章标题:', post.value?.title) // 自动依赖 post
})

2. 侦听 props 不能直接传对象

const props = defineProps({ post: Object })

watch(() => props.post, (val) => {}, { deep: true }) // 正确:getter 函数
watch(props.post, cb) // 错误:传进去的只是当时的值,失去响应性

3. 为什么函数里响应式变量没更新

模板里 ref 自动解包,但在 JS 中永远是 .value。90% 的"奇怪 bug"都是漏了 .value。

4. props 能不能直接改

不能,和 Vue 2 一样单向流。需要本地可编辑副本时:

const form = ref({ ...props.post }) // 拷贝一份
const emit = defineEmits(['update'])
function save() { emit('update', form.value) }

5. computed 里能不能发请求

不能有副作用,computed 必须纯计算。异步派生数据用 watch + 手动 ref,或用 VueUse 的 computedAsync。

6. onMounted 拿不到 DOM

确保 ref 已声明且模板元素绑定了同名 ref;v-if 初始为 false 的元素在 mounted 时不存在,要用 watch 或 nextTick 等出现后再访问。

7. 组件卸载了异步回调还在跑

竞态问题:用 watch 的 onCleanup 或 AbortController 作废过期请求:

watch(postId, async (id, old, onCleanup) => {
  const controller = new AbortController()
  onCleanup(() => controller.abort())
  post.value = await fetchPost(id, { signal: controller.signal })
})

8. 模板里用不了某个变量

setup/<script setup> 中声明的变量、import 的组件都必须 return / 声明在顶层才能在模板用;局部函数内部的 const 模板看不见。

迁移本身不难,难的是把"this + 选项"的旧肌肉记忆换成"声明式组合",写够三个组件基本就顺了。

看到这里了?如果这篇文章帮到过你

请我喝瓶可乐就好 🥤

收款码

评论0 条

还没有评论,来抢沙发~

发表评论

评论需审核后显示

© 2026 许冬博客 · 专注 JS 技术分享

·RSS 订阅·Powered by Nuxt 4