Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: perrysong <perrysong@xiaoman.cn> Co-authored-by: Flo Edelmann <git@flo-edelmann.de>
- Loading branch information
1 parent
3cbb1b3
commit 1a0bd29
Showing
5 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
--- | ||
pageClass: rule-details | ||
sidebarDepth: 0 | ||
title: vue/no-root-v-if | ||
description: disallow `v-if` directives on root element | ||
--- | ||
|
||
# vue/no-root-v-if | ||
|
||
> disallow `v-if` directives on root element | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge> | ||
|
||
This rule reports template roots with `v-if`. Rendering of the whole component could be made conditional in the parent component (with a `v-if` there) instead. | ||
|
||
## :book: Rule Details | ||
|
||
This rule reports the template root in the following cases: | ||
|
||
<eslint-code-block :rules="{'vue/no-root-v-if': ['error']}"> | ||
|
||
```vue | ||
<template> | ||
<div v-if="foo"></div> | ||
</template> | ||
``` | ||
|
||
</eslint-code-block> | ||
|
||
## :wrench: Options | ||
|
||
Nothing. | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-root-v-if.js) | ||
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-root-v-if.js) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/** | ||
* @author Perry Song | ||
* @copyright 2023 Perry Song. All rights reserved. | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const utils = require('../utils') | ||
|
||
module.exports = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: 'disallow `v-if` directives on root element', | ||
categories: undefined, | ||
url: 'https://eslint.vuejs.org/rules/no-root-v-if.html' | ||
}, | ||
fixable: null, | ||
schema: [] | ||
}, | ||
/** @param {RuleContext} context */ | ||
create(context) { | ||
return { | ||
/** @param {Program} program */ | ||
Program(program) { | ||
const element = program.templateBody | ||
if (element == null) { | ||
return | ||
} | ||
|
||
const rootElements = element.children.filter(utils.isVElement) | ||
if ( | ||
rootElements.length === 1 && | ||
utils.hasDirective(rootElements[0], 'if') | ||
) { | ||
context.report({ | ||
node: element, | ||
loc: element.loc, | ||
message: | ||
'`v-if` should not be used on root element without `v-else`.' | ||
}) | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* @author Perry Song | ||
* @copyright 2023 Perry Song. All rights reserved. | ||
* See LICENSE file in root directory for full license. | ||
*/ | ||
'use strict' | ||
|
||
const RuleTester = require('eslint').RuleTester | ||
const rule = require('../../../lib/rules/no-root-v-if') | ||
|
||
const tester = new RuleTester({ | ||
parser: require.resolve('vue-eslint-parser'), | ||
parserOptions: { ecmaVersion: 2015 } | ||
}) | ||
|
||
tester.run('no-root-v-if', rule, { | ||
valid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: '' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div>abc</div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>\n <div>abc</div>\n</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>\n <!-- comment -->\n <div>abc</div>\n</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>\n <!-- comment -->\n <div v-if="foo">abc</div>\n <div v-else>abc</div>\n</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>\n <!-- comment -->\n <div v-if="foo">abc</div>\n <div v-else-if="bar">abc</div>\n <div v-else>abc</div>\n</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: `<template>\n <c1 v-if="1" />\n <c2 v-else-if="1" />\n <c3 v-else />\n</template>` | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div v-if="foo"></div><div v-else-if="bar"></div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template src="foo.html"></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div><textarea/>test</div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><table><custom-thead></custom-thead></table></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div></div><div></div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>\n <div></div>\n <div></div>\n</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>{{a b c}}</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div></div>aaaaaa</template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template>aaaaaa<div></div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div v-for="x in list"></div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><slot></slot></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><template></template></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template> <div v-if="mode === \'a\'"></div><div v-if="mode === \'b\'"></div></template>' | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div /><div v-if="foo" /></template>' | ||
} | ||
], | ||
invalid: [ | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><custom-component v-if="foo"></custom-component></template>', | ||
errors: ['`v-if` should not be used on root element without `v-else`.'] | ||
}, | ||
{ | ||
filename: 'test.vue', | ||
code: '<template><div v-if="foo"></div></template>', | ||
errors: ['`v-if` should not be used on root element without `v-else`.'] | ||
} | ||
] | ||
}) |