Vue 规则
本页列出每条 Vue 规则的用途、配置、错误示例和正确示例。高亮行表示修改;复制代码时会保留完整源代码。
全部规则 · 规则选项 · ESLint 迁移对应表 · 项目检查 · 组件间属性传递
vue/a11y-img-alt
要求图片提供 alt 属性,以支持无障碍访问
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/a11y-img-alt": "warn"
}
},
},
});
vp run lint
错误示例
静态图片和动态来源的图片都未提供 alt 属性。
<template>
<img src="/photo.jpg" />
<img :src="photo" />
</template>
正确示例
承载信息的图片使用描述性 alt 文本,装饰性图片使用空 alt,动态图片则绑定其描述。
<template>
<!-- Informative image -->
<img src="/photo.jpg" alt="Team photo from company retreat" />
<!-- Decorative image (empty alt) -->
<img src="/decoration.svg" alt="" />
<!-- Dynamic alt -->
<img :src="photo" :alt="photoDescription" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/attribute-hyphenation
规范自定义组件的属性命名风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/attribute-hyphenation": "warn"
}
},
},
});
vp run lint
错误示例
组件属性使用了驼峰形式 firstName。
<template>
<UserCard firstName="Ada" />
</template>
正确示例
first-name 符合配置要求的连字符组件属性命名规范。
<template>
<UserCard first-name="Ada" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/attribute-order
要求属性保持一致的排列顺序
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/attribute-order": "warn"
}
},
},
});
vp run lint
错误示例
事件处理器位于结构性 v-if 指令和普通 id 属性之前。
<template>
<div @click="onClick" v-if="show" id="main"></div>
</template>
正确示例
按照规则的顺序,先写 v-if,再写 id,最后写事件处理器。
<template>
<div v-if="show" id="main" @click="onClick"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/component-definition-name-casing
要求组件定义名称使用 PascalCase 或 kebab-case
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
检查的是组件文件名。接受 PascalCase 和 kebab-case;混合大小写会被报告。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/component-definition-name-casing": "warn"
}
},
},
});
vp run lint
错误示例
文件名 myComponent.vue 以小写字母开头,却在内部使用大写字母,既不是 PascalCase,也不是 kebab-case。
myComponent.vue
<template><p>Content</p></template>
正确示例
将文件重命名为 MyComponent.vue 即采用 PascalCase;模板内容无需更改。
MyComponent.vue
<template><p>Content</p></template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/component-name-in-template-casing
要求模板中的组件名称使用指定的大小写风格
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/component-name-in-template-casing": "warn"
}
},
},
});
vp run lint
错误示例
配置要求 PascalCase,但组件名称使用了 kebab-case 和 camelCase。
<script setup>
import MyComponent from "./MyComponent.vue";
</script>
<template>
<my-component />
<myComponent />
</template>
正确示例
MyComponent 使用 PascalCase;原生 slot 语法仍使用小写。
<script setup>
import MyComponent from "./MyComponent.vue";
</script>
<template>
<MyComponent />
<RouterView />
<slot />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/html-button-has-type
要求 button 元素显式指定有效的 type
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/html-button-has-type": "warn"
}
},
},
});
vp run lint
错误示例
一个按钮省略了 type,另一个使用了不受支持的 foo 类型。
<template>
<button>Click</button>
<button type="foo">Click</button>
</template>
正确示例
按钮指定 button、submit 或 reset;绑定的 type 被视为动态值。
<template>
<button type="button">Click</button>
<button type="submit">Save</button>
<button type="reset">Reset</button>
<button :type="dynamicType">Click</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/html-quotes
规范 HTML 属性的引号风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/html-quotes": "warn"
}
},
},
});
vp run lint
错误示例
属性使用单引号或不加引号,不符合双引号规范。
<template>
<div class='foo'></div>
<div class=foo></div>
<div v-if='ready'></div>
</template>
正确示例
普通属性和指令表达式都使用双引号。
<template>
<div class="foo"></div>
<div v-if="ready"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/html-self-closing
规范自闭合标签风格
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/html-self-closing": "warn"
}
},
},
});
vp run lint
错误示例
空组件使用成对的起止标签,而空元素 img 和 br 没有采用配置要求的自闭合写法。
<template>
<MyComponent></MyComponent>
<img>
<br>
</template>
正确示例
组件和空元素使用自闭合语法;包含内容的 div 保留结束标签。
<template>
<MyComponent />
<div></div>
<div />
<img />
<br />
<div>content</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/max-template-complexity
限制组件自身模板的复杂度(圈复杂度和认知复杂度)
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
Bad 的圈复杂度为 13,认知复杂度为 25(上限分别为 11 和 16)。每个组件单独计量;仅支持内联 HTML 模板。
参见复杂度评分与组件边界,了解示例中两项评分的各部分贡献。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/max-template-complexity": "warn"
}
},
},
});
vp run lint
错误示例
父组件编写的分支、循环、插槽内容和表达式中的判断产生了 13 和 25 的复杂度,超过默认上限 11 和 16。
<script setup lang="ts">
defineProps<{ rows: Row[] }>();
</script>
<template>
<section>
<h1>{{ user ? user.name : 'Guest' }}</h1>
<DataTable :rows="rows">
<template #cell="{ row, column }">
<span v-if="column.key === 'status'" :class="row.active ? 'on' : 'off'">{{ row.status ?? 'unknown' }}</span>
<a v-else-if="column.key === 'link' && row.url" :href="row.url">{{ row.label }}</a>
<template v-else>
<em v-for="tag in row.tags" :key="tag">
<b v-if="tag.pinned || tag.starred">{{ tag.hot ? '!' : '' }}</b>
</em>
</template>
</template>
</DataTable>
<p v-if="!rows.length && !loading">No data</p>
</section>
</template>
正确示例
父组件模板将渲染交给 RowList,只保留一个 v-if;其自身的复杂度为 2 和 1。
<template>
<RowList v-if="ready" :rows="rows" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/multi-word-component-names
要求组件名称由多个单词组成
默认严重程度: error
预设: essential, nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
问题在于文件名。需要重命名该组件;更改子标签不能修复此问题。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/multi-word-component-names": "error"
}
},
},
});
vp run lint
错误示例
Item.vue 使用了单个单词的组件名称。
Item.vue
<template><p>Item</p></template>
正确示例
TodoItem.vue 为同一模板使用了多个单词组成的组件名称。
TodoItem.vue
<template><p>Item</p></template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/mustache-interpolation-spacing
要求双花括号插值内部的空格保持一致
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/mustache-interpolation-spacing": "warn"
}
},
},
});
vp run lint
错误示例
文本插值在一个或两个分隔符边界处缺少空格。
<template>
<div>{{text}}</div>
<div>{{ text}}</div>
<div>{{text }}</div>
</template>
正确示例
表达式与双花括号的起止分隔符之间均有空格。
<template>
<div>{{ text }}</div>
<div>{{ foo.bar }}</div>
<div>{{ foo + bar }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-array-index-key
禁止直接将 v-for 的索引变量用作 :key
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-array-index-key": "warn"
}
},
},
});
vp run lint
错误示例
列表使用当前索引作为 key,因此重新排列列表时,列表项的身份会发生变化。
<template>
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
</template>
正确示例
key 来自 item.id,即使位置改变,也能保持每个列表项的身份。
<template>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-bare-strings-in-template
禁止在模板中直接写入应当国际化的用户可读文本
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-bare-strings-in-template": "warn"
}
},
},
});
vp run lint
错误示例
可见文本和提供名称的属性直接在模板中嵌入了未翻译的字符串。
<template>
<div>hello</div>
<img alt="a cat" />
<input placeholder="Search" />
<button title="Close">x</button>
</template>
正确示例
可翻译内容调用 $t;示例中的标点和纯数字属于允许的例外。
<template>
<div>{{ $t('hello') }}</div>
<img :alt="$t('cat')" />
<div>-</div>
<div>123</div>
<button :title="$t('close')">{{ $t('x') }}</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-boolean-attr-value
禁止为 HTML 布尔属性显式指定值
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-boolean-attr-value": "warn"
}
},
},
});
vp run lint
错误示例
布尔属性 disabled 和 checked 包含了多余的字符串值。
<template>
<input disabled="disabled" />
<input checked="checked" />
<button disabled="true">Save</button>
</template>
正确示例
只要存在这些布尔属性,就能表达相同的启用状态,无需指定值。
<template>
<input disabled />
<input checked />
<button disabled>Save</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-child-content
禁止在使用 v-html 或 v-text 时提供子内容
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-child-content": "error"
}
},
},
});
vp run lint
错误示例
v-text 会替换段落内容,因此编写的后备文本无法在该指令生效后保留。
<template>
<p v-text="message">Fallback text</p>
</template>
正确示例
移除子文本后,v-text 成为段落内容的唯一来源。
<template>
<p v-text="message" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-filter
禁止使用已弃用的 Vue 2 管道运算符过滤器语法
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-filter": "error"
}
},
},
});
vp run lint
错误示例
管道使用了已移除的 Vue 过滤器语法来应用 capitalize。
<template>
{{ message | capitalize }}
</template>
正确示例
调用 capitalize(message),以普通表达式完成转换。
<template>
{{ capitalize(message) }}
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-functional-template
禁止在 SFC 的 <template> 上使用 functional 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-functional-template": "error"
}
},
},
});
vp run lint
错误示例
SFC 模板使用了已移除的 functional 属性,并读取旧的 props 上下文。
<template functional>
<div>{{ props.msg }}</div>
</template>
正确示例
普通模板省略 functional,直接读取组件绑定 msg。
<template>
<div>{{ msg }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-html-element-is
禁止在原生 HTML 元素上使用已弃用的 is 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-html-element-is": "error"
}
},
},
});
vp run lint
错误示例
原生 div 使用了没有前缀的旧 is 属性来指定 Vue 组件。
<template>
<div is="MyComponent" />
</template>
正确示例
动态组件使用 :is;原生元素的写法则显式使用 vue: 前缀。
<template>
<component :is="MyComponent" />
<div is="vue:MyComponent" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-inline-template
禁止使用已弃用的 inline-template 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-inline-template": "error"
}
},
},
});
vp run lint
错误示例
Card 使用已弃用的 inline-template 属性接收其内容。
<template>
<Card inline-template><p>Details</p></Card>
</template>
正确示例
省略 inline-template 属性,以通常方式传入相同内容。
<template>
<Card><p>Details</p></Card>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-router-link-tag-prop
禁止在 <router-link> 上使用 tag prop
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-router-link-tag-prop": "error"
}
},
},
});
vp run lint
错误示例
RouterLink 使用了已移除的 tag prop 来指定 button 元素。
<template>
<router-link to="/home" tag="button">Home</router-link>
</template>
正确示例
插槽将 navigate 提供给显式编写的 button。
<template>
<router-link to="/home" v-slot="{ navigate }">
<button @click="navigate">Home</button>
</router-link>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-scope-attribute
禁止在 <template> 上使用已弃用的 scope 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-scope-attribute": "error"
}
},
},
});
vp run lint
错误示例
插槽模板通过已弃用的 scope 属性声明 props。
<template>
<Card><template scope="props">{{ props.name }}</template></Card>
</template>
正确示例
默认插槽指令使用当前插槽语法声明相同的 props 绑定。
<template>
<Card><template #default="props">{{ props.name }}</template></Card>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-slot-attribute
禁止使用已弃用的 slot 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-slot-attribute": "error"
}
},
},
});
vp run lint
错误示例
通过旧 slot 属性选择 header 插槽。
<template>
<Foo>
<template slot="header"><h1>Title</h1></template>
<div :slot="name">Title</div>
</Foo>
</template>
正确示例
v-slot:header 使用当前指令显式选择 header 插槽。
<template>
<Foo>
<template v-slot:header><h1>Title</h1></template>
</Foo>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-slot-scope-attribute
禁止使用已弃用的 slot-scope 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-slot-scope-attribute": "error"
}
},
},
});
vp run lint
错误示例
模板通过已弃用的 slot-scope 属性接收插槽 props。
<template>
<Card><template slot-scope="props">{{ props.name }}</template></Card>
</template>
正确示例
#default 指令接收这些 props,无需使用 slot-scope。
<template>
<Card><template #default="props">{{ props.name }}</template></Card>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-v-bind-sync
禁止在 v-bind 上使用已弃用的 .sync 修饰符
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-v-bind-sync": "error"
}
},
},
});
vp run lint
错误示例
绑定使用了已移除的 .sync 修饰符,包括它与 .camel 的组合。
<template>
<MyComponent :title.sync="title" />
<MyComponent v-bind:title.sync="title" />
<MyComponent :title.sync.camel="title" />
</template>
正确示例
使用普通的单向 title 绑定;需要更新通道时,则使用 v-model:title。
<template>
<MyComponent :title="title" />
<MyComponent v-model:title="title" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-v-is
禁止使用已废弃的 v-is 指令
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-v-is": "error"
}
},
},
});
vp run lint
错误示例
v-is 已在 Vue 3.1 中废弃;示例仍用它切换渲染的组件。
<template>
<tr v-is="'MyRow'"></tr>
</template>
正确示例
改用带 vue: 前缀的 is 属性,或使用 <component :is> 选择组件。
<template>
<tr is="vue:MyRow"></tr>
<component :is="MyRow" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-v-on-native-modifier
禁止在 v-on 上使用已弃用的 .native 修饰符
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-v-on-native-modifier": "error"
}
},
},
});
vp run lint
错误示例
组件事件处理器使用了已移除的 .native 事件修饰符。
<template>
<MyComponent @click.native="handler" />
<MyComponent v-on:click.native="handler" />
<MyComponent @click.native.stop="handler" />
</template>
正确示例
处理器省略 .native,并保留 .stop 等其他事件修饰符。
<template>
<MyComponent @click="handler" />
<MyComponent @click.stop="handler" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-deprecated-v-on-number-modifiers
禁止在 v-on 上使用已弃用的数字 keyCode 修饰符
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
数值修饰符的选择与修复
首个名称带十进制整数前缀的数值修饰符决定诊断结果。@keyup.13.27="submit" 只报告 13,并提供修复结果 @keyup.enter.27="submit";再次修复可以将 27 替换为 escape。@keyup.13suffix="submit" 也会变为 @keyup.enter="submit"。0–9 不在检查范围内,因此 @keyup.0.13="submit" 不会触发此规则。999 等未知值会被报告,但不提供修复。现有的 Vue 2 和 petite-vue 豁免仍然有效。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-deprecated-v-on-number-modifiers": "error"
}
},
},
});
vp run lint
错误示例
键盘事件处理器使用已移除的数字代码 13 和 27 来识别按键。
<template>
<input @keyup.13="submit" />
<input v-on:keyup.27="cancel" />
<input @keyup.13.stop="submit" />
</template>
正确示例
处理器使用具名按键修饰符 enter 和 esc。
<template>
<input @keyup.enter="submit" />
<input @keyup.esc="cancel" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-dupe-v-else-if
禁止在 v-if / v-else-if 链中使用重复条件
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-dupe-v-else-if": "error"
}
},
},
});
vp run lint
错误示例
else-if 重复了首个分支已检查的 ready 条件,导致后面的分支无法执行。
<template>
<p v-if="status === 'ready'">Ready</p>
<p v-else-if="status === 'ready'">Still ready</p>
</template>
正确示例
第二个分支检查 loading,这是不同的状态,因此能够进入 else-if。
<template>
<p v-if="status === 'ready'">Ready</p>
<p v-else-if="status === 'loading'">Loading</p>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-duplicate-attributes
禁止在同一元素上重复声明属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-duplicate-attributes": "error"
}
},
},
});
vp run lint
错误示例
同一个按钮声明了两次 class,而不是将它们合并为一个 class 值。
<template>
<button class="primary" class="large">Save</button>
</template>
正确示例
两个类名都放在同一个 class 属性中。
<template>
<button class="primary large">Save</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-empty-component-block
禁止空的 SFC 块
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-empty-component-block": "warn"
}
},
},
});
vp run lint
错误示例
template、script 和 style 块都没有实质内容。
<template></template>
<script></script>
<style>
</style>
正确示例
每个保留的块都包含实际的标记、脚本声明或样式声明。
<template>
<div>Hello</div>
</template>
<script setup>
const message = "Hello";
</script>
<style scoped>
.button { color: red; }
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-inline-style
不建议使用内联 style 属性
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-inline-style": "warn"
}
},
},
});
vp run lint
错误示例
静态 style 属性将颜色声明直接嵌入元素。
<template>
<div style="color: red">Text</div>
</template>
正确示例
类名表达固定颜色;依赖 ratio 的宽度仍使用动态样式绑定,不属于静态属性检查的范围。
<template>
<div class="text-red">Text</div>
<span :class="{ 'text-red': isRed }">Text</span>
<div :style="{ width: `${ratio}%` }">Text</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-invalid-html-attribute
禁止 HTML 属性使用无效的静态值
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-invalid-html-attribute": "warn"
}
},
},
});
vp run lint
错误示例
锚点元素将 stylesheet 用作 rel 值,但该值应当用于样式表 link 元素。
<template>
<a href="/guide" rel="stylesheet">Guide</a>
</template>
正确示例
锚点使用 help,这是适用于所链接帮助资源的 rel 值。
<template>
<a href="/guide" rel="help">Guide</a>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-lone-template
禁止不必要的 <template> 元素
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-lone-template": "warn"
}
},
},
});
vp run lint
错误示例
内层 template 没有指令或插槽作用,因此不具备结构上的用途。
<template>
<div><template><p>Details</p></template></div>
</template>
正确示例
移除不必要的包装层后,段落直接位于 div 内。
<template>
<div><p>Details</p></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-multi-spaces
禁止连续多个空格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-multi-spaces": "warn"
}
},
},
});
vp run lint
错误示例
属性之间,或元素名称与第一个属性之间,使用了两个空格。
<template>
<div class="panel"></div>
<div class="panel" id="main"></div>
</template>
正确示例
同样的属性之间使用单个空格。
<template>
<div class="panel"></div>
<div class="panel" id="main"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-multiple-objects-in-class
禁止在 :class 数组绑定中使用多个对象字面量
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-multiple-objects-in-class": "warn"
}
},
},
});
vp run lint
错误示例
class 数组包含两个可以合并的顶层对象字面量。
<template>
<div :class="[{ a }, { b }]"></div>
<div :class="[{ active: isActive }, { error: hasError }]"></div>
</template>
正确示例
一个对象包含所有类名条件;只有一个对象和一个字符串的数组,以及包含非字面量项的数组,仍被允许。
<template>
<div :class="{ a, b }"></div>
<div :class="[{ active: isActive }, 'static']"></div>
<div :class="[foo, bar]"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-multiple-template-root
禁止模板包含多个根节点
默认严重程度: error
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
仅在需要单根节点约定时启用。Vue 3 通常支持片段。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-multiple-template-root": "error"
}
},
},
});
vp run lint
错误示例
启用的单根节点规范在模板根部发现了两个同级段落。
<template>
<p>First</p>
<p>Second</p>
</template>
正确示例
使用 section 将段落包装为一个根节点;仅在需要单根节点约定时启用此规范。
<template>
<section><p>First</p><p>Second</p></section>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-mutating-props
禁止修改组件 props
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-mutating-props": "error"
}
},
},
});
vp run lint
错误示例
递增 props.count 会直接写入父组件提供的值。
<script setup lang="ts">
const props = defineProps<{ count: number }>();
props.count++;
</script>
正确示例
组件发出携带下一个值的 update:count 事件,由父组件负责更新 prop。
<script setup lang="ts">
const props = defineProps<{ count: number }>();
const emit = defineEmits<{ "update:count": [value: number] }>();
function increment() {
emit("update:count", props.count + 1);
}
</script>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-negated-v-if-condition
禁止在含有 v-else 的条件链中使用否定的 v-if 条件
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-negated-v-if-condition": "warn"
}
},
},
});
vp run lint
错误示例
成对的 v-if 和 v-else 分支以否定条件开头。
<template>
<div v-if="!ok">A</div>
<div v-else>B</div>
</template>
正确示例
先使用肯定条件 ok;反转条件时,将原来的相反分支放在前面。单独使用否定的 v-if 和 !== 比较仍被允许。
<template>
<div v-if="ok">B</div>
<div v-else>A</div>
<div v-if="!ok">A</div>
<div v-if="a !== b">A</div>
<div v-else>B</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-non-component-keep-alive-child
禁止在 <KeepAlive> 的直属子层使用普通元素包装
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-non-component-keep-alive-child": "warn"
}
},
},
});
vp run lint
错误示例
KeepAlive 有条件地包装原生 div,而没有直接缓存 UserCard。
<template>
<KeepAlive>
<div v-if="ready">
<UserCard />
</div>
</KeepAlive>
</template>
正确示例
第一个示例将 UserCard 设为条件子节点。v-show 包装层展示了不属于此条件子节点检查范围的结构,并不保证原生包装元素会被缓存。
<template>
<KeepAlive>
<UserCard v-if="ready" />
</KeepAlive>
<KeepAlive>
<div v-show="opened">
<UserCard />
</div>
</KeepAlive>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-preprocessor-lang
不建议使用 CSS 预处理器,优先使用现代 CSS
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-preprocessor-lang": "warn"
}
},
},
});
vp run lint
错误示例
style 块通过 lang 选择 SCSS。这描述了不使用预处理器的预期规范;当前 SFC 路径不会报告此规则。
<template><p>Notice</p></template>
<style lang="scss">
.notice { color: red; }
</style>
正确示例
相同的 CSS 声明省略了预处理器 lang。这修正了规范上的问题,但目前不会产生可执行的 Bad/Good 诊断差异。
<template><p>Notice</p></template>
<style>
.notice { color: red; }
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-reserved-component-names
禁止使用保留名称作为组件名称
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-reserved-component-names": "error"
}
},
},
});
vp run lint
错误示例
组件名称 button 与原生 HTML 元素名称冲突。
<script>
export default {
name: "button",
};
</script>
正确示例
AppButton 是应用组件名称,没有复用原生 button 名称。
<script setup lang="ts">
defineOptions({ name: "AppButton" });
</script>
<template>
<Transition>
<AppButton />
</Transition>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-root-v-if
禁止在模板的唯一根元素上使用 v-if
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-root-v-if": "warn"
}
},
},
});
vp run lint
错误示例
组件根元素本身会在 v-if 控制下出现或消失。
<template>
<div v-if="show">content</div>
</template>
正确示例
稳定的外层 div 始终作为根元素,而内层段落承担可见性条件。
<template>
<div>
<p v-if="show">content</p>
</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-script-non-standard-lang
不建议使用非标准的 script lang 值
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 尚未在 SFC lint 中实现
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
当前支持情况: no-sfc-finding
此目录条目目前不会通过 SFC lint 报告该规则特有的问题。Bad/Good 对照描述的是预期规范,并非可执行的诊断。启用此 ID 也不会补上缺失的 SFC 检查。
可配置的 ID(当前没有 SFC 诊断)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-script-non-standard-lang": "warn"
}
},
},
});
vp run lint
错误示例
脚本在 lang=coffee 下使用 CoffeeScript 语法。当前 SFC 路径不会针对该语言报告此目录规则。
<script lang="coffee">
count = 0
</script>
<template><p>Notice</p></template>
正确示例
脚本在 lang=ts 下使用普通 TypeScript 声明,展示预期的语言规范。
<script lang="ts">
const count = 0;
</script>
<template><p>Notice</p></template>
正确示例展示预期规范;当前 SFC 流程不会为任一示例生成这条规则的诊断。
vue/no-src-attribute
不建议在 SFC 块上使用 src 属性
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-src-attribute": "warn"
}
},
},
});
vp run lint
错误示例
SFC 块通过 src 文件提供模板、脚本和样式内容。
<template src="./template.html"></template>
<script src="./script.ts"></script>
<style src="./style.css"></style>
正确示例
每个 SFC 块都包含自身内容,不使用外部 src 属性。
<template>
<p>Hello</p>
</template>
<script setup lang="ts">
const label = "Hello";
</script>
<style scoped>
p {
color: red;
}
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-static-inline-styles
禁止静态内联 style 属性
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-static-inline-styles": "warn"
}
},
},
});
vp run lint
错误示例
段落在 style 属性中包含固定的颜色声明。
<template>
<p style="color: red">Notice</p>
</template>
正确示例
notice 类和 scoped 样式表将固定颜色放在模板属性之外。
<template><p class="notice">Notice</p></template>
<style scoped>.notice { color: red; }</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-template-key
禁止在 <template> 上使用 key 属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-template-key": "error"
}
},
},
});
vp run lint
错误示例
非循环的 template 包装层具有 key,但它并不是需要 key 的迭代边界。
<template>
<template :key="section"><div>Details</div></template>
</template>
正确示例
key 属于 template v-for 迭代,用来标识每个重复的片段。
<template>
<template v-for="item in items" :key="item.id"><div>{{ item.name }}</div></template>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-template-lang
不建议在 template 块上使用 lang 属性
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-template-lang": "warn"
}
},
},
});
vp run lint
错误示例
模板通过 lang 选择 Pug。这是只使用 HTML 的预期规范;当前 SFC 路径不会针对该目录 ID 产生诊断。
<template lang="pug">
p Notice
</template>
正确示例
普通 HTML 模板省略 lang,直接使用段落。这展示了规范,并未声称当前 SFC 会报告问题。
<template>
<p>Notice</p>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-template-shadow
禁止使用遮蔽外层作用域变量的变量名称
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
此检查比较模板内的 v-for、v-slot(包括 #name)和旧式作用域插槽绑定。它报告遮蔽先前绑定的标识符,也包括按属性顺序比较的同一元素上的声明。兄弟元素具有独立的作用域。属性键和默认值中的引用不属于声明,v-pre 会使其子树不参与检查。
脚本和组件属性的名称不在当前检查范围内:单个模板绑定不会仅仅因为与脚本绑定同名就产生警告。诊断范围覆盖源代码中实际编写的标识符,包括转义写法和 HTML 实体。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-template-shadow": "warn"
}
},
},
});
vp run lint
错误示例
内层 v-for 再次声明 item,在嵌套循环中遮蔽了外层 item 绑定。
<template>
<div v-for="item in items" :key="item.id"><span v-for="item in item.children" :key="item.id">{{ item.name }}</span></div>
</template>
正确示例
内层循环声明 child,外层行仍使用 item,内层行则使用 child。
<template>
<div v-for="item in items" :key="item.id"><span v-for="child in item.children" :key="child.id">{{ child.name }}</span></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-template-target-blank
禁止使用 target="_blank" 而不设置 rel="noopener noreferrer"
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-template-target-blank": "warn"
}
},
},
});
vp run lint
错误示例
外部链接打开新的浏览上下文,却没有预期的 rel 保护。
<template>
<a href="https://example.com" target="_blank">x</a>
</template>
正确示例
同一链接在 target=_blank 之外还包含 noopener noreferrer。
<template>
<a href="https://example.com" target="_blank" rel="noopener noreferrer">x</a>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-textarea-mustache
禁止在 <textarea> 内使用双花括号插值
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-textarea-mustache": "error"
}
},
},
});
vp run lint
错误示例
textarea 将 message 写在子内容插值中,而没有绑定其值。
<template>
<textarea>{{ message }}</textarea>
</template>
正确示例
v-model 将可编辑的 textarea 值绑定到 message。
<template>
<textarea v-model="message"></textarea>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-undefined-refs
禁止在模板中引用未定义的变量
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-undefined-refs": "warn"
}
},
},
});
vp run lint
错误示例
模板读取 missing,但脚本只声明了 message。
<script setup>const message = "Hello";</script>
<template>{{ missing }}</template>
正确示例
插值读取已存在的 message 绑定。
<script setup>const message = "Hello";</script>
<template>{{ message }}</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unsafe-url
警告可能不安全的 URL 绑定
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unsafe-url": "warn"
}
},
},
});
vp run lint
错误示例
锚点的目标地址以可执行的 javascript: 协议开头。
<template>
<a href="javascript:alert(1)">Continue</a>
</template>
正确示例
锚点使用普通的本地导航目标 /next。
<template>
<a href="/next">Continue</a>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unsandboxed-iframe
要求 iframe 元素具有 sandbox 属性
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unsandboxed-iframe": "warn"
}
},
},
});
vp run lint
错误示例
嵌入的框架没有使用 sandbox 属性限制其能力。
<template>
<iframe src="/embed"></iframe>
</template>
正确示例
sandbox 施加限制;需要脚本能力时,allow-scripts 显式允许这一项能力。
<template>
<iframe src="/embed" sandbox></iframe>
<iframe src="/embed" sandbox="allow-scripts"></iframe>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unused-components
禁止注册未在模板中使用的组件
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unused-components": "warn"
}
},
},
});
vp run lint
错误示例
UserAvatar 作为组件导入,但模板从未渲染它。
<script setup lang="ts">
import UserAvatar from "./UserAvatar.vue";
</script>
<template>
<p>{{ user.name }}</p>
</template>
正确示例
模板渲染导入的 UserAvatar,并传入 user 绑定。
<script setup lang="ts">
import UserAvatar from "./UserAvatar.vue";
</script>
<template>
<UserAvatar :user="user" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unused-properties
禁止 defineProps 中定义的未使用属性
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unused-properties": "warn"
}
},
},
});
vp run lint
错误示例
组件将 description 声明为 prop,但只渲染了 title。
<script setup lang="ts">
defineProps<{ title: string; description: string }>();
</script>
<template>
<h1>{{ title }}</h1>
</template>
正确示例
模板引用了两个已声明的 props。
<script setup lang="ts">
defineProps<{ title: string; description: string }>();
</script>
<template>
<h1>{{ title }}</h1>
<p>{{ description }}</p>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unused-refs
报告从未在 <script> 中引用的模板 ref(ref="x")
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unused-refs": "warn"
}
},
},
});
vp run lint
错误示例
模板声明了名为 unused 的 ref,但脚本中没有对应的引用绑定。
<template><input ref="unused" /></template>
<script setup>
const x = 1
</script>
正确示例
模板 ref inputEl 在 script setup 中具有同名的 ref 绑定。
<template><input ref="inputEl" /></template>
<script setup>
import { ref } from 'vue'
const inputEl = ref(null)
</script>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unused-setup-bindings
禁止从未读取的 script setup 绑定
默认严重程度: warning
预设: none
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unused-setup-bindings": "warn"
}
},
},
});
vp run lint
错误示例
script setup 中的 message 绑定从未被模板读取。
<script setup>const message = "Hello";</script>
<template><p>Welcome</p></template>
正确示例
段落插值使用 message,从而使用了声明的绑定。
<script setup>const message = "Hello";</script>
<template><p>{{ message }}</p></template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-unused-vars
禁止 v-for 和 v-slot 指令中未使用的变量定义
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-unused-vars": "warn"
}
},
},
});
vp run lint
错误示例
循环声明了未使用的 index,插槽也声明了未被引用的 foo。
<template>
<li v-for="(item, index) in items" :key="item.id">{{ item.name }}</li>
<template v-slot="{ foo }">
<span>Hello</span>
</template>
</template>
正确示例
示例使用 index,或将其命名为 _index 以标记有意不使用;插槽则渲染 data。这里的索引 key 只展示变量使用,并不建议用它保持列表项身份稳定。
<template>
<li v-for="(item, index) in items" :key="index">{{ item.name }}</li>
<li v-for="(item, _index) in items" :key="item.id">{{ item.name }}</li>
<template v-slot="{ data }">
<span>{{ data }}</span>
</template>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-use-v-else-with-v-for
禁止在同一元素上使用 v-else-if 或 v-else 与 v-for
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-use-v-else-with-v-for": "warn"
}
},
},
});
vp run lint
错误示例
else 分支和 v-for 迭代都附加在同一段落上。
<template>
<p v-if="ready">Ready</p>
<p v-else v-for="item in items" :key="item.id">{{ item.name }}</p>
</template>
正确示例
独立的 template 承担 v-else,其子段落承担 v-for。
<template>
<p v-if="ready">Ready</p>
<template v-else><p v-for="item in items" :key="item.id">{{ item.name }}</p></template>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-use-v-if-with-v-for
禁止在同一元素上使用 v-if 与 v-for
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-use-v-if-with-v-for": "warn"
}
},
},
});
vp run lint
错误示例
同一个列表元素同时使用 v-if 和 v-for,并通过循环绑定检查可见性。
<template>
<li v-for="item in items" v-if="item.visible" :key="item.id">
{{ item.name }}
</li>
</template>
正确示例
计算属性中的集合先筛选出可见项,再由模板进行迭代。
<script setup lang="ts">
const visibleItems = computed(() => items.filter((item) => item.visible));
</script>
<template>
<li v-for="item in visibleItems" :key="item.id">
{{ item.name }}
</li>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-useless-mustaches
禁止表达式为常量字符串字面量的双花括号插值
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-useless-mustaches": "warn"
}
},
},
});
vp run lint
错误示例
插值仅包含常量字符串,无需对表达式求值。
<template>
<div>{{ 'x' }}</div>
<div>{{ "x" }}</div>
<div>{{ `x` }}</div>
</template>
正确示例
字面文本直接写入模板;变量表达式、带插值的模板字符串,以及有意作为分隔符的空白,仍可使用插值。
<template>
<div>x</div>
<div>{{ x }}</div>
<div>{{ `pre-${x}` }}</div>
<span>A</span> {{ " " }} <span>B</span>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-useless-template-attributes
禁止在 <template> 元素上使用不起作用的属性
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-useless-template-attributes": "error"
}
},
},
});
vp run lint
错误示例
条件 template 具有 class,但这个结构性包装层不会渲染可接收该属性的 DOM 元素。
<template>
<section><template v-if="ready" class="notice"><p>Ready</p></template></section>
</template>
正确示例
class 移到实际渲染的段落上,v-if 则保留在结构性 template 上。
<template>
<section><template v-if="ready"><p class="notice">Ready</p></template></section>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-useless-v-bind
禁止值为普通字符串字面量的 v-bind
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-useless-v-bind": "warn"
}
},
},
});
vp run lint
错误示例
foo 绑定对带引号的常量字符串,或不含插值的模板字符串,进行求值。
<template>
<div :foo="'bar'"></div>
<div :foo="`bar`"></div>
</template>
正确示例
常量值改为静态属性;变量值和含插值的值保留绑定。
<template>
<div foo="bar"></div>
<div :foo="bar"></div>
<div :foo="`pre-${bar}`"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-v-for-template-key-on-child
禁止在 <template v-for> 的子节点上使用 key
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-v-for-template-key-on-child": "error"
}
},
},
});
vp run lint
错误示例
子段落具有 key,但 template 迭代自身没有 key。
<template>
<template v-for="item in items"><p :key="item.id">{{ item.name }}</p></template>
</template>
正确示例
key 移到 template v-for 上,用来标识整个重复片段。
<template>
<template v-for="item in items" :key="item.id"><p>{{ item.name }}</p></template>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-v-html
警告使用 v-html,以避免 XSS 漏洞
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-v-html": "warn"
}
},
},
});
vp run lint
错误示例
v-html 将 content 解释为 HTML,而不是普通文本。
<template>
<article v-html="content" />
</template>
正确示例
双花括号插值将 content 显示为转义后的文本,而不注入 HTML。
<template>
<article>{{ content }}</article>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-v-text
禁止 v-text 指令,优先使用双花括号插值
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-v-text": "warn"
}
},
},
});
vp run lint
错误示例
div 的内容通过 v-text 指令提供。
<template>
<div v-text="message"></div>
</template>
正确示例
双花括号插值直接在元素内容中表达相同的文本绑定。
<template>
<div>{{ message }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/no-v-text-v-html-on-component
禁止在组件元素上使用 v-text / v-html
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/no-v-text-v-html-on-component": "error"
}
},
},
});
vp run lint
错误示例
组件标签使用 v-html 或 v-text,这些指令会替换元素内容,而不是提供组件插槽。
<template>
<MyComponent v-html="content" />
<MyComponent v-text="content" />
</template>
正确示例
原生 HTML 目标可接收这些指令;MyComponent 通过默认插槽接收内容。
<template>
<div v-html="content"></div>
<component is="div" v-html="content" />
<MyComponent>{{ content }}</MyComponent>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/permitted-contents
要求符合 HTML 内容模型规则
默认严重程度: error
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/permitted-contents": "error"
}
},
},
});
vp run lint
错误示例
示例在 p 中放置块级内容、省略表格主体、嵌套交互控件,或将 div 直接放在 ul 内。
<template>
<p><div>block in a paragraph</div></p>
<table><tr><td>row without tbody</td></tr></table>
<a href="#"><button type="button">nested control</button></a>
<ul><div>not a list item</div></ul>
</template>
正确示例
示例使用段落内的行内内容、显式 tbody 和 li 子节点。自定义 MyItem 不被视为已知的原生 ul 子节点。
<template>
<p><span>inline in a paragraph</span></p>
<table><tbody><tr><td>cell</td></tr></tbody></table>
<ul><li>list item</li><MyItem /></ul>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/prefer-props-shorthand
建议使用 props 简写语法(Vue 3.4+)
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/prefer-props-shorthand": "warn"
}
},
},
});
vp run lint
错误示例
每个绑定都重复了对应的变量名,包括与连字符参数对应的驼峰名称。
<template>
<MyComponent :foo="foo" />
<MyComponent :user-name="userName" />
<span :style="style" />
<div :aria-label="ariaLabel" />
</template>
正确示例
Vue 3.4+ 的同名绑定简写省略了重复表达式;bar 等不同的来源变量仍显式写出。
<template>
<MyComponent :foo />
<MyComponent :user-name />
<span :style />
<div :aria-label />
<MyComponent :foo="bar" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/prefer-true-attribute-shorthand
优先使用绑定到 true 的布尔属性简写
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/prefer-true-attribute-shorthand": "warn"
}
},
},
});
vp run lint
错误示例
原生布尔属性 disabled 绑定了常量 true。
<template>
<input :disabled="true" />
</template>
正确示例
原生属性使用布尔简写。false 绑定和组件 props 保留显式值。
<template>
<input disabled />
<input :disabled="false" />
<MyComponent :visible="true" />
<MyComponent :visible="isVisible" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/prop-name-casing
规范所声明 prop 名称的大小写风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
检查所声明的 prop 名称,而不是传给子组件的属性的大小写风格。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/prop-name-casing": "warn"
}
},
},
});
vp run lint
错误示例
声明的 prop 名称 user_name 使用下划线分隔。
<script setup lang="ts">
defineProps<{ user_name: string }>();
</script>
<template><p>{{ user_name }}</p></template>
正确示例
声明及其模板引用都使用驼峰名称 userName。
<script setup lang="ts">
defineProps<{ userName: string }>();
</script>
<template><p>{{ userName }}</p></template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/require-component-is
要求 <component> 元素具有 v-bind:is
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/require-component-is": "error"
}
},
},
});
vp run lint
错误示例
动态 <component> 没有 is 目标,因此 Vue 无法选择要渲染的组件。
<template>
<component />
</template>
正确示例
:is="currentComponent" 提供组件选择;该绑定可在运行时变化。
<template>
<component :is="currentComponent" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/require-component-registration
要求显式导入或注册组件
默认严重程度: warning
预设: opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
列出由应用插件或 Musea previewSetup 提供的明确组件名称。接受 PascalCase 和 kebab-case 写法;不解析正则表达式。设置选项不会启用规则。后面的配置层会替换列表;空列表会清除继承的名称。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/require-component-registration": "warn"
},
"ruleOptions": {
"vue/require-component-registration": {
"globals": [
"MyButton",
"MyIcon"
]
}
}
},
},
});
vp run lint
错误示例
MissingWidget 既未注册,也不在配置的全局组件允许列表中。
<template>
<MissingWidget />
</template>
正确示例
MyButton 列在示例的 globals 选项中。该选项让已知的全局组件免于此检查,并不会注册或导入组件。
<template>
<MyButton />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/require-scoped-style
要求 style 标签具有 scoped 属性
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/require-scoped-style": "warn"
}
},
},
});
vp run lint
错误示例
.button 样式没有作用域限制,可能影响组件外部匹配的元素。
<style>
.button {
color: red;
}
</style>
正确示例
添加 scoped,为同样的选择器和声明应用 Vue 的组件作用域。
<style scoped>
.button {
color: red;
}
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/require-toggle-inside-transition
要求 <transition> 包裹的元素具有切换条件
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/require-toggle-inside-transition": "error"
}
},
},
});
vp run lint
错误示例
<Transition> 内的静态子节点没有条件可见性或动态选择,无法触发进入或离开的变化。
<template>
<transition>
<div>content</div>
</transition>
</template>
正确示例
v-if="show" 改变子节点是否存在,为过渡提供进入和离开的边界。
<template>
<transition>
<div v-if="show">content</div>
</transition>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/require-v-for-key
要求 v-for 指令搭配 v-bind:key
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/require-v-for-key": "error"
}
},
},
});
vp run lint
错误示例
每个重复的 <li> 都缺少在列表更新时标识对应列表项的 key。
<template>
<li v-for="item in items">{{ item.name }}</li>
</template>
正确示例
:key="item.id" 为每个重复节点提供列表项的身份,而不是当前位置。
<template>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/scoped-event-names
建议使用 context:event 格式的作用域事件名称
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/scoped-event-names": "warn"
}
},
},
});
vp run lint
错误示例
playAudio、pauseAudio 和 reloadAudio 使用驼峰后缀表达作用域,不符合规则要求的冒号分隔事件规范。
<template>
<AudioPlayer
@playAudio="play"
@pauseAudio="pause"
@reloadAudio="reload"
/>
</template>
正确示例
audio:play、audio:pause 和 audio:reload 共享显式的 audio: 作用域。发出事件的组件必须使用相同名称。
<template>
<AudioPlayer
@audio:play="play"
@audio:pause="pause"
@audio:reload="reload"
/>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/sfc-element-order
要求 SFC 顶层元素保持一致的顺序
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/sfc-element-order": "warn"
}
},
},
});
vp run lint
错误示例
style 块位于 script 块之前,不符合配置的 SFC 块顺序。
<style scoped>
.panel {
color: red;
}
</style>
<script setup lang="ts">
const label = "Save";
</script>
正确示例
各块按照 script → template → style 排列。项目可通过此规则的类型化选项选择其他顺序。
<script setup lang="ts">
const label = "Save";
</script>
<template>
<p>{{ label }}</p>
</template>
<style scoped>
p {
color: red;
}
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/single-style-block
建议只使用一个 style 块
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/single-style-block": "warn"
}
},
},
});
vp run lint
错误示例
组件将带作用域的 panel 和 title 样式分散在两个 style 块中。
<style scoped>
.panel {
color: red;
}
</style>
<style scoped>
.title {
color: blue;
}
</style>
正确示例
两个选择器都保留在同一个带作用域的 style 块中,满足单块规范,也没有丢弃任何样式。
<style scoped>
.panel {
color: red;
}
.title {
color: blue;
}
</style>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/slot-name-casing
要求通过 v-slot 使用的具名插槽采用 kebab-case
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/slot-name-casing": "warn"
}
},
},
});
vp run lint
错误示例
具名插槽 mySlot 使用驼峰命名,而规则要求连字符名称。
<template>
<MyCard><template #mySlot>Content</template></MyCard>
</template>
正确示例
#my-slot 使用 kebab-case。将对应的插槽出口重命名为相同名称。
<template>
<MyCard><template #my-slot>Content</template></MyCard>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/this-in-template
禁止在模板表达式中使用 this.
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/this-in-template": "warn"
}
},
},
});
vp run lint
错误示例
模板表达式显式访问 this.message、this.className 和 this.handleClick,但 Vue 已直接暴露这些绑定。
<template>
<div>{{ this.message }}</div>
<div :class="this.className"></div>
<button @click="this.handleClick()"></button>
</template>
正确示例
直接使用 message、className 和 handleClick。字面字符串 'this.is.a.string' 保持不变,因为它不是成员访问。
<template>
<div>{{ message }}</div>
<div :class="className"></div>
<button @click="handleClick()"></button>
<div>{{ 'this.is.a.string' }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/use-unique-element-ids
要求使用 useId() 生成唯一元素 ID,而不是静态字面量
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/use-unique-element-ids": "warn"
}
},
},
});
vp run lint
错误示例
组件的每个实例都会复用字面量 ID email,多个实例同时渲染时,标签可能指向错误的输入框。
<template>
<label for="email">Email</label>
<input id="email" />
</template>
正确示例
useId() 生成实例的 emailId;将同一值绑定到标签的 for 和输入框的 id。
<script setup>
import { useId } from "vue";
const emailId = useId();
</script>
<template>
<label :for="emailId">Email</label>
<input :id="emailId" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/use-v-on-exact
存在带按键修饰符的处理器时,要求在 v-on 上使用 .exact
默认严重程度: warning
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
处理器何时会重叠
此规则比较原生元素上同一事件的监听器。对于自定义组件事件,只有两个监听器都使用 .native 时才进行检查。事件名称不同或按键过滤器没有共同按键时,不会发生冲突。
系统修饰符指定必须按下的按键,因此 @keydown.alt.shift 也接受 Ctrl+Alt+Shift。如果另一个处理器使用 @keydown.alt.ctrl.shift,请为匹配范围更广的处理器添加 .exact,以区分这些操作。.exact 允许其声明的系统修饰符,并拒绝额外的 Ctrl、Shift、Alt 或 Meta 键。
多个键盘修饰符表示备选项:@keydown.up.down 接受上、下两个方向键中的任意一个。按下 Ctrl+下方向键时,它可能与 @keydown.ctrl.down 重叠。规则报告需要 .exact 的指令键,不包括其处理器表达式。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/use-v-on-exact": "warn"
}
},
},
});
vp run lint
错误示例
普通点击处理器也可能在 Ctrl-click 时运行,与独立的 .ctrl 处理器重叠。
<template>
<button type="button" @click="handleClick" @click.ctrl="handleCtrlClick">
Save
</button>
</template>
正确示例
.exact 将普通点击处理器限制为未按修饰键的点击;Ctrl 专用处理器仍保持独立。
<template>
<button
type="button"
@click.exact="handleClick"
@click.ctrl="handleCtrlClick"
>
Save
</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/v-bind-style
规范 v-bind 指令风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/v-bind-style": "warn"
}
},
},
});
vp run lint
错误示例
v-bind:class 使用了完整形式,但配置的绑定风格要求冒号简写。
<template>
<div v-bind:class="panelClass"></div>
</template>
正确示例
:class 使用所需的简写,并保留相同表达式;此规则检查写法,而非值的类型。
<template>
<div :class="panelClass"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/v-on-event-hyphenation
要求组件上 v-on 中的自定义事件名称使用连字符
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/v-on-event-hyphenation": "warn"
}
},
},
});
vp run lint
错误示例
自定义组件监听器使用了 @myEvent,而不是连字符事件名称。
<template>
<MyComponent @myEvent="handler" />
<MyComponent v-on:myEvent="handler" />
</template>
正确示例
@my-event 符合要求的自定义事件写法。下方展示的原生元素监听器和动态事件参数不在此检查范围内。
<template>
<MyComponent @my-event="handler" />
<div @myEvent="handler" />
<MyComponent @[dynamicEvent]="handler" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/v-on-handler-style
要求 v-on 处理器写为方法引用或内联函数
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/v-on-handler-style": "warn"
}
},
},
});
vp run lint
错误示例
处理器将修改操作和多条语句直接写在事件属性中。
<template>
<button @click="count++"></button>
<button @click="doThis(); doThat()"></button>
<button @click="foo = bar"></button>
</template>
正确示例
使用处理器引用;需要内联逻辑时,使用箭头函数或函数表达式。函数边界使处理器形式明确。
<template>
<button @click="handler"></button>
<button @click="foo.bar"></button>
<button @click="() => count++"></button>
<button @click="function () { count++ }"></button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/v-on-style
规范 v-on 指令风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/v-on-style": "warn"
}
},
},
});
vp run lint
错误示例
v-on:click 使用完整的事件监听形式,但规则要求简写。
<template>
<div v-on:click="handleClick"></div>
</template>
正确示例
@click 使用配置的简写,并保留同一处理器。
<template>
<div @click="handleClick"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/v-slot-style
规范 v-slot 指令风格
默认严重程度: warning
预设: happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/v-slot-style": "warn"
}
},
},
});
vp run lint
错误示例
组件使用 #default,template 使用 v-slot:header,与规则针对各上下文要求的风格相反。
<template>
<MyComponent #default="props">{{ props.item }}</MyComponent>
<MyComponent>
<template v-slot:header>Header</template>
</MyComponent>
</template>
正确示例
组件的默认插槽使用 v-slot,template 的具名插槽使用 #header。
<template>
<MyComponent v-slot="props">{{ props.item }}</MyComponent>
<MyComponent>
<template #header>Header</template>
</MyComponent>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-attribute-name
要求属性名称有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
错误示例的诊断: parser/template
格式错误的属性写法会先由 parser/template 诊断,之后该防御性规则才能读取属性。因此 Bad 报告的是 parser/template,并不保证另有独立的 vue/valid-attribute-name 问题。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-attribute-name": "error"
}
},
},
});
vp run lint
错误示例
my"attr 内的引号使属性名称格式错误。此示例产生解析器的 parser/template 诊断,并不保证另有独立的规则诊断。
<template>
<div my"attr="value"></div>
</template>
正确示例
my-attr 是格式正确的属性名称,因此模板解析器可以读取该属性及其值。
<template>
<div my-attr="value"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-template-root
要求 <template> 根节点符合 Vue 3 片段语义
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-template-root": "error"
}
},
},
});
vp run lint
错误示例
普通的嵌套 <template> 占据模板根部,却没有赋予它渲染作用的指令。
<template>
<template>content</template>
</template>
正确示例
<div> 是可渲染的根元素。此示例并未对 Vue 3 片段施加普遍的单根节点限制。
<template>
<div>content</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-bind
要求 v-bind 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-bind": "error"
}
},
},
});
vp run lint
错误示例
不带参数的 v-bind 缺少对象表达式,空参数形式则缺少属性名称。
<template>
<div v-bind></div>
<div :></div>
</template>
正确示例
提供属性与表达式、绑定对象,或使用 Vue 3.4+ 的同名简写,例如 :loading。
<template>
<div :class="panelClass"></div>
<div v-bind="{ class: panelClass }"></div>
<div :loading></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-cloak
要求 v-cloak 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-cloak": "error"
}
},
},
});
vp run lint
错误示例
v-cloak 设置了值、参数或修饰符,但它不接受这些内容。
<template>
<div v-cloak="foo"></div>
<div v-cloak:arg></div>
<div v-cloak.mod></div>
</template>
正确示例
使用不带值的 v-cloak;CSS 可隐藏元素,直到 Vue 挂载后移除此属性。
<template>
<div v-cloak></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-else
要求 v-else 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 适用于已支持的诊断
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-else": "error"
}
},
},
});
vp run lint
错误示例
示例为 v-else 提供表达式、将其与 v-if 组合,或省略了紧邻其前的条件分支。
<template>
<div v-else="ready"></div>
<div v-else v-if="ready"></div>
<div v-else></div>
</template>
正确示例
将不带值的 v-else 紧接在对应的 v-if 分支之后。
<template>
<div v-if="ready"></div>
<div v-else></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-else-if
要求 v-else-if 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-else-if": "error"
}
},
},
});
vp run lint
错误示例
示例中的 v-else-if 前面没有条件分支、缺少条件,或带有参数或修饰符。
<template>
<div v-else-if="foo"></div> <!-- without preceding v-if -->
<div v-if="foo"></div><div v-else-if></div>
<div v-if="foo"></div><div v-else-if:arg="bar"></div>
<div v-if="foo"></div><div v-else-if.mod="bar"></div>
</template>
正确示例
将带条件的 v-else-if 紧跟在它所延续的 v-if 或 v-else-if 分支之后。
<template>
<div v-if="foo"></div>
<div v-else-if="bar"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-for
要求 v-for 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-for": "error"
}
},
},
});
vp run lint
错误示例
循环省略了迭代表达式,或添加了不受支持的 .stop 修饰符。
<template>
<div v-for></div>
<div v-for=""></div>
<div v-for.stop="item in items"></div>
</template>
正确示例
使用 item in items 或 (item, index) of items,提供完整的迭代表达式及示例中的 key。
<template>
<div v-for="item in items" :key="item.id"></div>
<div v-for="(item, index) of items" :key="index"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-html
要求 v-html 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-html": "error"
}
},
},
});
vp run lint
错误示例
v-html 缺少表达式,或使用了此指令不支持的参数或修饰符。
<template>
<div v-html></div>
<div v-html:arg="foo"></div>
<div v-html.mod="foo"></div>
</template>
正确示例
v-html="html" 提供有效表达式。语法有效并不会清理 HTML,也不会让不可信内容变得安全。
<template>
<div v-html="html"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-if
要求 v-if 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-if": "error"
}
},
},
});
vp run lint
错误示例
条件省略了表达式,或在同一节点上将 v-if 与 else 指令组合。
<template>
<div v-if></div>
<div v-if=""></div>
<div v-if="ready" v-else></div>
</template>
正确示例
每个 v-if 都具有 ready 或 count > 0 等非空条件,且没有不兼容的 else 指令。
<template>
<div v-if="ready"></div>
<div v-if="count > 0"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-is
要求 v-is 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-is": "error"
}
},
},
});
vp run lint
错误示例
v-is 带有参数或修饰符、缺少值,或用在组件上而不是原生 HTML 元素上。
<template>
<tr v-is:arg="'MyRow'"></tr>
<tr v-is.mod="'MyRow'"></tr>
<tr v-is></tr>
<MyComponent v-is="'MyRow'" />
</template>
正确示例
在 <tr> 等原生元素上使用带值的 v-is,指定要在该位置渲染的组件。
<template>
<tr v-is="'MyRow'"></tr>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-memo
要求 v-memo 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-memo": "error"
}
},
},
});
vp run lint
错误示例
不带值的 v-memo 没有为 Vue 提供依赖表达式,无法判断何时复用子树。
<template>
<div v-memo></div>
</template>
正确示例
v-memo="[valueA, valueB]" 提供用于记忆化的依赖数组。
<template>
<div v-memo="[valueA, valueB]">{{ label }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-model
要求 v-model 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-model": "error"
}
},
},
});
vp run lint
错误示例
原生 <div> 不能像表单控件一样使用 v-model,输入框上不带值的指令也没有可写的目标表达式。
<template>
<div v-model="value"></div>
<input v-model />
</template>
正确示例
将 input、select、textarea 或自定义组件绑定到示例中的可写变量。
<template>
<input v-model="value" />
<select v-model="selected"></select>
<textarea v-model="text"></textarea>
<MyInput v-model="value" />
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-on
要求 v-on 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
修饰符验证
不受支持的修饰符会在各自名称的位置被单独报告,包括长格式 v-on:click、动态事件参数和监听器对象语法中的修饰符。接受的名称与 eslint-plugin-vue 10.9.2 一致:Vue 内置的事件修饰符、完整的按键别名表、任意单个 Unicode 码点,以及带有有限十进制整数前缀的名称(遵循 JavaScript 的 Number.parseInt(name, 10) 语义)。例如,此规则接受 .13suffix。数字键码的弃用诊断和 .native 的迁移诊断由其他规则负责。
只有 .stop 和 .prevent 在没有处理器时也能产生行为。.once、.enter 或配置的自定义名称等修饰符仍然需要处理器表达式。
使用自定义事件处理的项目可以在 vue.linter.ruleOptions 下添加名称:
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({}).withVue({
linter: {
rules: { "vue/valid-v-on": "error" },
ruleOptions: { "vue/valid-v-on": { modifiers: ["custom"] } },
},
});
这允许使用 @click.custom="handler"。名称必须精确匹配且区分大小写;这些选项补充内置名称,不会启用已禁用的规则。限定作用范围的配置条目可以用新列表替换继承的名称,或用 [] 将其重置。
按键表改编自采用 MIT 许可证的 eslint-plugin-vue 按键别名。其源代码和许可证与实现一同保留。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-on": "error"
},
"ruleOptions": {
"vue/valid-v-on": {
"modifiers": [
"custom"
]
}
}
},
},
});
vp run lint
错误示例
监听器形式缺少事件参数,或缺少所需的处理器或对象表达式。
<template>
<div v-on></div>
<div @></div>
<div @click></div>
<div @click.sync="handleClick"></div>
<div @click.nativeish="handleClick"></div>
<div @click.once></div>
</template>
正确示例
提供事件及其处理器,或将监听器对象传给无参数的 v-on。
<template>
<div @click="handleClick"></div>
<form @submit.prevent></form>
<input @keyup.page-down="handlePageDown" />
<input @keyup.あ="handleKey" />
<div v-on="{ click: handleClick }"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-once
要求 v-once 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-once": "error"
}
},
},
});
vp run lint
错误示例
v-once 设置了值、参数或修饰符,但此指令是无值的单次渲染标记。
<template>
<div v-once="foo"></div>
<div v-once:arg></div>
<div v-once.mod></div>
</template>
正确示例
不带值的 v-once 将子树标记为只渲染一次,不使用不受支持的语法。
<template>
<div v-once></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-pre
要求 v-pre 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-pre": "error"
}
},
},
});
vp run lint
错误示例
v-pre 设置了参数、修饰符或值,但此指令是跳过编译的无值标记。
<template>
<div v-pre:arg></div>
<div v-pre.mod></div>
<div v-pre="foo"></div>
</template>
正确示例
不带值的 v-pre 让子树跳过编译,其中的插值按原样显示。
<template>
<div v-pre>{{ raw }}</div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-show
要求 v-show 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-show": "error"
}
},
},
});
vp run lint
错误示例
v-show 缺少可见性表达式,或被放在 <template> 上;该元素没有可改变 display 的 DOM 元素。
<template>
<div v-show></div>
<template v-show="ready"><div></div></template>
</template>
正确示例
将可见性表达式应用于 <div> 等实际渲染的元素。
<template>
<div v-show="ready"></div>
<div v-show="count > 0"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-slot
要求 v-slot 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 参见类型化选项和默认值。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-slot": "error"
}
},
},
});
vp run lint
错误示例
插槽指令位于原生 <div> 上,或与其他默认或具名插槽声明冲突。
<template>
<div v-slot:header></div>
<MyComponent v-slot v-slot:header />
<template v-slot:header v-slot:footer />
</template>
正确示例
在组件自身上声明其默认插槽,或在子 <template #header> 上声明其具名插槽。
<template>
<MyComponent v-slot="{ item }">{{ item }}</MyComponent>
<MyComponent>
<template #header>Header</template>
</MyComponent>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/valid-v-text
要求 v-text 指令有效
默认严重程度: error
预设: essential, happy-path, nuxt, ecosystem, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/valid-v-text": "error"
}
},
},
});
vp run lint
错误示例
v-text 缺少文本表达式,或使用了不受支持的参数或修饰符。
<template>
<div v-text></div>
<div v-text:arg="foo"></div>
<div v-text.mod="foo"></div>
</template>
正确示例
v-text="msg" 在语法上有效。独立的 vue/no-v-text 风格规则仍可能要求优先使用插值。
<template>
<div v-text="msg"></div>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/warn-custom-block
警告 SFC 文件中的自定义块
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/warn-custom-block": "warn"
}
},
},
});
vp run lint
错误示例
SFC 包含 <i18n> 自定义块,需要普通 template、script 和 style 处理之外的外部集成。
<i18n>
{ "en": { "hello": "Hello" } }
</i18n>
<template>
<p>{{ hello }}</p>
</template>
正确示例
示例使用标准的 template 和 script-setup 块。此可选的可移植性警告并不意味着所有自定义块都是无效 Vue。
<template>
<p>{{ hello }}</p>
</template>
<script setup lang="ts">
const hello = "Hello";
</script>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。
vue/warn-custom-directive
警告需要注册的自定义指令
默认严重程度: warning
预设: nuxt, opinionated
自动修复: 无;请检查建议的修改
适用范围: Vue SFC 模板和代码块,包括规则所需的脚本上下文
选项: 没有规则专属选项。可以配置严重程度和预设。
配置(Vite+)
import { defineConfig } from "@vizejs/vite-plugin/vite-plus";
export default defineConfig({
vue: {
linter: {
"preset": "incremental",
"rules": {
"vue/warn-custom-directive": "warn"
}
},
},
});
vp run lint
错误示例
v-focus、v-mask 和 v-click-outside 需要项目特定的指令实现,因此被此可选规范标记。
<template>
<input v-focus />
<input v-mask="'###-####'" />
<div v-click-outside="handleClose"></div>
</template>
正确示例
示例使用内置的 v-if、v-model 和 v-on。禁用此策略时,正确注册的自定义指令仍可作为有效的 Vue 使用。
<template>
<div v-if="ready"></div>
<input v-model="value" />
<button type="button" @click="onClick">Save</button>
</template>
正确示例在上述配置下不会触发这条规则的诊断;其他规则仍可能报告诊断。