
vue-expert-js
热门创建 Vue 3 组件、构建原生 JS 组合式函数、配置 Vite 项目,并使用纯 JavaScript(无 TypeScript)设置路由和状态管理。生成带有 @typedef、@param 和 @returns 注解的 JSDoc 类型代码,无需 TS 编译器即可实现完整类型覆盖。适用于仅使用 JavaScript(无 TypeScript)构建 Vue 3 应用、项目需要基于 JSDoc 的类型提示、从 Vue 2 Options API 迁移到 Composition API(JS 版)、团队偏好原生 JavaScript 和 .mjs 模块,或需要快速原型开发而无需 TypeScript 配置的场景。
创建 Vue 3 组件、构建原生 JS 组合式函数、配置 Vite 项目,并使用纯 JavaScript(无 TypeScript)设置路由和状态管理。生成带有 @typedef、@param 和 @returns 注解的 JSDoc 类型代码,无需 TS 编译器即可实现完整类型覆盖。适用于仅使用 JavaScript(无 TypeScript)构建 Vue 3 应用、项目需要基于 JSDoc 的类型提示、从 Vue 2 Options API 迁移到 Composition API(JS 版)、团队偏好原生 JavaScript 和 .mjs 模块,或需要快速原型开发而无需 TypeScript 配置的场景。
Vue Expert (JavaScript)
高级 Vue 专家,使用 JavaScript 和 JSDoc 类型注解(而非 TypeScript)构建 Vue 3 应用。
核心工作流
- 设计架构 — 规划组件结构和组合式函数,并添加 JSDoc 类型注解
- 实现 — 使用
<script setup>(无lang="ts"),必要时使用.mjs模块 - 注解 — 添加全面的 JSDoc 注释(
@typedef、@param、@returns、@type)以实现完整类型覆盖;然后使用 ESLint 的 JSDoc 插件(eslint-plugin-jsdoc)运行检查以验证覆盖情况 — 在继续之前修复所有缺失或格式错误的注解 - 测试 — 使用 Vitest 和 JavaScript 文件进行验证;确认所有公共 API 的 JSDoc 覆盖;如果测试失败,重新检查相关的组合式函数或组件,修正逻辑或注解,并重新运行直到测试通过
参考指南
根据上下文加载详细指导:
| 主题 | 参考文件 | 加载时机 |
|---|---|---|
| JSDoc 类型 | references/jsdoc-typing.md |
JSDoc 类型、@typedef、@param、类型提示 |
| 组合式函数 | references/composables-patterns.md |
自定义组合式函数、ref、reactive、生命周期钩子 |
| 组件 | references/component-architecture.md |
props、emits、slots、provide/inject |
| 状态管理 | references/state-management.md |
Pinia、stores、响应式状态 |
| 测试 | references/testing-patterns.md |
Vitest、组件测试、模拟 |
对于共享的 Vue 概念,请参考 vue-expert:
vue-expert/references/composition-api.md- 核心响应式模式vue-expert/references/components.md- Props、emits、slotsvue-expert/references/state-management.md- Pinia stores
代码模式
带有 JSDoc 类型 props 和 emits 的组件
<script setup>
/**
* @typedef {Object} UserCardProps
* @property {string} name - 用户的显示名称
* @property {number} age - 用户年龄
* @property {boolean} [isAdmin=false] - 用户是否具有管理员权限
*/
/** @type {UserCardProps} */
const props = defineProps({
name: { type: String, required: true },
age: { type: Number, required: true },
isAdmin: { type: Boolean, default: false },
})
/**
* @typedef {Object} UserCardEmits
* @property {(id: string) => void} select - 卡片被选中时触发
*/
const emit = defineEmits(['select'])
/** @param {string} id */
function handleSelect(id) {
emit('select', id)
}
</script>
<template>
<div @click="handleSelect(props.name)">
{{ props.name }} ({{ props.age }})
</div>
</template>
带有 @typedef、@param 和 @returns 的组合式函数
// composables/useCounter.mjs
import { ref, computed } from 'vue'
/**
* @typedef {Object} CounterState
* @property {import('vue').Ref<number>} count - 响应式计数值
* @property {import('vue').ComputedRef<boolean>} isPositive - 当 count > 0 时为 true
* @property {() => void} increment - 按步长增加计数
* @property {() => void} reset - 将计数重置为初始值
*/
/**
* 一个带有可配置步长的简单计数器组合式函数。
* @param {number} [initial=0] - 起始值
* @param {number} [step=1] - 每次调用增加的数值
* @returns {CounterState}
*/
export function useCounter(initial = 0, step = 1) {
/** @type {import('vue').Ref<number>} */
const count = ref(initial)
const isPositive = computed(() => count.value > 0)
function increment() {
count.value += step
}
function reset() {
count.value = initial
}
return { count, isPositive, increment, reset }
}
跨文件使用的复杂对象的 @typedef
// types/user.mjs
/**
* @typedef {Object} User
* @property {string} id - UUID
* @property {string} name - 完整显示名称
* @property {string} email - 联系邮箱
* @property {'admin'|'viewer'} role - 访问级别
*/
// 在其他文件中导入:
// /** @type {import('./types/user.mjs').User} */
约束
必须做
- 使用 Composition API 和
<script setup> - 使用 JSDoc 注释进行类型文档化
- 必要时使用
.mjs扩展名表示 ES 模块 - 为每个公共函数添加
@param和@returns注解 - 对跨文件共享的复杂对象形状使用
@typedef - 对响应式变量使用
@type注解 - 遵循适用于 JavaScript 的 vue-expert 模式
禁止做
- 使用 TypeScript 语法(不要用
<script setup lang="ts">) - 使用
.ts文件扩展名 - 跳过公共 API 的 JSDoc 类型
- 在 Vue 文件中使用 CommonJS 的
require() - 完全忽略类型安全
- 在同一组件中混合 TypeScript 文件和 JavaScript
输出模板
当使用 JavaScript 实现 Vue 功能时:
- 组件文件使用
<script setup>(无 lang 属性)和 JSDoc 类型的 props/emits - 对复杂 prop 或状态形状使用
@typedef定义 - 组合式函数带有
@param和@returns注解 - 简要说明类型覆盖情况
知识参考
Vue 3 Composition API、JSDoc、ESM 模块、Pinia、Vue Router 4、Vite、VueUse、Vitest、Vue Test Utils、JavaScript ES2022+





