vue-best-practices

Vue 3 最佳实践、常见陷阱和性能优化。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "vue-best-practices" with this command: npx skills add hello-lizhihua/skills_zh-cn/hello-lizhihua-skills-zh-cn-vue-best-practices

Vue 3 最佳实践、常见陷阱和性能优化。

响应式

  • 在脚本中访问 ref() 值时不带 .value → 参见 ref-value-access

  • 解构 reactive() 对象,丢失响应性 → 参见 reactive-destructuring

  • 为状态选择 ref() 和 reactive() → 参见 prefer-ref-over-reactive

  • 访问数组和集合内的 ref → 参见 refs-in-collections-need-value

  • 大对象或外部库数据开销 → 参见 shallow-ref-for-performance

  • 在模板表达式中使用嵌套 ref → 参见 template-ref-unwrapping-top-level

  • 使用 === 运算符比较响应式对象 → 参见 reactivity-proxy-identity-hazard

  • 库实例在响应式状态中损坏 → 参见 reactivity-markraw-for-non-reactive

  • 期望侦听器对每次状态更改都触发 → 参见 reactivity-same-tick-batching

  • 集成外部状态管理库 → 参见 reactivity-external-state-integration

  • 追踪意外的重新渲染和状态更新 → 参见 reactivity-debugging-hooks

  • 使用 watchEffect 而不是 computed 派生状态 → 参见 reactivity-computed-over-watcheffect-mutations

计算属性

  • 计算属性 getter 进行 API 调用或突变 → 参见 computed-no-side-effects

  • 突变计算属性值导致意外丢失更改 → 参见 computed-return-value-readonly

  • 计算属性未按预期更新 → 参见 computed-conditional-dependencies

  • 排序或反转数组破坏原始数据 → 参见 computed-array-mutation

  • 昂贵操作在每次渲染时过于频繁地运行 → 参见 computed-vs-methods-caching

  • 试图向计算属性传递参数 → 参见 computed-no-parameters

  • 复杂条件导致内联类绑定臃肿 → 参见 computed-properties-for-class-logic

侦听器

  • 需要侦听响应式对象属性 → 参见 watch-reactive-property-getter

  • 大型嵌套数据结构导致性能问题 → 参见 watch-deep-performance

  • 异步操作被陈旧数据覆盖 → 参见 watch-async-cleanup

  • 在异步回调中创建侦听器 → 参见 watch-async-creation-memory-leak

  • await 之后访问的依赖项未被追踪 → 参见 watcheffect-async-dependency-tracking

  • 需要在侦听器中访问更新后的 DOM → 参见 watch-flush-timing

  • 不确定是使用 watch 还是 watchEffect → 参见 watch-vs-watcheffect

  • 重复初始调用和侦听器回调 → 参见 watch-immediate-option

  • 无法正确比较新旧值 → 参见 watch-deep-same-object-reference

  • 模板 ref 显示为 null 或陈旧 → 参见 watcheffect-flush-post-for-refs

组件

  • prop 值被子组件更改 → 参见 props-are-read-only

  • 父组件无法在 script setup 中访问子组件 ref 数据 → 参见 component-ref-requires-defineexpose

  • 子组件抛出“组件未找到”错误 → 参见 local-components-not-in-descendants

  • 点击监听器未在自定义组件上触发 → 参见 click-events-on-components

  • HTML 模板解析破坏 Vue 组件语法 → 参见 in-dom-template-parsing-caveats

  • 祖父母组件无法监听孙组件发出的事件 → 参见 component-events-dont-bubble

  • 由于命名冲突导致渲染错误的组件 → 参见 component-naming-conflicts

  • 区分 Vue 组件与原生元素 → 参见 component-naming-pascalcase

  • 父组件样式未应用于多根组件 → 参见 multi-root-component-class-attrs

  • 递归组件需要引用自身 → 参见 self-referencing-component-name

  • 捆绑包包含未使用的组件 → 参见 prefer-local-component-registration

  • 通过组件 ref 访问进行紧耦合 → 参见 prefer-props-emit-over-component-refs

Props & Emits

  • 布尔 prop 未按预期解析 → 参见 prop-boolean-casting-order

  • prop 更改时组合式函数未更新 → 参见 prop-composable-reactivity-loss

  • defineProps 中引用的变量导致错误 → 参见 prop-defineprops-scope-limitation

  • 解构的 prop 未更新侦听器 → 参见 prop-destructured-watch-getter

  • prop 验证需要组件实例数据 → 参见 prop-validation-before-instance

  • 组件发出未声明的事件导致警告 → 参见 declare-emits-for-documentation

  • defineEmits 在函数或条件内部使用 → 参见 defineEmits-must-be-top-level

  • defineEmits 同时具有类型和运行时参数 → 参见 defineEmits-no-runtime-and-type-mixed

  • 模板和脚本中的事件名称不一致 → 参见 emit-kebab-case-in-templates

  • 事件负载在开发期间需要验证 → 参见 emit-validation-for-complex-payloads

  • 原生事件监听器未响应点击 → 参见 native-event-collision-with-emits

  • 点击时组件事件触发两次 → 参见 undeclared-emits-double-firing

模板

  • 将不受信任的用户内容渲染为 HTML → 参见 v-html-xss-security

  • 过滤或有条件地隐藏列表项 → 参见 no-v-if-with-v-for

  • 列表项意外消失或交换状态 → 参见 v-for-key-attribute

  • 使用语句时出现模板编译错误 → 参见 template-expressions-restrictions

  • 动态指令参数无法正常工作 → 参见 dynamic-argument-constraints

  • 模板中的函数意外修改数据 → 参见 template-functions-no-side-effects

  • v-else 元素总是无条件渲染 → 参见 v-else-must-follow-v-if

  • 循环中的子组件显示未定义数据 → 参见 v-for-component-props

  • 排序或反转后数组顺序更改 → 参见 v-for-computed-reverse-sort

  • 范围迭代出现差一错误 → 参见 v-for-range-starts-at-one

  • 过滤或排序列表导致性能问题 → 参见 v-for-use-computed-for-filtering

  • "Cannot read property of undefined" 运行时错误 → 参见 v-if-null-check-order

  • 在 v-if 和 v-show 之间选择用于条件渲染 → 参见 v-if-vs-v-show-performance

  • v-show 或 v-else 在 template 元素上不起作用 → 参见 v-show-template-limitation

模板 Ref

  • 元素有条件隐藏时 ref 变为 null → 参见 template-ref-null-with-v-if

  • 循环中 ref 数组索引与数据数组不匹配 → 参见 template-ref-v-for-order

  • 重构模板 ref 名称在代码中静默中断 → 参见 use-template-ref-vue35

表单 & v-model

  • 使用 v-model 时初始表单值未显示 → 参见 v-model-ignores-html-attributes

  • Textarea 内容更改未更新 ref → 参见 textarea-no-interpolation

  • iOS 用户无法选择下拉列表第一个选项 → 参见 select-initial-value-ios-bug

  • 父子组件具有不同的值 → 参见 define-model-default-value-sync

  • 需要在子组件中处理 v-model 修饰符 → 参见 definemodel-hidden-modifier-props

  • 对象属性更改未同步到父组件 → 参见 definemodel-object-mutation-no-emit

  • 需要在更改后立即使用更新的值 → 参见 definemodel-value-next-tick

  • 中文/日文输入的实时搜索/验证损坏 → 参见 v-model-ime-composition

  • 数字输入返回空字符串而不是零 → 参见 v-model-number-modifier-behavior

  • 将 Vue 2 组件迁移到 Vue 3 → 参见 v-model-vue3-breaking-changes

  • 自定义复选框值未在表单中提交 → 参见 checkbox-true-false-value-form-submission

事件 & 修饰符

  • 链接多个事件修饰符产生意外结果 → 参见 event-modifier-order-matters

  • 需要只处理一次同一事件 → 参见 event-once-modifier-for-single-use

  • 键盘快捷键使用非预期的修饰符组合触发 → 参见 exact-modifier-for-precise-shortcuts

  • 键盘快捷键不随系统修饰键触发 → 参见 keyup-modifier-timing

  • 使用左手鼠标或非标准输入设备 → 参见 mouse-button-modifiers-intent

  • 阻止默认浏览器行为和滚动性能在一起 → 参见 no-passive-with-prevent

生命周期

  • 生命周期钩子不异步执行 → 参见 lifecycle-hooks-synchronous-registration

  • 组件挂载前 DOM 访问失败 → 参见 lifecycle-dom-access-timing

  • 未移除事件监听器导致内存泄漏 → 参见 cleanup-side-effects

  • SSR 渲染与客户端激活不同 → 参见 lifecycle-ssr-awareness

  • 昂贵操作极大地降低性能 → 参见 updated-hook-performance

  • 状态更改后 DOM 读取返回陈旧值 → 参见 dom-update-timing-nexttick

插槽

  • 在插槽内容中访问子组件数据 → 参见 slot-render-scope-parent-only

  • 混合使用具名插槽和作用域插槽 → 参见 slot-named-scoped-explicit-default

  • 在原生 HTML 元素上使用 v-slot → 参见 slot-v-slot-on-components-or-templates-only

  • 空包装元素不必要地渲染 → 参见 slot-conditional-rendering-with-slots

  • 作用域插槽 prop 缺乏 TypeScript 类型安全 → 参见 slot-define-slots-for-typescript

  • 渲染没有默认值的空组件插槽 → 参见 slot-fallback-content-default-values

  • 包装组件破坏子插槽功能 → 参见 slot-forwarding-to-child-components

  • 混淆哪个插槽内容去哪里 → 参见 slot-implicit-default-content

  • 期望作用域插槽 prop 中有 name 属性 → 参见 slot-name-reserved-prop

  • 在无渲染组件和组合式函数之间选择 → 参见 slot-renderless-components-vs-composables

Provide/Inject

  • 提供者更改时注入的值未更新 → 参见 provide-inject-reactivity-not-automatic

  • 异步操作后调用 provide 失败且无声息 → 参见 provide-inject-synchronous-setup

  • 字符串键在大型应用中冲突 → 参见 provide-inject-symbol-keys

  • 追踪提供的值来自何处 → 参见 provide-inject-debugging-challenges

  • 多个组件共享相同的默认对象 → 参见 provide-inject-default-value-factory

  • 状态突变分散在组件之间 → 参见 provide-inject-mutations-in-provider

  • 通过许多组件层传递 props → 参见 avoid-prop-drilling-use-provide-inject

Attrs

  • 内部和透传事件处理器都执行 → 参见 attrs-event-listener-merging

  • 在 JavaScript 代码中访问连字符属性 → 参见 attrs-hyphenated-property-access

  • 使用 watch() 侦听透传属性更改 → 参见 attrs-not-reactive

  • 显式属性被透传值覆盖 → 参见 fallthrough-attrs-overwrite-vue3

  • 属性应用于包装器中的错误元素 → 参见 inheritattrs-false-for-wrapper-components

组合式函数

  • 组合式函数具有影响外部状态的意外副作用 → 参见 composable-avoid-hidden-side-effects

  • 在 setup 上下文之外或异步调用组合式函数 → 参见 composable-call-location-restrictions

  • 从较小的专注组合式函数构建复杂逻辑 → 参见 composable-composition-pattern

  • 不一致的组合式函数名称或解构丢失响应性 → 参见 composable-naming-return-pattern

  • 组合式函数有许多可选参数或令人困惑的参数顺序 → 参见 composable-options-object-pattern

  • 需要防止不受控制的组合式函数状态突变 → 参见 composable-readonly-state

  • 输入更改时组合式函数响应式依赖项未更新 → 参见 composable-tovalue-inside-watcheffect

  • 不确定逻辑属于组合式函数还是工具函数 → 参见 composable-vs-utility-functions

组合式 API

  • 优化生产包大小和性能 → 参见 composition-api-bundle-size-minification

  • 组合式 API 代码变得分散且难以维护 → 参见 composition-api-code-organization

  • 修复 mixin 中的命名冲突和不明确的数据来源 → 参见 composition-api-mixins-replacement

  • 错误地将函数式模式应用于 Vue 状态 → 参见 composition-api-not-functional-programming

  • 逐步迁移大型选项式 API 代码库 → 参见 composition-api-options-api-coexistence

  • 异步操作后生命周期钩子静默失败 → 参见 composition-api-script-setup-async-context

  • 来自 React,不必要地过度设计 Vue 模式 → 参见 composition-api-vs-react-hooks-differences

  • 父组件 ref 无法访问公开的属性 → 参见 define-expose-before-await

指令

  • 跨指令钩子存储状态 → 参见 directive-arguments-read-only

  • 将自定义指令应用于 Vue 组件 → 参见 directive-avoid-on-components

  • 在指令中创建间隔或事件监听器 → 参见 directive-cleanup-in-unmounted

  • 简化具有相同行为的指令 → 参见 directive-function-shorthand

  • 在 script setup 中使用自定义指令 → 参见 directive-naming-v-prefix

  • 在自定义指令和内置指令之间选择 → 参见 directive-prefer-declarative-templating

  • 在指令和组件之间决定 → 参见 directive-vs-component-decision

  • 将 Vue 2 指令迁移到 Vue 3 → 参见 directive-vue2-migration-hooks

过渡

  • 将多个元素或组件包装在过渡中 → 参见 transition-single-element-slot

  • 在相同元素类型之间过渡而无动画 → 参见 transition-key-for-same-element

  • 使用 JavaScript 动画而不调用 done 回调 → 参见 transition-js-hooks-done-callback

  • 使用 TransitionGroup 动画化列表而没有唯一键 → 参见 transition-group-key-requirement

  • 抖动的列表动画导致性能问题 → 参见 transition-animate-transform-opacity

  • 移动动画在内联列表元素上失败 → 参见 transition-group-flip-inline-elements

  • 列表项跳跃而不是平滑动画 → 参见 transition-group-move-animation-position-absolute

  • Vue 2 到 Vue 3 过渡布局意外中断 → 参见 transition-group-no-default-wrapper-vue3

  • 试图使用 mode 属性对列表动画进行排序 → 参见 transition-group-no-mode-prop

  • 为列表项动画创建级联延迟 → 参见 transition-group-staggered-animations

  • 过渡期间元素重叠或布局跳跃 → 参见 transition-mode-out-in

  • 嵌套过渡动画过早切断 → 参见 transition-nested-duration

  • 带有作用域样式的可复用过渡组件中断 → 参见 transition-reusable-scoped-style

  • RouterView 过渡在页面加载时意外动画化 → 参见 transition-router-view-appear

  • 混合 CSS 过渡和动画导致时间问题 → 参见 transition-type-when-mixed

  • 组件清理在快速过渡替换期间未触发 → 参见 transition-unmount-hook-timing

动画

  • 需要动画化保留在 DOM 中的元素 → 参见 animation-class-based-technique

  • 内容更改时动画未触发 → 参见 animation-key-for-rerender

  • 使用用户输入构建交互式动画 → 参见 animation-state-driven-technique

  • 动画化列表更改导致明显的滞后 → 参见 animation-transitiongroup-performance

KeepAlive

  • 使用 KeepAlive 而没有适当的缓存限制或清理 → 参见 keepalive-memory-management

  • KeepAlive include/exclude 属性与缓存组件不匹配 → 参见 keepalive-component-name-requirement

  • 需要以编程方式从 KeepAlive 缓存中删除组件 → 参见 keepalive-no-cache-removal-vue3

  • 期望新鲜页面数据时用户看到陈旧的缓存内容 → 参见 keepalive-router-fresh-vs-cached

  • 子组件在嵌套 Vue Router 路由中挂载两次 → 参见 keepalive-router-nested-double-mount

  • 将 KeepAlive 与 Transition 动画结合使用时内存增长 → 参见 keepalive-transition-memory-leak

  • 在动态组件之间切换时状态重置 → 参见 dynamic-components-with-keepalive

异步组件

  • 设置 Vue Router 路由组件加载 → 参见 async-component-vue-router

  • 异步组件选项被父 Suspense 忽略 → 参见 async-component-suspense-control

  • 加载组件时网络故障或超时 → 参见 async-component-error-handling

  • 改善 SSR 应用的可交互时间 → 参见 async-component-hydration-strategies

  • 组件重新激活后模板 ref 未定义 → 参见 async-component-keepalive-ref-issue

  • 快速网络上加载微调器闪烁 → 参见 async-component-loading-delay

渲染函数

  • 来自 setup 的渲染函数未响应式更新 → 参见 rendering-render-function-return-from-setup

  • 同一 vnode 在树中出现多次 → 参见 render-function-vnodes-must-be-unique

  • 在没有键的渲染函数中渲染列表 → 参见 render-function-v-for-keys-required

  • 在渲染函数中实现 .stop, .prevent → 参见 render-function-event-modifiers

  • 在渲染函数中的组件上进行双向绑定 → 参见 render-function-v-model-implementation

  • 在渲染函数中为组件使用字符串名称 → 参见 rendering-resolve-component-for-string-names

  • 访问 vnode 内部,如 el 或 shapeFlag → 参见 render-function-avoid-internal-vnode-properties

  • 创建简单的无状态展示组件 → 参见 render-function-functional-components

  • 在渲染函数中应用自定义指令 → 参见 render-function-custom-directives

  • 来自侦听器或深度侦听器的过多重新渲染 → 参见 rendering-excessive-rerenders-watch-vs-computed

  • 选择渲染函数而非模板 → 参见 rendering-prefer-templates-over-render-functions

  • 将 Vue 2 渲染函数迁移到 Vue 3 → 参见 rendering-render-function-h-import-vue3

  • 错误地将插槽内容传递给 h() → 参见 rendering-render-function-slots-as-functions

  • 理解 Vue 的 vdom 优化块 → 参见 rendering-understand-vdom-block-structure

Teleport

  • 在 DOM 中未找到 Teleport 目标元素 → 参见 teleport-target-must-exist

  • 传送的内容破坏 SSR 激活 → 参见 teleport-ssr-hydration

  • 模态框因父级 CSS 变换而中断 → 参见 teleport-css-positioning-issues

  • 内容在移动设备上需要不同的布局 → 参见 teleport-disabled-for-responsive

  • 不确定 props/events 是否通过 teleport 工作 → 参见 teleport-logical-hierarchy-preserved

  • 多个模态框针对同一容器 → 参见 teleport-multiple-to-same-target

  • 作用域样式未应用于传送的内容 → 参见 teleport-scoped-styles-limitation

Suspense

  • 需要处理来自 Suspense 组件的异步错误 → 参见 suspense-no-builtin-error-handling

  • 想要以编程方式追踪 Suspense 加载状态 → 参见 suspense-events-for-state-tracking

  • 规划生产应用中的 Suspense 使用 → 参见 suspense-experimental-api-stability

  • 内容更改时未显示回退 → 参见 suspense-fallback-not-immediate-on-revert

  • 将 Suspense 组件嵌套在一起 → 参见 suspense-nested-suspensible-prop

  • 将 Suspense 与 Router、Transition、KeepAlive 结合使用 → 参见 suspense-nesting-order-with-router

  • 嵌套异步组件未显示加载指示器 → 参见 suspense-revert-only-on-root-change

  • 单个 Suspense 中的多个异步组件 → 参见 suspense-single-child-requirement

  • 在服务器端渲染中使用 Suspense → 参见 suspense-ssr-hydration-issues

TypeScript

  • 在组合式 API 组件中使用 TypeScript 声明 props → 参见 ts-defineprops-type-based-declaration

  • 为可变 prop 类型提供默认值 → 参见 ts-withdefaults-mutable-factory-function

  • 使用 ref 解包关注点类型化响应式状态 → 参见 ts-reactive-no-generic-argument

  • 组件挂载后访问 DOM 元素 → 参见 ts-template-ref-null-handling

  • 类型化子 Vue 组件的 ref → 参见 ts-component-ref-typeof-instancetype

  • 使用具有 TypeScript 支持的自定义指令 → 参见 ts-custom-directive-type-augmentation

  • 使用完全类型安全声明组件事件 → 参见 ts-defineemits-type-based-syntax

  • 在 TypeScript 中处理可选布尔 props → 参见 ts-defineprops-boolean-default-false

  • 在 defineProps 中安全使用导入的类型 → 参见 ts-defineprops-imported-types-limitations

  • 使用严格 TypeScript 检查处理 DOM 事件 → 参见 ts-event-handler-explicit-typing

  • 在具有类型安全的组件之间共享数据 → 参见 ts-provide-inject-injection-key

  • 在响应式状态中存储 Vue 组件 → 参见 ts-shallowref-for-dynamic-components

  • 在 Vue 模板中使用联合类型 → 参见 ts-template-type-casting

SSR

  • 用户数据在服务器请求之间泄漏 → 参见 state-ssr-cross-request-pollution

  • HTML 在服务器和客户端渲染之间不同 → 参见 ssr-hydration-mismatch-causes

  • 代码在服务器和浏览器环境中运行 → 参见 ssr-platform-specific-apis

  • 自定义指令未显示在服务器渲染的 HTML 上 → 参见 ssr-custom-directive-getssrprops

性能

  • 状态更改期间许多列表项不必要地重新渲染 → 参见 perf-props-stability-update-optimization

  • 渲染成百上千的项目导致 DOM 性能问题 → 参见 perf-virtualize-large-lists

  • 静态内容在每次父组件更新时重新评估 → 参见 perf-v-once-v-memo-directives

  • 列表性能因深度嵌套组件结构而下降 → 参见 perf-avoid-component-abstraction-in-lists

  • 返回对象的计算属性意外触发副作用 → 参见 perf-computed-object-stability

  • 页面加载指标受客户端 JavaScript 执行延迟影响 → 参见 perf-ssr-ssg-for-page-load

SFC (单文件组件)

  • 试图从组件脚本块使用命名导出 → 参见 sfc-named-exports-forbidden

  • 启动具有构建设置的 Vue 项目 → 参见 sfc-recommended-for-build-projects

  • 使用作用域 CSS 为子组件元素设置样式 → 参见 sfc-scoped-css-child-component-styling

  • 为使用 v-html 动态添加的内容设置样式 → 参见 sfc-scoped-css-dynamic-content

  • 优化作用域 CSS 选择器性能 → 参见 sfc-scoped-css-performance

  • 为通过组件插槽传递的内容设置样式 → 参见 sfc-scoped-css-slot-content

  • 更改后变量在模板中未更新 → 参见 sfc-script-setup-reactivity

  • 组织组件模板、逻辑和样式 → 参见 sfc-separation-of-concerns-colocate

  • 使用属性名称绑定内联样式 → 参见 style-binding-camelcase

  • 使用字符串连接构建 Tailwind 类 → 参见 tailwind-dynamic-class-generation

插件

  • 调试全局属性导致命名冲突的原因 → 参见 plugin-global-properties-sparingly

  • 插件不工作或 inject 返回 undefined → 参见 plugin-install-before-mount

  • 全局属性在 setup 函数中不可用 → 参见 plugin-prefer-provide-inject-over-global-properties

  • 从头开始创建一个新的 Vue 插件 → 参见 plugin-structure-install-method

  • 防止多个插件之间的冲突 → 参见 plugin-symbol-injection-keys

  • 全局属性缺少 TypeScript 自动完成支持 → 参见 plugin-typescript-type-augmentation

应用配置

  • mount 调用后应用配置方法不工作 → 参见 configure-app-before-mount

  • 需要在 mount 后链式调用应用配置方法 → 参见 mount-return-value

  • Vue 仅控制特定页面部分 → 参见 multiple-app-instances

  • 将动态组件注册迁移到 Vite → 参见 dynamic-component-registration-vite

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

vue-pinia-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

vue-jsx-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

vue-options-api-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
General

vue-router-best-practices

No summary provided by upstream source.

Repository SourceNeeds Review
vue-best-practices | V50.AI