Vize

类型与脚本规则

本页集中列出所有相关规则的用途、配置、错误示例和正确示例,无需跳转页面查看对照。高亮行标示修改;复制代码时保留完整源代码。每条规则注明适用范围和当前支持限制;规范示例并不保证当前实现会产生诊断。

规则 示例 用途
script/component-options-name-casing 错误示例 · 正确示例 要求组件 name 选项使用 PascalCase
script/custom-event-name-casing 错误示例 · 正确示例 要求发出的自定义事件名称使用 camelCase
script/define-emits-declaration 错误示例 · 正确示例 要求使用类型形式 defineEmits<{}>(),而不是运行时或数组形式
script/define-macros-order 错误示例 · 正确示例 要求 <script setup> 中的 Vue 编译器宏保持一致的顺序
script/define-props-declaration 错误示例 · 正确示例 要求使用类型形式 defineProps<{ ... }>(),而不是运行时或对象形式
script/define-props-destructuring 错误示例 · 正确示例 要求 <script setup> 中的 defineProps 解构风格保持一致
script/no-arrow-functions-in-watch 错误示例 · 正确示例 禁止将箭头函数用作 Options API watch 处理器
script/no-async-in-computed 错误示例 · 正确示例 禁止计算属性中的异步函数
script/no-boolean-default 错误示例 · 正确示例 禁止为 Boolean prop 设置默认值
script/no-deep-destructure-in-props 错误示例 · 正确示例 禁止在 defineProps 中进行深层嵌套解构
script/no-deprecated-data-object-declaration 错误示例 · 正确示例 禁止将对象字面量作为组件 data 选项(Vue 3 要求函数)
script/no-deprecated-destroyed-lifecycle 错误示例 · 正确示例 禁止已弃用的 destroyed 和 beforeDestroy 生命周期钩子
script/no-deprecated-dollar-listeners-api 错误示例 · 正确示例 禁止 Vue 3 已移除的 $listeners 实例属性(已合并到 $attrs)
script/no-deprecated-dollar-scopedslots-api 错误示例 · 正确示例 禁止 Vue 3 已移除的 $scopedSlots 实例属性(使用 $slots)
script/no-deprecated-events-api 错误示例 · 正确示例 禁止已移除的 Vue 2 事件 API($on / $off / $once)
script/no-deprecated-props-default-this 错误示例 · 正确示例 禁止在 prop 默认值或校验函数中使用 this(Vue 3 已移除)
script/no-dupe-keys 错误示例 · 正确示例 禁止 Options API 的 props/data/computed/methods/setup/inject 之间重复的键
script/no-duplicate-attr-inheritance 错误示例 · 正确示例 标记重复应用透传属性的组件
script/no-export-in-script-setup 错误示例 · 正确示例 禁止 <script setup> 内的 export 语句
script/no-expose-after-await 错误示例 · 正确示例 禁止在 await 之后调用 expose() 和 defineExpose()
script/no-get-current-instance 错误示例 · 正确示例 禁止在 Vapor 模式使用 getCurrentInstance()(返回 null)
script/no-import-compiler-macros 错误示例 · 正确示例 禁止导入自动可用的 Vue 编译器宏
script/no-internal-imports 错误示例 · 正确示例 禁止从 Vue 内部模块导入
script/no-lifecycle-after-await 错误示例 · 正确示例 禁止在 setup() 中 await 之后注册生命周期钩子
script/no-multiple-slot-args 错误示例 · 正确示例 禁止向作用域插槽函数调用传入多个参数
script/no-next-tick 错误示例 · 正确示例 禁止面向 Vapor 的组件使用 nextTick()
script/no-options-api 错误示例 · 正确示例 禁止 Vapor 模式中的 Options API 模式
script/no-potential-component-option-typo 错误示例 · 正确示例 标记 Options API 组件选项名称中的疑似拼写错误
script/no-reactive-destructure 错误示例 · 正确示例 禁止导致响应性丢失的响应式对象解构
script/no-ref-as-operand 错误示例 · 正确示例 要求将 ref 绑定变量用作操作数时通过 .value 访问
script/no-required-prop-with-default 错误示例 · 正确示例 禁止 prop 同时具有 required: true 和默认值
script/no-reserved-identifiers 错误示例 · 正确示例 禁止使用 Vue 编译器保留标识符
script/no-reserved-keys 错误示例 · 正确示例 禁止将 Vue 保留名称用作 Options API props/data/computed/methods/setup/inject 键
script/no-reserved-props 错误示例 · 正确示例 禁止在组件 props 声明中使用保留名称
script/no-restricted-globals 错误示例 · 正确示例 禁止直接引用必须通过类型化包装器访问的运行时环境全局变量
script/no-restricted-members 错误示例 · 正确示例 禁止项目配置的 object.property 成员访问
script/no-side-effects-in-computed-properties 错误示例 · 正确示例 禁止 Options API 计算 getter 中的副作用
script/no-top-level-ref-in-script 错误示例 · 正确示例 禁止顶层 ref/reactive,以防止跨请求状态污染
script/no-unstable-nested-components 错误示例 · 正确示例 禁止在 setup 或 render 函数内定义组件
script/no-unused-emit-declarations 错误示例 · 正确示例 标记已声明却从未发出的事件
script/no-use-computed-property-like-method 错误示例 · 正确示例 禁止像方法一样调用 Options API 计算属性
script/no-watch-after-await 错误示例 · 正确示例 禁止在 setup() 中 await 之后注册未保留停止句柄的侦听器
script/no-with-defaults 错误示例 · 正确示例 不建议使用 withDefaults,优先使用解构默认值(Vue 3.5+)
script/prefer-computed 错误示例 · 正确示例 响应式派生状态优先使用 computed()
script/prefer-define-options 错误示例 · 正确示例 优先使用 defineOptions(),而不是仅设置 name/inheritAttrs 的普通 <script>
script/prefer-import-from-vue 错误示例 · 正确示例 优先从 'vue' 导入,而不是内部包
script/prefer-ref-over-reactive 错误示例 · 正确示例 建议使用 ref() 而不是 reactive() 管理状态
script/prefer-use-attrs 错误示例 · 正确示例 建议使用 useAttrs() 而不是 context.attrs
script/prefer-use-id 错误示例 · 正确示例 建议使用 useId() 生成唯一 ID(Vue 3.5+)
script/prefer-use-slots 错误示例 · 正确示例 建议使用 useSlots() 而不是 context.slots
script/prefer-use-template-ref 错误示例 · 正确示例 模板引用建议使用 useTemplateRef 而不是 ref(Vue 3.5+)
script/require-default-prop 错误示例 · 正确示例 要求每个可选的非 Boolean prop 具有默认值
script/require-explicit-emits 错误示例 · 正确示例 要求发出的事件在 defineEmits 或 emits 选项中声明
script/require-explicit-slots 错误示例 · 正确示例 要求通过 useSlots() 使用的插槽由 defineSlots<...>() 显式定义类型
script/require-function-return-type 错误示例 · 正确示例 要求函数具有返回类型注解
script/require-prop-type-constructor 错误示例 · 正确示例 要求 prop 的 type 值是构造器,而不是字符串字面量
script/require-prop-types 错误示例 · 正确示例 要求每个 prop 声明类型
script/require-symbol-provide 错误示例 · 正确示例 建议使用 Symbol 作为 provide/inject 的注入键
script/require-typed-object-prop 错误示例 · 正确示例 要求运行时类型为 Object 或 Array 的 prop 具有显式类型
script/require-typed-ref 错误示例 · 正确示例 要求无初始值、null 或 undefined 初始化的 ref() 具有显式类型参数
script/require-valid-default-prop 错误示例 · 正确示例 要求 prop 默认值符合声明类型
script/return-in-computed-property 错误示例 · 正确示例 要求每个计算 getter 返回值
script/return-in-emits-validator 错误示例 · 正确示例 要求每个 Options API emits 校验函数返回值
script/valid-define-emits 错误示例 · 正确示例 要求 defineEmits() 用法有效(不同时提供类型和运行时参数、不引用局部变量、只调用一次)
script/valid-define-options 错误示例 · 正确示例 要求 defineOptions() 用法有效(单个对象参数、不包含 props/emits/expose/slots)
script/valid-define-props 错误示例 · 正确示例 要求 defineProps() 用法有效(只调用一次、不同时提供类型和运行时参数、不引用局部变量)
script/valid-next-tick 错误示例 · 正确示例 要求 nextTick() 调用结果被等待、链式处理,或提供回调
type/no-floating-promises 错误示例 · 正确示例 禁止悬空(未处理)的 Promise
type/no-reactivity-loss 错误示例 · 正确示例 禁止赋值和调用中对响应式值取普通快照
type/no-unsafe-template-binding 错误示例 · 正确示例 禁止解析为不安全类型的模板绑定
type/require-typed-emits 错误示例 · 正确示例 要求 defineEmits 具有类型定义
type/require-typed-props 错误示例 · 正确示例 要求 defineProps 具有类型定义
type/strict-boolean-expressions 错误示例 · 正确示例 要求脚本和模板条件使用安全的布尔表达式

全部规则 · 规则选项 · ESLint 迁移对应表 · 项目检查 · 组件间属性传递

script/component-options-name-casing

要求组件 name 选项使用 PascalCase

错误示例 · 正确示例

默认严重程度: error
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/component-options-name-casing": "error"
      }
    },
  },
});
vp run lint

错误示例

组件选项 name: 'my-component' 使用 kebab-case,但此规则要求名称字面量采用 PascalCase。

<script lang="ts">
export default {
  name: 'my-component' // kebab-case
}
</script>

正确示例

MyComponent 以大写字母开头,且仅包含字母和数字,满足名称检查。

<script lang="ts">
export default {
  name: 'MyComponent'
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/custom-event-name-casing

要求发出的自定义事件名称使用 camelCase

错误示例 · 正确示例

默认严重程度: error
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 参见类型化选项和默认值。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/custom-event-name-casing": "error"
      }
    },
  },
});
vp run lint

错误示例

发出的字符串 my-event 含有连字符,违反默认的 camelCase 事件命名策略。

<script setup lang="ts">
const emit = defineEmits(['my-event'])
emit('my-event')         // kebab-case → report
</script>

正确示例

声明和调用都使用 myEvent,既保持事件名称与发出操作一致,也满足默认大小写策略。配置为 kebab-case 时要求不同。

<script setup lang="ts">
const emit = defineEmits(['myEvent'])
emit('myEvent')
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/define-emits-declaration

要求使用类型形式 defineEmits<{}>(),而不是运行时或数组形式

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-emits-declaration": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineEmits(["change"]) 使用运行时数组声明;此风格规则偏好类型声明。

<script setup lang="ts">
const emit = defineEmits(["change"]);
emit("change", 1);
</script>

正确示例

defineEmits<{ change: [id: number] }>() 将事件声明移到类型参数中,并显式描述 emit("change", 1) 使用的数字载荷。

<script setup lang="ts">
const emit = defineEmits<{ change: [id: number] }>();
emit("change", 1);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/define-macros-order

要求 <script setup> 中的 Vue 编译器宏保持一致的顺序

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 参见类型化选项和默认值。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-macros-order": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineEmits 位于 defineProps 之前,但 <script setup> 必须先写 defineProps,再写 defineEmits。

<script setup lang="ts">
// defineEmits before defineProps
const emit = defineEmits<{ change: [value: string] }>()
const props = defineProps<{ count: number }>()
</script>

正确示例

defineProps 和 defineEmits 依次紧跟在 import 之后、其他所有语句之前;其余宏的顺序不限。

<script setup lang="ts">
import { ref } from 'vue'
const props = defineProps<{ count: number }>()
const emit = defineEmits<{ change: [value: string] }>()
const model = defineModel<string>()
const value = ref(0)
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/define-props-declaration

要求使用类型形式 defineProps<{ ... }>(),而不是运行时或对象形式

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-props-declaration": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineProps({ title: String }) 提供运行时对象,与此规则偏好的类型 props 声明冲突。

<script setup lang="ts">
const props = defineProps({ title: String });
console.log(props.title);
</script>

正确示例

defineProps<{ title: string }>() 在类型参数中声明 title,保留 props.title 访问,无需运行时声明参数。

<script setup lang="ts">
const props = defineProps<{ title: string }>();
console.log(props.title);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/define-props-destructuring

要求 <script setup> 中的 defineProps 解构风格保持一致

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 参见类型化选项和默认值。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/define-props-destructuring": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineProps 被赋给单一的 props 绑定,而非解构,不符合默认的解构偏好。

<script setup lang="ts">
const props = defineProps<{ foo: string }>()
</script>

正确示例

对象模式直接绑定 foo 和 bar,并为可选的 bar 提供默认值。这依赖 Vue 3.5+ 的响应式 props 解构;可配置的 never 模式偏好相反形式。

<script setup lang="ts">
const { foo, bar = 'default' } = defineProps<{ foo: string; bar?: string }>()
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-arrow-functions-in-watch

禁止将箭头函数用作 Options API watch 处理器

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-arrow-functions-in-watch": "error"
      }
    },
  },
});
vp run lint

错误示例

Options API 侦听器 value 和嵌套的 other.handler 都是箭头函数。箭头函数捕获外层 this,不会接收组件实例。

<script lang="ts">
export default {
  watch: {
    // `this` is not the component instance inside an arrow function.
    value: () => {
      this.doSomething()
    },
    other: {
      handler: () => {}
    }
  }
}
</script>

正确示例

两个处理器改为普通方法,使 Vue 能将 this 绑定到组件。deep: true 侦听选项仍与对象形式兼容。

<script lang="ts">
export default {
  watch: {
    value(newValue, oldValue) {
      this.doSomething()
    },
    other: {
      handler(newValue) {},
      deep: true
    }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-async-in-computed

禁止计算属性中的异步函数

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-async-in-computed": "error"
      }
    },
  },
});
vp run lint

错误示例

computed getter 使用 async,因此 fetch 产生 Promise,而不是同步派生的计算值。

<script setup lang="ts">
import { computed } from "vue";
const data = computed(async () => {
  const response = await fetch("/api/data");
  return response.json();
});
</script>

正确示例

异步 fetch 移到 watch,将结果存入 data.value。清理逻辑中止旧请求,并阻止失效回调写入过期结果;不再存在异步计算 getter。

<script setup lang="ts">
import { ref, watch } from "vue";
const query = ref("");
const data = ref<unknown>(null);
watch(query, async (value, _oldValue, onCleanup) => {
  const controller = new AbortController();
  let active = true;
  onCleanup(() => { active = false; controller.abort(); });
  const response = await fetch(`/api/data?q=${encodeURIComponent(value)}`, { signal: controller.signal });
  const next: unknown = await response.json();
  if (active) data.value = next;
});
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-boolean-default

禁止为 Boolean prop 设置默认值

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-boolean-default": "warn"
      }
    },
  },
});
vp run lint

错误示例

disabled 和 checked 都为唯一构造器为 Boolean 的 prop 声明了 default;规则连显式的 false 默认值也会拒绝。

<script lang="ts">
export default {
  props: {
    // Boolean props already default to false; an explicit default is confusing.
    disabled: { type: Boolean, default: true },
    checked: { type: Boolean, default: false }
  }
}
</script>

正确示例

仅 Boolean 的 props 省略 default,使用 Vue 隐式的 false 值。[Boolean, String] 联合类型和 Number prop 说明此检查仅限唯一的 Boolean 构造器。

<script lang="ts">
export default {
  props: {
    // No explicit default: defaults to false.
    disabled: { type: Boolean },
    disabled2: Boolean,
    // Union type may legitimately need a default.
    value: { type: [Boolean, String], default: '' },
    // Non-Boolean prop.
    count: { type: Number, default: 0 }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deep-destructure-in-props

禁止在 defineProps 中进行深层嵌套解构

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deep-destructure-in-props": "warn"
      }
    },
  },
});
vp run lint

错误示例

绑定模式进入 user 解构 name,超过默认的浅层 props 解构深度。

<script setup lang="ts">
const { user: { name } } = defineProps<{ user: { name: string } }>();
</script>

正确示例

props 对象保持完整,由计算 getter 读取 props.user.name。嵌套访问保持显式,不使用深层嵌套绑定模式。

<script setup lang="ts">
import { computed } from "vue";
const props = defineProps<{ user: { name: string } }>();
const userName = computed(() => props.user.name);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-data-object-declaration

禁止将对象字面量作为组件 data 选项(Vue 3 要求函数)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-data-object-declaration": "error"
      }
    },
  },
});
vp run lint

错误示例

Options API 的 data 选项是对象字面量,这是 Vue 3 不再接受的 Vue 2 形式。

<script lang="ts">
export default {
  // `data` must be a function in Vue 3, not an object literal.
  data: {
    count: 0
  }
}
</script>

正确示例

data() 返回新的 { count: 0 } 对象,提供 Vue 3 所需的函数式 data 声明。

<script lang="ts">
export default {
  data() {
    return { count: 0 }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-destroyed-lifecycle

禁止已弃用的 destroyed 和 beforeDestroy 生命周期钩子

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-destroyed-lifecycle": "error"
      }
    },
  },
});
vp run lint

错误示例

定时器清理使用了已移除的 Vue 2 生命周期选项 beforeDestroy。

<script lang="ts">
export default { beforeDestroy() { clearTimeout(this.timer); } };
</script>

正确示例

将钩子重命名为 beforeUnmount,在 Vue 3 生命周期名称下保留清理函数体。

<script lang="ts">
export default { beforeUnmount() { clearTimeout(this.timer); } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-dollar-listeners-api

禁止 Vue 3 已移除的 $listeners 实例属性(已合并到 $attrs)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-dollar-listeners-api": "error"
      }
    },
  },
});
vp run lint

错误示例

成员读取和独立参数引用都使用 $listeners,Vue 3 在将监听器合并到属性后移除了它。

<script>
export default {
  mounted() {
    const vm = this
    return vm.$listeners
  }
}
</script>
<template><Child v-on="$listeners" /></template>

正确示例

读取改为 this.$attrs 和 setup 上下文的 ctx.attrs,替代已移除的监听器接口;示例中的接收对象必须存在于周围组件上下文。

<script>
export default {
  mounted() {
    return this.$attrs
  }
}
</script>
<template><Child v-bind="$attrs" /></template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-dollar-scopedslots-api

禁止 Vue 3 已移除的 $scopedSlots 实例属性(使用 $slots)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-dollar-scopedslots-api": "error"
      }
    },
  },
});
vp run lint

错误示例

this.$scopedSlots、ctx.$scopedSlots 和独立的 $scopedSlots 引用使用了 Vue 3 已移除的 Vue 2 作用域插槽 API。

<script setup lang="ts">
const header = this.$scopedSlots.header
const footer = ctx.$scopedSlots.footer
render($scopedSlots.default)
</script>

正确示例

将 $scopedSlots 替换为 $slots,使用统一插槽接口。示例移除弃用写法,并未为接收对象建立 setup 上下文。

<script setup lang="ts">
const header = this.$slots.header
const footer = ctx.$slots.footer
render($slots.default)
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-events-api

禁止已移除的 Vue 2 事件 API($on / $off / $once)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-events-api": "error"
      }
    },
  },
});
vp run lint

错误示例

$on、$once 和 $off 调用使用了 Vue 3 已移除的实例事件总线方法。

<script>
export default {
  mounted() {
    this.$on('event', handler)
    const vm = this
    vm.$once('event', handler)
    this.$off('event', handler)
  }
}
</script>

正确示例

$emit 仍然有效,事件总线订阅则移到外部发射器的 on 方法。修复区分面向父组件的事件发出与外部事件总线。

<script>
import mitt from 'mitt'
const emitter = mitt()
export default {
  mounted() {
    this.$emit('event', payload)
    emitter.on('event', handler)
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-deprecated-props-default-this

禁止在 prop 默认值或校验函数中使用 this(Vue 3 已移除)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-deprecated-props-default-this": "error"
      }
    },
  },
});
vp run lint

错误示例

prop 默认值和校验函数读取 this,但在 Vue 3 中这些函数不能依赖组件实例。

<script lang="ts">
export default {
  props: {
    size: {
      type: Number,
      // `this` is not the component instance in Vue 3.
      default() {
        return this.defaultSize
      }
    },
    value: {
      type: Number,
      validator() {
        return this.value > 0
      }
    }
  }
}
</script>

正确示例

默认值从参数读取 props.baseSize,校验函数检查 value 参数。两者都不再依赖不可用的实例接收对象。

<script lang="ts">
export default {
  props: {
    size: {
      type: Number,
      // Vue 3 passes the raw props as the first argument instead.
      default(props) {
        return props.baseSize
      }
    },
    value: {
      type: Number,
      validator(value) {
        return value > 0
      }
    }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-dupe-keys

禁止 Options API 的 props/data/computed/methods/setup/inject 之间重复的键

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-dupe-keys": "error"
      }
    },
  },
});
vp run lint

错误示例

props 和 data 都声明 foo,computed 和 methods 都声明 bar。这些声明竞争相同的组件实例键。

<script lang="ts">
export default {
  props: ['foo'],
  data() {
    return { foo: 1 } // duplicate of prop `foo`
  },
  computed: {
    bar() { return 2 }
  },
  methods: {
    bar() {} // duplicate of computed `bar`
  }
}
</script>

正确示例

prop、data 和 computed 声明使用不同名称(foo、bar 和 baz),消除两处跨选项冲突。

<script lang="ts">
export default {
  props: ['foo'],
  data() {
    return { bar: 1 }
  },
  computed: {
    baz() { return 2 }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-duplicate-attr-inheritance

标记重复应用透传属性的组件

错误示例 · 正确示例

默认严重程度: warning
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-duplicate-attr-inheritance": "warn"
      }
    },
  },
});
vp run lint

错误示例

显式 inheritAttrs: true 重复了 Vue 的默认值。即使没有展示根节点 $attrs 展开,规则也会报告此多余字面量。

<script setup></script>
<template><div><button v-bind="$attrs">Save</button></div></template>

正确示例

inheritAttrs: false 表达实际的退出选择,空选项对象则隐式保留默认继承。两者都不重复多余的 true。

<script setup>defineOptions({ inheritAttrs: false })</script>
<template><div><button v-bind="$attrs">Save</button></div></template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-export-in-script-setup

禁止 <script setup> 内的 export 语句

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-export-in-script-setup": "error"
      }
    },
  },
});
vp run lint

错误示例

export const count 试图从 <script setup> 暴露模块导出,但这里禁止运行时导出。

<script setup lang="ts">
export const count = 1;
</script>

正确示例

移除 export,使 count 保持为 setup 绑定,而非模块导出。

<script setup lang="ts">
const count = 1;
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-expose-after-await

禁止在 await 之后调用 expose() 和 defineExpose()

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-expose-after-await": "error"
      }
    },
  },
});
vp run lint

错误示例

defineExpose() 在顶层 await 之后执行,此时没有当前组件实例,因此不会暴露任何内容。

<script setup lang="ts">
await loadData()
defineExpose({ reload })
</script>

正确示例

defineExpose() 在第一个 await 之前执行,此时组件实例仍是当前实例。

<script setup lang="ts">
defineExpose({ reload })
await loadData()
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-get-current-instance

禁止在 Vapor 模式使用 getCurrentInstance()(返回 null)

错误示例 · 正确示例

默认严重程度: error
预设: opinionated
自动修复: 无;请检查建议的修改
适用范围: 面向 Vapor 的脚本检查;显式启用后,限制也适用于普通脚本
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-get-current-instance": "error"
      }
    },
  },
});
vp run lint

错误示例

带 Vapor 标记的 setup 导入并调用 getCurrentInstance,依赖了此规则针对 Vapor 组件禁止的实例 API。

<script setup lang="ts" vapor>
import { getCurrentInstance } from "vue";
const instance = getCurrentInstance();
</script>

正确示例

inject("app-config") 获取显式提供的配置,无需导入或调用 getCurrentInstance。

<script setup lang="ts" vapor>
import { inject } from "vue";
const appConfig = inject("app-config");
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-import-compiler-macros

禁止导入自动可用的 Vue 编译器宏

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-import-compiler-macros": "error"
      }
    },
  },
});
vp run lint

错误示例

vue 导入包含 defineProps 和 defineEmits,但这些编译器宏已在 <script setup> 中直接可用。

<script setup lang="ts">
import { defineProps, defineEmits } from "vue";
const props = defineProps<{ title: string }>();
const emit = defineEmits<{ save: [id: number] }>();
</script>

正确示例

移除宏导入,保留两个带类型的宏调用;两种声明都无需运行时导入。

<script setup lang="ts">
const props = defineProps<{ title: string }>();
const emit = defineEmits<{ save: [id: number] }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-internal-imports

禁止从 Vue 内部模块导入

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-internal-imports": "error"
      }
    },
  },
});
vp run lint

错误示例

两个导入都指向内部 dist 文件,而非 Vue 公共包入口,使组件与构建文件路径耦合。

<script setup lang="ts">
import { foo } from '@vue/runtime-core/dist/runtime-core.esm-bundler'
import { bar } from 'vue/dist/vue.esm-bundler'
</script>

正确示例

从 vue 导入所需辅助函数,移除对内部发行文件位置的依赖。

<script setup lang="ts">
import { ref, computed } from 'vue'
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-lifecycle-after-await

禁止在 setup() 中 await 之后注册生命周期钩子

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-lifecycle-after-await": "error"
      }
    },
  },
});
vp run lint

错误示例

setup() 在 await loadData() 之后调用 onMounted();此时没有当前组件实例,钩子不会被注册。

<script lang="ts">
import { onMounted } from 'vue'
export default {
  async setup() {
    await loadData()
    onMounted(() => {})
  },
}
</script>

正确示例

onMounted() 在第一个 await 之前注册,此时 setup() 仍在为组件同步执行。

<script lang="ts">
import { onMounted } from 'vue'
export default {
  async setup() {
    onMounted(() => {})
    await loadData()
  },
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-multiple-slot-args

禁止向作用域插槽函数调用传入多个参数

错误示例 · 正确示例

默认严重程度: warning
预设: happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-multiple-slot-args": "warn"
      }
    },
  },
});
vp run lint

错误示例

插槽调用传入多个位置参数,或展开未知参数列表。Vue 插槽接收一个 props 对象,而非位置参数列表。

<script setup lang="ts">
slots.default(foo, bar)
$slots.header(a, b)
this.$scopedSlots.item(x, y)
useSlots().default(a, b)
slots.default(...args)
</script>

正确示例

{ foo, bar } 将数据合并为一个参数;slotProps 和无参数调用也符合支持的插槽调用形式。

<script setup lang="ts">
slots.default({ foo, bar })
slots.default(slotProps)
slots.default()
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-next-tick

禁止面向 Vapor 的组件使用 nextTick()

错误示例 · 正确示例

默认严重程度: error
预设: none
自动修复: 无;请检查建议的修改
适用范围: 面向 Vapor 的脚本检查;显式启用后,限制也适用于普通脚本
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-next-tick": "error"
      }
    },
  },
});
vp run lint

错误示例

面向 Vapor 的组件导入并等待 nextTick,引入此迁移规则拒绝的 DOM 刷新调度依赖。

<script setup lang="ts" vapor>
import { nextTick } from "vue";
await nextTick();
</script>

正确示例

通过 useTemplateRef 获取输入框,并在 onMounted 时聚焦。显式挂载边界替代示例中的 nextTick 依赖。

<script setup lang="ts" vapor>
import { onMounted, useTemplateRef } from "vue";
const input = useTemplateRef<HTMLInputElement>("input");
onMounted(() => { input.value?.focus(); });
</script>
<template><input ref="input"></template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-options-api

禁止 Vapor 模式中的 Options API 模式

错误示例 · 正确示例

默认严重程度: error
预设: opinionated
自动修复: 无;请检查建议的修改
适用范围: 面向 Vapor 的脚本检查;显式启用后,限制也适用于普通脚本
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-options-api": "error"
      }
    },
  },
});
vp run lint

错误示例

默认导出对象声明了 Options API 的 data(),这是此规则禁止的组件选项形式。

<script lang="ts">
export default {
  data() {
    return { count: 0 };
  },
};
</script>

正确示例

组件状态改为 Vapor <script setup> 中的 Composition API ref,移除 Options API 对象及其 data 选项。

<script setup lang="ts" vapor>
const count = ref(0);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-potential-component-option-typo

标记 Options API 组件选项名称中的疑似拼写错误

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-potential-component-option-typo": "error"
      }
    },
  },
});
vp run lint

错误示例

选项被写为 method,与受识别的 methods 选项只差一次编辑;Vue 不会将它视为预期的方法声明。

<script lang="ts">
export default { method: { save() {} } };
</script>

正确示例

将键改为 methods,使 save() 位于受识别的组件选项下。

<script lang="ts">
export default { methods: { save() {} } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-reactive-destructure

禁止导致响应性丢失的响应式对象解构

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reactive-destructure": "warn"
      }
    },
  },
});
vp run lint

错误示例

const { count, name } = state 从 reactive 对象复制原始类型属性,失去与后续属性变化的联系。

<script setup lang="ts">
import { reactive } from "vue";
const state = reactive({ count: 0, name: "Ada" });
const { count, name } = state;
</script>

正确示例

解构 toRefs(state) 为 count 和 name 创建 refs,使每个绑定继续关联原始响应式属性。

<script setup lang="ts">
import { reactive, toRefs } from "vue";
const state = reactive({ count: 0, name: "Ada" });
const { count, name } = toRefs(state);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-ref-as-operand

要求将 ref 绑定变量用作操作数时通过 .value 访问

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-ref-as-operand": "error"
      }
    },
  },
});
vp run lint

错误示例

count + 1 将 ref 对象本身用作算术操作数,而不是其包裹的数字。

<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
const next = count + 1;
</script>

正确示例

count.value + 1 先读取包裹的数字,再加一;脚本算术需要此显式 ref 访问。

<script setup lang="ts">
import { ref } from "vue";
const count = ref(0);
const next = count.value + 1;
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-required-prop-with-default

禁止 prop 同时具有 required: true 和默认值

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-required-prop-with-default": "error"
      }
    },
  },
});
vp run lint

错误示例

title 既是必需项,又具有后备值 "Untitled",混合了必需输入约定和面向缺失输入的默认值。

<script lang="ts">
export default { props: { title: { type: String, required: true, default: "Untitled" } } };
</script>

正确示例

移除 required: true,使 title 可选,并保留 "Untitled" 作为一致的后备值。

<script lang="ts">
export default { props: { title: { type: String, default: "Untitled" } } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-reserved-identifiers

禁止使用 Vue 编译器保留标识符

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-identifiers": "error"
      }
    },
  },
});
vp run lint

错误示例

绑定 __props、__emit 和 __sfc__ 使用了为 Vue 编译器生成代码保留的标识符。

<script setup lang="ts">
const __props = { name: "Ada" };
const __emit = () => {};
const __sfc__ = {};
</script>

正确示例

普通名称 props、emit 和 componentData 避开这些生成标识符,同时保留 props 和 emits 声明。

<script setup lang="ts">
const props = defineProps<{ name: string }>();
const emit = defineEmits<{ save: [] }>();
const componentData = {};
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-reserved-keys

禁止将 Vue 保留名称用作 Options API props/data/computed/methods/setup/inject 键

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-keys": "error"
      }
    },
  },
});
vp run lint

错误示例

返回的 data 键 $el 与 Vue 内置组件实例属性冲突,也使用了保留的 $ 前缀。

<script lang="ts">
export default { data() { return { $el: "custom" }; } };
</script>

正确示例

将应用数据重命名为 elementLabel,避开内置实例接口和保留前缀。

<script lang="ts">
export default { data() { return { elementLabel: "custom" }; } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-reserved-props

禁止在组件 props 声明中使用保留名称

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-reserved-props": "error"
      }
    },
  },
});
vp run lint

错误示例

对象形式的 ref 和 $foo,以及数组形式的 key,都是保留 prop 名称。ref 和 key 是框架控制项,带 $ 前缀的名称也会被拒绝。

<script lang="ts">
export default {
  props: {
    ref: String,   // reserved
    $foo: Number    // `$`-prefixed names are reserved
  }
}

export default {
  props: ['key']    // reserved (array form)
}
</script>

正确示例

普通 prop 名称 name 和 refValue 在拼写及前缀上都避开了保留名称。

<script lang="ts">
export default {
  props: {
    name: String,
    refValue: Number
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-restricted-globals

禁止直接引用必须通过类型化包装器访问的运行时环境全局变量

错误示例 · 正确示例

默认严重程度: error
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 参见类型化选项和默认值。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-restricted-globals": "error"
      }
    },
  },
});
vp run lint

错误示例

示例直接读取默认受限全局变量 process、localStorage 和 sessionStorage,绕过项目显式的配置和存储辅助函数。

<script setup lang="ts">
const flag = process.env.FEATURE_FLAG
const token = localStorage.getItem('auth.token')
sessionStorage.setItem('view.scroll', String(window.scrollY))
</script>

正确示例

useFeatureFlag、authStorage.read 和 viewStorage.write 移除了这些直接引用。剩余的 window.scrollY 不是规则的默认限制;SSR 安全是独立问题。

<script setup lang="ts">
// Use a typed config helper that distinguishes server vs. client.
const flag = useFeatureFlag('FEATURE_FLAG')

// Use a typed wrapper that scopes keys and handles SSR / disabled storage.
const token = authStorage.read('auth.token')
viewStorage.write('view.scroll', String(window.scrollY))
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-restricted-members

禁止项目配置的 object.property 成员访问

错误示例 · 正确示例

默认严重程度: error
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 参见类型化选项和默认值。

此示例配置 window.localStorage。规则没有默认拒绝列表;仅启用规则不会报告成员。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-restricted-members": "error"
      },
      "ruleOptions": {
        "script/no-restricted-members": {
          "members": [
            {
              "object": "window",
              "property": "localStorage"
            }
          ]
        }
      }
    },
  },
});
vp run lint

错误示例

在 ruleOptions 中配置 { object: "window", property: "localStorage" } 后,window.localStorage 访问了禁止的对象与成员组合。规则没有默认禁止成员。

<script setup lang="ts">
const token = window.localStorage.getItem("token");
</script>

正确示例

authStorage.read("token") 将读取交给应用存储辅助函数,不再访问配置禁止的 window.localStorage 成员。

<script setup lang="ts">
const token = authStorage.read("token");
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-side-effects-in-computed-properties

禁止 Options API 计算 getter 中的副作用

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-side-effects-in-computed-properties": "error"
      }
    },
  },
});
vp run lint

错误示例

doubled 赋值给 this.count,reversed 通过 reverse() 修改 this.items。两个 getter 都修改了本应只用于派生的状态。

<script lang="ts">
export default {
  data() {
    return { count: 0, items: [] }
  },
  computed: {
    doubled() {
      this.count = this.count * 2 // side effect: assigns to data
      return this.count
    },
    reversed() {
      return this.items.reverse() // side effect: mutates the array
    }
  }
}
</script>

正确示例

doubled 返回乘法结果,不进行赋值。reversed 先复制数组再反转,getter 不会改变原组件状态。

<script lang="ts">
export default {
  data() {
    return { count: 0, items: [] }
  },
  computed: {
    doubled() {
      return this.count * 2
    },
    reversed() {
      return [...this.items].reverse() // operate on a copy
    }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-top-level-ref-in-script

禁止顶层 ref/reactive,以防止跨请求状态污染

错误示例 · 正确示例

默认严重程度: error
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-top-level-ref-in-script": "error"
      }
    },
  },
});
vp run lint

错误示例

普通 <script> 在模块作用域初始化 count 和 user。SSR 期间,这些状态对象可能跨组件实例和请求共享。

<script>
// This state is shared across all requests in SSR!
const count = ref(0)
const user = reactive({ name: '' })

export default {
  setup() {
    return { count, user }
  }
}
</script>

正确示例

setup ref 按组件实例初始化;普通脚本只保留常量、生成状态的函数,以及 setup() 内创建的 ref。都不会在普通模块作用域创建响应式状态。

<script setup>
// Script setup creates fresh state per request
const count = ref(0)
</script>

<script>
// Constants are fine
const API_URL = 'https://api.example.com'

// Functions that create state are fine
function createState() {
  return reactive({ count: 0 })
}

export default {
  setup() {
    // Create state inside setup
    const count = ref(0)
    return { count }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-unstable-nested-components

禁止在 setup 或 render 函数内定义组件

错误示例 · 正确示例

默认严重程度: warning
预设: happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-unstable-nested-components": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineComponent 在父组件的 setup() 内运行,每次执行 setup 都创建新的 Child 组件定义。

<script lang="ts">
import { defineComponent } from "vue";
export default { setup() { const Child = defineComponent({ render() { return null; } }); return { Child }; } };
</script>

正确示例

Child 定义移到模块作用域,setup() 返回已存在的定义。

<script lang="ts">
import { defineComponent } from "vue";
const Child = defineComponent({ render() { return null; } });
export default { setup() { return { Child }; } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-unused-emit-declarations

标记已声明却从未发出的事件

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-unused-emit-declarations": "warn"
      }
    },
  },
});
vp run lint

错误示例

defineEmits 声明了 change 和 unused,但捕获的 emit 函数只发出字面量事件 change。

<script setup lang="ts">
const emit = defineEmits(['change', 'unused'])
emit('change')
// `unused` is never emitted
</script>

正确示例

移除 unused,使声明的事件列表与观察到的发出操作一致。示例使用捕获且未逸出的 emit 绑定,因此可以得出此局部使用结论。

<script setup lang="ts">
const emit = defineEmits(['change'])
emit('change')
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-use-computed-property-like-method

禁止像方法一样调用 Options API 计算属性

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-use-computed-property-like-method": "error"
      }
    },
  },
});
vp run lint

错误示例

this.total() 调用了计算 getter 暴露的值;getter 返回不可调用的 3。

<script lang="ts">
export default { computed: { total() { return 3; } }, methods: { log() { console.log(this.total()); } } };
</script>

正确示例

this.total 不加调用括号,直接读取计算值,使 log 打印派生数字。

<script lang="ts">
export default { computed: { total() { return 3; } }, methods: { log() { console.log(this.total); } } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-watch-after-await

禁止在 setup() 中 await 之后注册未保留停止句柄的侦听器

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-watch-after-await": "error"
      }
    },
  },
});
vp run lint

错误示例

watch() 在 await loadData() 之后创建且丢弃了停止句柄,因此侦听器不会随组件一起停止。

<script lang="ts">
import { watch } from 'vue'
export default {
  async setup(props) {
    await loadData()
    watch(() => props.id, reload)
  },
}
</script>

正确示例

侦听器在第一个 await 之前创建,因此组件卸载时 Vue 会停止它。

<script lang="ts">
import { watch } from 'vue'
export default {
  async setup(props) {
    watch(() => props.id, reload)
    await loadData()
  },
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/no-with-defaults

不建议使用 withDefaults,优先使用解构默认值(Vue 3.5+)

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/no-with-defaults": "warn"
      }
    },
  },
});
vp run lint

错误示例

withDefaults 包装带类型的 props 声明,仅为 count 和 name 提供默认值,没有使用此处偏好的 Vue 3.5+ 解构默认值风格。

<script setup lang="ts">
const props = withDefaults(defineProps<{ count?: number; name?: string }>(), { count: 0, name: "Ada" });
</script>

正确示例

解构模式将 count = 0 和 name = "Ada" 放在对应绑定旁,并移除 withDefaults 包装。

<script setup lang="ts">
const { count = 0, name = "Ada" } = defineProps<{ count?: number; name?: string }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-computed

响应式派生状态优先使用 computed()

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

此情形要求侦听器仅派生目标值。可编辑副本及具有其他副作用的回调被允许。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-computed": "warn"
      }
    },
  },
});
vp run lint

错误示例

侦听器仅将 count 的派生值复制到第二个 ref doubled,通过手动同步维护派生状态。

<script setup lang="ts">
import { ref, watch } from "vue";
const count = ref(0);
const doubled = ref(0);
watch(count, (value) => { doubled.value = value * 2; });
</script>

正确示例

computed(() => count.value * 2) 直接表达派生关系,移除额外可写 ref 及其同步侦听器。

<script setup lang="ts">
import { ref, computed } from "vue";
const count = ref(0);
const doubled = computed(() => count.value * 2);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-define-options

优先使用 defineOptions(),而不是仅设置 name/inheritAttrs 的普通 <script>

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-define-options": "warn"
      }
    },
  },
});
vp run lint

错误示例

普通脚本唯一有实质作用的语句导出只含 name 和 inheritAttrs 的对象;这些选项可通过 defineOptions 表达。

<script lang="ts">
export default { name: 'MyComponent', inheritAttrs: false }
</script>

正确示例

示例中的 data() 方法让脚本包含实际 Options API 逻辑,因此不在此规则保守的仅选项建议范围内。此正确示例展示允许的例外;直接迁移则应在 <script setup> 中使用 defineOptions({ name: 'MyComponent', inheritAttrs: false })。

<script lang="ts">
// Real options logic — keep the plain script.
export default {
  name: 'MyComponent',
  data() { return { count: 0 } },
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-import-from-vue

优先从 'vue' 导入,而不是内部包

错误示例 · 正确示例

默认严重程度: warning
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-import-from-vue": "warn"
      }
    },
  },
});
vp run lint

错误示例

ref 和 h 从内部 @vue/runtime-core 和 @vue/runtime-dom 包导入,而不是公共 vue 包。

<script setup lang="ts">
import { ref } from '@vue/runtime-core'
import { h } from '@vue/runtime-dom'
</script>

正确示例

公共辅助函数从 vue 导入。vue 未公开的 isString 保留 @vue/shared。命名空间、默认及公共与私有混合导入保留警告,但不提供自动修复。

<script setup lang="ts">
import { ref, h } from 'vue'
import { isString } from '@vue/shared'
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-ref-over-reactive

建议使用 ref() 而不是 reactive() 管理状态

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-ref-over-reactive": "warn"
      }
    },
  },
});
vp run lint

错误示例

状态通过 reactive 创建,不符合此主张型规则对 refs 的偏好。示例展示风格偏好,并非响应式对象本身无效。

<script setup lang="ts">
// reactive requires careful handling to avoid losing reactivity
const state = reactive({
  count: 0,
  name: 'foo'
})
</script>

正确示例

示例通过 ref 创建标量和对象状态;相关字段也可拆为独立 refs,满足偏好的状态构造形式。

<script setup lang="ts">
// ref is more explicit and safer
const count = ref(0)
const name = ref('foo')

// For objects, ref still works
const user = ref({ name: 'foo', age: 20 })

// Or use multiple refs for related data
const userName = ref('foo')
const userAge = ref(20)
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-use-attrs

建议使用 useAttrs() 而不是 context.attrs

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-attrs": "warn"
      }
    },
  },
});
vp run lint

错误示例

setup 通过解构上下文参数获取 attrs,规则要求改用 Composition API 辅助函数。

<script lang="ts">
export default { setup(_props, { attrs }) { console.log(attrs.class); } };
</script>

正确示例

useAttrs() 在 setup 内提供 attrs,保留 attrs.class 读取,不依赖第二个 setup 参数。

<script lang="ts">
import { useAttrs } from "vue";
export default { setup() { const attrs = useAttrs(); console.log(attrs.class); } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-use-id

建议使用 useId() 生成唯一 ID(Vue 3.5+)

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-id": "warn"
      }
    },
  },
});
vp run lint

错误示例

id 包含 Math.random(),生成的输入框与标签标识符可能在服务端和客户端渲染时不同。以 ID 命名的绑定是规则可识别的生成上下文。

<script setup lang="ts">
const id = `input-${Math.random()}`;
</script>
<template><label :for="id">Name</label><input :id="id" /></template>

正确示例

Vue 3.5+ 的 useId() 生成标识符,:for 和 :id 继续读取同一绑定,不再分别生成随机值。

<script setup lang="ts">
import { useId } from "vue";
const id = useId();
</script>
<template><label :for="id">Name</label><input :id="id" /></template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-use-slots

建议使用 useSlots() 而不是 context.slots

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-slots": "warn"
      }
    },
  },
});
vp run lint

错误示例

setup 从上下文参数解构 slots,这是此规则建议替换的访问形式。

<script lang="ts">
import { defineComponent, h } from "vue";
export default defineComponent({
  setup(_props, { slots }) { return () => h("div", slots.default?.()); },
});
</script>

正确示例

useSlots() 在 setup 内获取插槽,保留渲染函数及可选默认插槽调用,不使用上下文参数。

<script lang="ts">
import { defineComponent, h, useSlots } from "vue";
export default defineComponent({
  setup() {
    const slots = useSlots();
    return () => h("div", slots.default?.());
  },
});
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/prefer-use-template-ref

模板引用建议使用 useTemplateRef 而不是 ref(Vue 3.5+)

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/prefer-use-template-ref": "warn"
      }
    },
  },
});
vp run lint

错误示例

可为空的 input ref 与模板字面量 ref="input" 配对,表明它是元素引用,而非普通可空数据。

<script setup lang="ts">
import { ref } from 'vue'
const input = ref<HTMLInputElement | null>(null)
</script>
<template>
  <input ref="input" />
</template>

正确示例

Vue 3.5+ 的 useTemplateRef<HTMLInputElement>('input') 显式表达模板引用。未配对的 error = ref(null) 仍是普通数据,有意不在此规则范围内。

<script setup lang="ts">
import { ref, useTemplateRef } from 'vue'
// Paired with the template ref below.
const input = useTemplateRef<HTMLInputElement>('input')
// A nullable data ref the template never binds as a ref.
const error = ref(null)
</script>
<template>
  <input ref="input" />
  <p>{{ error }}</p>
</template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-default-prop

要求每个可选的非 Boolean prop 具有默认值

错误示例 · 正确示例

默认严重程度: error
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-default-prop": "error"
      }
    },
  },
});
vp run lint

错误示例

name 和 age 是没有默认值的可选非 Boolean 运行时 props,省略输入时的值未指定。

<script lang="ts">
export default {
  props: {
    // optional, non-Boolean, no default
    name: String,
    age: { type: Number },
  }
}
</script>

正确示例

name 获得 default: ''。enabled 使用 Boolean 隐式的 false 默认值,必需的 id 无需后备值,展示了两种豁免。

<script lang="ts">
export default {
  props: {
    name: { type: String, default: '' },
    enabled: Boolean,                 // Boolean defaults to false
    id: { type: Number, required: true },
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-explicit-emits

要求发出的事件在 defineEmits 或 emits 选项中声明

错误示例 · 正确示例

默认严重程度: warning
预设: happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-explicit-emits": "warn"
      }
    },
  },
});
vp run lint

错误示例

捕获的 emit 函数发出 save,但 defineEmits([]) 未声明该事件。

<script setup lang="ts">
const emit = defineEmits([]);
emit("save");
</script>

正确示例

在声明中添加 "save",使发出的字面量事件成为组件显式事件约定的一部分。

<script setup lang="ts">
const emit = defineEmits(["save"]);
emit("save");
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-explicit-slots

要求通过 useSlots() 使用的插槽由 defineSlots<...>() 显式定义类型

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-explicit-slots": "warn"
      }
    },
  },
});
vp run lint

错误示例

带类型的 defineProps<{ id: number }>() 确立了 TypeScript 语法,但 setup 使用 useSlots() 而没有 defineSlots 声明,因此规则发现缺少显式插槽约定。

<script setup lang="ts">
const props = defineProps<{ id: number }>()
const slots = useSlots()
</script>

正确示例

defineSlots 声明 props 含 msg: string 的 default 插槽;useSlots() 现在配有显式的类型化插槽约定。

<script setup lang="ts">
defineSlots<{ default(props: { msg: string }): unknown }>()
const slots = useSlots()
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-function-return-type

要求函数具有返回类型注解

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-function-return-type": "warn"
      }
    },
  },
});
vp run lint

错误示例

add 和 greet 都注解了参数,却省略返回类型注解;推断返回类型不满足此显式注解策略。

<script setup lang="ts">
const add = (a: number, b: number) => {
  return a + b
}

function greet(name: string) {
  return `Hello, ${name}`
}
</script>

正确示例

add 声明 : number,greet 声明 : string,明确返回约定而不改变函数体。

<script setup lang="ts">
const add = (a: number, b: number): number => {
  return a + b
}

function greet(name: string): string {
  return `Hello, ${name}`
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-prop-type-constructor

要求 prop 的 type 值是构造器,而不是字符串字面量

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-prop-type-constructor": "error"
      }
    },
  },
});
vp run lint

错误示例

prop 声明将字符串 "String" 和 "Number" 用作运行时类型,包括构造器数组内的值。这些字符串不是构造函数。

<script lang="ts">
export default {
  props: {
    // The type should be the `String` constructor, not the string "String".
    name: "String",
    age: { type: "Number" },
    id: { type: ["String", "Number"] }
  }
}
</script>

正确示例

声明使用实际的 String 和 Number 标识符,包括联合数组 [String, Number]。

<script lang="ts">
export default {
  props: {
    name: String,
    age: { type: Number },
    id: { type: [String, Number] }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-prop-types

要求每个 prop 声明类型

错误示例 · 正确示例

默认严重程度: error
预设: opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-prop-types": "error"
      }
    },
  },
});
vp run lint

错误示例

数组项只声明名称 status;null 值和空描述对象也没有声明运行时 prop 类型。

<script lang="ts">
export default {
  props: ['status']            // array form: no types
}

export default {
  props: {
    status: null,              // no type
    other: {}                  // empty descriptor: no type
  }
}
</script>

正确示例

status: String 提供简写构造器,other 在描述对象内提供 type: Number,两个 props 现在都有类型声明。

<script lang="ts">
export default {
  props: {
    status: String,
    other: { type: Number, default: 0 }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-symbol-provide

建议使用 Symbol 作为 provide/inject 的注入键

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-symbol-provide": "warn"
      }
    },
  },
});
vp run lint

错误示例

provide 和 inject 使用 'user'、'theme' 等字符串字面量键,可能与同名的其他提供者冲突。

<script setup lang="ts">
// String keys can collide
provide('user', user)
const user = inject('user')

// Magic strings are error-prone
provide('theme', { dark: true })
</script>

正确示例

共享的 UserKey 通过 Symbol 创建,并注解为 InjectionKey<User>;两个调用都传入该键,而非字符串字面量。

<script lang="ts">
// Define injection key with Symbol
export const UserKey: InjectionKey<User> = Symbol('user')

// Provide with Symbol
provide(UserKey, user)

// Inject with Symbol
const user = inject(UserKey)
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-typed-object-prop

要求运行时类型为 Object 或 Array 的 prop 具有显式类型

错误示例 · 正确示例

默认严重程度: warning
预设: opinionated, nuxt
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-typed-object-prop": "warn"
      }
    },
  },
});
vp run lint

错误示例

单独的 Object 和 Array 构造器只描述宽泛的运行时类别,因此 user 和 items 元素结构都没有显式静态类型。

<script setup lang="ts">
const props = defineProps({ user: Object, items: { type: Array } });
</script>

正确示例

PropType<User> 和 PropType<User[]> 添加对象和元素类型,同时保留原运行时构造器。

<script setup lang="ts">
import type { PropType } from "vue";
interface User { name: string }
const props = defineProps({
  user: Object as PropType<User>,
  items: { type: Array as PropType<User[]> },
});
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-typed-ref

要求无初始值、null 或 undefined 初始化的 ref() 具有显式类型参数

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-typed-ref": "warn"
      }
    },
  },
});
vp run lint

错误示例

导入的 ref 调用既无类型参数,也无有效初始值:无参数、null 和 undefined 都无法推断未来值的预期类型。

<script setup lang="ts">
import { ref } from 'vue'

const a = ref()           // Ref<undefined>
const b = ref(null)       // Ref<null>
const c = ref(undefined)  // Ref<undefined>
</script>

正确示例

显式类型参数描述字符串和可空 User refs。ref(0) 已有具体数字初始值,可以依靠推断。

<script setup lang="ts">
import { ref } from 'vue'

const a = ref<string>()
const b = ref<User | null>(null)
const c = ref(0)          // inferred Ref<number>
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/require-valid-default-prop

要求 prop 默认值符合声明类型

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/require-valid-default-prop": "error"
      }
    },
  },
});
vp run lint

错误示例

Number 和 Boolean props 使用了不匹配的标量默认值,Array 和 Object props 使用共享字面量而不是工厂。

<script lang="ts">
export default {
  props: {
    count: { type: Number, default: '0' },     // string default for Number
    enabled: { type: Boolean, default: 1 },     // non-boolean default for Boolean
    items: { type: Array, default: [] },        // literal must be a factory
    config: { type: Object, default: {} }       // literal must be a factory
  }
}
</script>

正确示例

标量默认值改为 0 和 false;数组和对象默认值改为返回新值的函数。[String, Number] 示例接受字符串默认值,因为它匹配一个声明类型。

<script lang="ts">
export default {
  props: {
    count: { type: Number, default: 0 },
    enabled: { type: Boolean, default: false },
    items: { type: Array, default: () => [] },
    config: { type: Object, default: () => ({}) },
    label: { type: [String, Number], default: '' }
  }
}
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/return-in-computed-property

要求每个计算 getter 返回值

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/return-in-computed-property": "error"
      }
    },
  },
});
vp run lint

错误示例

块函数体计算 getter 求值 1 + 2 却从不返回,使计算值为 undefined。

<script setup lang="ts">
import { computed } from "vue";
const total = computed(() => { 1 + 2; });
</script>

正确示例

return 1 + 2 将表达式转为 getter 的返回值。规则查找 getter 自身返回值的 return,而非仅有表达式语句。

<script setup lang="ts">
import { computed } from "vue";
const total = computed(() => { return 1 + 2; });
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/return-in-emits-validator

要求每个 Options API emits 校验函数返回值

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

为当前支持的 SFC 筛选使用块函数体箭头函数。底层校验器也处理方法简写,但当前 SFC 前置筛选无法可靠分派该形式。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/return-in-emits-validator": "error"
      }
    },
  },
});
vp run lint

错误示例

submit 校验函数记录载荷,却不返回校验结果,因此块函数体产生 undefined。

<script lang="ts">
export default { emits: { submit: (payload: unknown) => { console.log(payload); } } };
</script>

正确示例

return payload != null 为提交载荷提供布尔校验结果,避免结束时没有返回值。

<script lang="ts">
export default { emits: { submit: (payload: unknown) => { return payload != null; } } };
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/valid-define-emits

要求 defineEmits() 用法有效(不同时提供类型和运行时参数、不引用局部变量、只调用一次)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-emits": "error"
      }
    },
  },
});
vp run lint

错误示例

同一 defineEmits 调用同时提供类型参数和运行时数组 ["save"],混合两种互斥声明。

<script setup lang="ts">
defineEmits<{ save: [] }>(["save"]);
</script>

正确示例

移除运行时参数,只保留一个针对 save 的类型事件声明。

<script setup lang="ts">
defineEmits<{ save: [] }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/valid-define-options

要求 defineOptions() 用法有效(单个对象参数、不包含 props/emits/expose/slots)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-options": "error"
      }
    },
  },
});
vp run lint

错误示例

第一个调用将专用的 props 声明放入 defineOptions;后续调用又重复宏,并包含非对象参数。这些展示了禁止的形式和重复调用限制。

<script setup lang="ts">
defineOptions({ props: ['foo'] })   // use defineProps instead
defineOptions({ name: 'Foo' })
defineOptions({ name: 'Bar' })      // duplicate call
defineOptions('Foo')                // not an object literal
</script>

正确示例

一个 defineOptions 调用接收只包含受支持普通选项 name 和 inheritAttrs 的对象。

<script setup lang="ts">
defineOptions({ name: 'Foo', inheritAttrs: false })
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/valid-define-props

要求 defineProps() 用法有效(只调用一次、不同时提供类型和运行时参数、不引用局部变量)

错误示例 · 正确示例

默认严重程度: error
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-define-props": "error"
      }
    },
  },
});
vp run lint

错误示例

同一 defineProps 调用同时提供类型参数 { title: string } 和运行时参数 { title: String },编译器不允许二者组合。

<script setup lang="ts">
defineProps<{ title: string }>({ title: String });
</script>

正确示例

移除运行时对象,只保留一个针对 title 的类型声明,不再组合两种声明形式。

<script setup lang="ts">
defineProps<{ title: string }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

script/valid-next-tick

要求 nextTick() 调用结果被等待、链式处理,或提供回调

错误示例 · 正确示例

默认严重程度: warning
预设: essential, happy-path, ecosystem, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 中的 JS/TS 脚本;示例展示对应的 Options API 或 script setup 形式
选项: 没有规则专属选项。可以配置严重程度和预设。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "script/valid-next-tick": "warn"
      }
    },
  },
});
vp run lint

错误示例

导入的 nextTick() 是无回调的独立表达式,其返回 Promise 被忽略,没有操作等待 DOM 刷新。

<script setup lang="ts">
import { nextTick } from "vue";
nextTick();
</script>

正确示例

await nextTick() 使用该 Promise,显式等待下一次 DOM 更新,再继续执行后续 setup 代码。

<script setup lang="ts">
import { nextTick } from "vue";
await nextTick();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/no-floating-promises

禁止悬空(未处理)的 Promise

错误示例 · 正确示例

默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 没有规则专属选项。可以配置严重程度和预设。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-floating-promises": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

异步 save 函数返回 Promise,但独立的 save() 调用既不等待也不返回它,也未显式标记有意丢弃。

<script setup lang="ts">
async function save(): Promise<void> {}
save();
</script>

正确示例

void save() 显式标记此规则接受的发出后不等待意图。这是显式丢弃标记,不是拒绝处理器。

<script setup lang="ts">
async function save(): Promise<void> {}
void save();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/no-reactivity-loss

禁止赋值和调用中对响应式值取普通快照

错误示例 · 正确示例

默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 没有规则专属选项。可以配置严重程度和预设。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-reactivity-loss": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

const count = state.count 对响应式属性取普通数字快照,因此之后 state.count 的更新不会反映到该绑定。

<script setup lang="ts">
import { reactive } from "vue";
const state = reactive({ count: 0 });
const count = state.count;
</script>

正确示例

toRef(state, "count") 使 count 继续关联原响应式属性,不复制其当前原始类型值。

<script setup lang="ts">
import { reactive, toRef } from "vue";
const state = reactive({ count: 0 });
const count = toRef(state, "count");
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/no-unsafe-template-binding

禁止解析为不安全类型的模板绑定

错误示例 · 正确示例

默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 没有规则专属选项。可以配置严重程度和预设。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/no-unsafe-template-binding": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

插值的 value 被显式注解为 any,检查器无法为模板绑定提供安全的具体类型。

<script setup lang="ts">
const value: any = "Hello";
</script>
<template><p>{{ value }}</p></template>

正确示例

将注解改为 string,为同一插值提供可检查的具体类型,而不改变渲染值。

<script setup lang="ts">
const value: string = "Hello";
</script>
<template><p>{{ value }}</p></template>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/require-typed-emits

要求 defineEmits 具有类型定义

错误示例 · 正确示例

默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 没有规则专属选项。可以配置严重程度和预设。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/require-typed-emits": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

仅数组形式的 defineEmits(["save"]) 声明事件名称,却没有类型化载荷约定。

<script setup lang="ts">
defineEmits(["save"]);
</script>

正确示例

defineEmits<{ save: [] }>() 以空载荷元组声明带类型的 save 事件,明确表示不接收载荷参数。

<script setup lang="ts">
defineEmits<{ save: [] }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/require-typed-props

要求 defineProps 具有类型定义

错误示例 · 正确示例

默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 没有规则专属选项。可以配置严重程度和预设。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/require-typed-props": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

仅数组形式的 defineProps(["title"]) 只按名称声明 title,没有提供类型。

<script setup lang="ts">
defineProps(["title"]);
</script>

正确示例

defineProps<{ title: string }>() 为 title 提供显式字符串类型,替代仅名称的运行时声明。

<script setup lang="ts">
defineProps<{ title: string }>();
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则

type/strict-boolean-expressions

要求脚本和模板条件使用安全的布尔表达式

错误示例 · 正确示例

默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 脚本和模板中下方所示结构的类型信息
选项: 参见类型化选项和默认值。

显式启用 typeAware 和此规则。默认不允许可空数字,允许非空数字。

类型感知检查使用原生 Corsa 运行时及 TypeScript 项目。仅设置 typeAware 不会启用需显式选择的规则。

配置(Vite+)

import { defineConfig } from "@vizejs/vite-plugin/vite-plus";

export default defineConfig({
  vue: {
    linter: {
      "preset": "incremental",
      "rules": {
        "type/strict-boolean-expressions": "warn"
      },
      "typeAware": true
    },
  },
});
vp run lint

错误示例

if (count) 依赖可空数字绑定的真值性,而非显式布尔检查,也将零与缺失混为一谈。

<script setup lang="ts">
const count: number | undefined = undefined;
if (count) console.log(count);
</script>

正确示例

count !== undefined && count > 0 分别检查存在性和正值,缩窄可选值后产生显式布尔条件。

<script setup lang="ts">
const count: number | undefined = undefined;
if (count !== undefined && count > 0) console.log(count);
</script>

正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。

实现 · 全部规则