名称: vue-best-practices
描述: 必须用于 Vue.js 任务。强烈推荐使用 Composition API 和 <script setup> 以及 TypeScript 作为标准方法。覆盖 Vue 3、SSR、Volar、vue-tsc。适用于任何 Vue、.vue 文件、Vue Router、Pinia 或 Vite 与 Vue 的工作。除非项目明确要求 Options API,否则始终使用 Composition API。
许可证: MIT
元数据:
作者: github.com/vuejs-ai
版本: “17.0.0”
Vue 3 最佳实践、常见陷阱和性能优化。
响应式
- 在脚本中访问 ref() 值而不使用 .value → 参见 ref-value-access
- 解构 reactive() 对象,失去响应式 → 参见 reactive-destructuring
- 为状态选择 ref() 或 reactive() → 参见 prefer-ref-over-reactive
- 访问数组和集合中的 refs → 参见 refs-in-collections-need-value
- 大对象或外部库数据开销 → 参见 shallow-ref-for-performance
- 在模板表达式中使用嵌套 refs → 参见 template-ref-unwrapping-top-level
- 使用 === 操作符比较响应式对象 → 参见 reactivity-proxy-identity-hazard
- 库实例在响应式状态中中断 → 参见 reactivity-markraw-for-non-reactive
- 期望监听器为每个状态更改触发 → 参见 reactivity-same-tick-batching
- 集成外部状态管理库 → 参见 reactivity-external-state-integration
- 使用 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
- await 后访问的依赖不跟踪 → 参见 watcheffect-async-dependency-tracking
- 需要在监听器中访问更新的 DOM → 参见 watch-flush-timing
- 不确定使用 watch 或 watchEffect → 参见 watch-vs-watcheffect
- 重复初始调用和监听回调 → 参见 watch-immediate-option
- 无法正确比较旧值和新值 → 参见 watch-deep-same-object-reference
- 模板引用出现 null 或过时 → 参见 watcheffect-flush-post-for-refs
组件
- 子组件更改 prop 值 → 参见 props-are-read-only
- 祖父母无法监听孙辈发出的事件 → 参见 component-events-dont-bubble
- 区分 Vue 组件和原生元素 → 参见 component-naming-pascalcase
- 递归组件需要引用自身 → 参见 self-referencing-component-name
- 捆绑包包含未使用的组件 → 参见 prefer-local-component-registration
- 通过组件引用访问导致紧耦合 → 参见 prefer-props-emit-over-component-refs
Props & 事件
- 布尔 prop 解析不符合预期 → 参见 prop-boolean-casting-order
- 组合函数在 props 更改时不更新 → 参见 prop-composable-reactivity-loss
- 解构的 props 不更新监听器 → 参见 prop-destructured-watch-getter
- Prop 验证需要组件实例数据 → 参见 prop-validation-before-instance
- 事件名在模板和脚本中不一致 → 参见 emit-kebab-case-in-templates
- 开发期间需要验证事件负载 → 参见 emit-validation-for-complex-payloads
模板
- 渲染不受信任的用户内容为 HTML → 参见 v-html-xss-security
- 过滤或条件隐藏列表项 → 参见 no-v-if-with-v-for
- 模板中的函数意外修改数据 → 参见 template-functions-no-side-effects
- 过滤或排序列表的性能问题 → 参见 v-for-use-computed-for-filtering
- 为条件选择 v-if 和 v-show → 参见 v-if-vs-v-show-performance
表单与 v-model
- 需要在子组件处理 v-model 修饰符 → 参见 definemodel-hidden-modifier-props
- 更改后需要立即使用更新值 → 参见 definemodel-value-next-tick
- 迁移 Vue 2 组件到 Vue 3 → 参见 v-model-vue3-breaking-changes
事件与修饰符
- 需要处理同一事件仅一次 → 参见 event-once-modifier-for-single-use
- 键盘快捷键与非预期修饰符组合触发 → 参见 exact-modifier-for-precise-shortcuts
- 使用左手鼠标或非标准输入设备 → 参见 mouse-button-modifiers-intent
- 阻止默认浏览器操作和滚动性能 → 参见 no-passive-with-prevent
生命周期
- 生命周期钩子不同步执行 → 参见 lifecycle-hooks-synchronous-registration
- 昂贵操作严重降低性能 → 参见 updated-hook-performance
插槽
- 在插槽内容中访问子组件数据 → 参见 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
- 作用域插槽 props 缺乏 TypeScript 类型安全 → 参见 slot-define-slots-for-typescript
- 渲染空组件插槽无默认值 → 参见 slot-fallback-content-default-values
- 混淆哪个插槽内容去向 → 参见 slot-implicit-default-content
- 期望作用域插槽 props 中有 name 属性 → 参见 slot-name-reserved-prop
- 选择无渲染组件与组合函数 → 参见 slot-renderless-components-vs-composables
Provide/Inject
- 字符串键在大型应用中冲突 → 参见 provide-inject-symbol-keys
- 状态突变分散在组件中 → 参见 provide-inject-mutations-in-provider
- 通过多组件层传递 props → 参见 avoid-prop-drilling-use-provide-inject
Attrs
- 在 JavaScript 代码中访问连字符属性 → 参见 attrs-hyphenated-property-access
- 使用 watch() 监视回退属性更改 → 参见 attrs-not-reactive
组合函数
- 组合函数有意外副作用影响外部状态 → 参见 composable-avoid-hidden-side-effects
- 从较小专注的组合函数构建复杂逻辑 → 参见 composable-composition-pattern
- 不一致的组合函数名或解构失去响应式 → 参见 composable-naming-return-pattern
- 组合函数有许多可选参数或混淆参数顺序 → 参见 composable-options-object-pattern
- 需要防止组合函数状态不受控突变 → 参见 composable-readonly-state
- 不确定逻辑属于组合函数或工具函数 → 参见 composable-vs-utility-functions
Composition API
- 优化生产捆绑大小和性能 → 参见 composition-api-bundle-size-minification
- Composition API 代码变得分散难以维护 → 参见 composition-api-code-organization
- 修复混入中的命名冲突和不清数据来源 → 参见 composition-api-mixins-replacement
- 错误应用函数式模式到 Vue 状态 → 参见 composition-api-not-functional-programming
- 逐渐迁移大型 Options API 代码库 → 参见 composition-api-options-api-coexistence
- 从 React 来,过度工程 Vue 模式 → 参见 composition-api-vs-react-hooks-differences
指令
- 在指令钩子间存储状态 → 参见 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 prop 序列列表动画 → 参见 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 props 不匹配缓存组件 → 参见 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
- 用 SSR 应用提升 Time to Interactive → 参见 async-component-hydration-strategies
- 快速网络加载指示器闪烁 → 参见 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
- 模态框与父级 CSS 变换中断 → 参见 teleport-css-positioning-issues
- 移动端内容需要不同布局 → 参见 teleport-disabled-for-responsive
- 不确定 props/事件通过 teleport 工作 → 参见 teleport-logical-hierarchy-preserved
- 多个模态框目标相同容器 → 参见 teleport-multiple-to-same-target
- 作用域样式不应用于 teleported 内容 → 参见 teleport-scoped-styles-limitation
Suspense
- 想编程追踪 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
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 组件 → 参见 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
- 代码在服务器和浏览器环境运行 → 参见 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 (单文件组件)
- 用构建设置开始 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-separation-of-concerns-colocate
- 绑定内联样式与属性名 → 参见 style-binding-camelcase
- 构建 Tailwind 类用字符串连接 → 参见 tailwind-dynamic-class-generation
插件
- 全局属性在 setup 函数中不可用 → 参见 plugin-prefer-provide-inject-over-global-properties
- 从零创建新 Vue 插件 → 参见 plugin-structure-install-method
- 防止多个插件间冲突 → 参见 plugin-symbol-injection-keys
- 全局属性缺少 TypeScript 自动完成支持 → 参见 plugin-typescript-type-augmentation
应用配置
- 需要链接应用配置方法后挂载 → 参见 mount-return-value
- Vue 仅控制特定页面部分 → 参见 multiple-app-instances
- 迁移动态组件注册到 Vite → 参见 dynamic-component-registration-vite