Skip to content

Commit 411e6c8

Browse files
committed
feat: add rule no-v-text
1 parent f6a1475 commit 411e6c8

File tree

3 files changed

+175
-0
lines changed

3 files changed

+175
-0
lines changed

docs/rules/no-v-text.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-v-text
5+
description: disallow use of v-text
6+
since: v7.17.0
7+
---
8+
# vue/no-v-text
9+
10+
> disallow use of v-text
11+
12+
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule.
13+
- However, when using selfClose to element with v-text like `<div v-text="foobar" />`, it can't be fixed.
14+
15+
## :book: Rule Details
16+
17+
This rule reports all uses of `v-text` directive.
18+
19+
20+
<eslint-code-block :rules="{'vue/no-v-text': ['error']}">
21+
22+
```vue
23+
<template>
24+
<!-- ✓ GOOD -->
25+
<div>{{ foobar }}</div>
26+
27+
<!-- ✗ BAD -->
28+
<div v-text="foobar"></div>
29+
<!-- Reported. However, Not fixable -->
30+
<div v-text="foobar" />
31+
</template>
32+
```
33+
34+
</eslint-code-block>
35+
36+
## :wrench: Options
37+
38+
Nothing.
39+
40+
## :rocket: Version
41+
42+
This rule was introduced in eslint-plugin-vue v7.17.0
43+
44+
## :mag: Implementation
45+
46+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-v-text.js)
47+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-v-text.js)

lib/rules/no-v-text.js

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/**
2+
* @author tyankatsu <https://github.com/tyankatsu0105>
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
'use strict'
6+
const utils = require('../utils')
7+
8+
// ------------------------------------------------------------------------------
9+
// Rule Definition
10+
// ------------------------------------------------------------------------------
11+
12+
/**
13+
*
14+
* @param {VElement} node
15+
* @returns {{node: VAttribute | VDirective, value: string}}
16+
*/
17+
const getVText = (node) => {
18+
const vText = node.startTag.attributes.find(
19+
(attribute) =>
20+
attribute.key.type === 'VDirectiveKey' &&
21+
attribute.key.name.name === 'text'
22+
)
23+
24+
if (!vText) return
25+
if (!vText.value) return
26+
if (vText.value.type !== 'VExpressionContainer') return
27+
if (!vText.value.expression) return
28+
if (vText.value.expression.type !== 'Identifier') return
29+
30+
const vTextValue = vText.value.expression.name
31+
32+
return {
33+
node: vText,
34+
value: vTextValue
35+
}
36+
}
37+
38+
module.exports = {
39+
meta: {
40+
type: 'suggestion',
41+
docs: {
42+
description: 'disallow use of v-text',
43+
categories: undefined,
44+
url: 'https://eslint.vuejs.org/rules/no-v-text.html'
45+
},
46+
fixable: 'code',
47+
schema: []
48+
},
49+
/** @param {RuleContext} context */
50+
create(context) {
51+
return utils.defineTemplateBodyVisitor(context, {
52+
/** @param {VElement} node */
53+
"VElement:has(VAttribute[directive=true][key.name.name='text'])"(node) {
54+
const vText = getVText(node)
55+
if (!vText) return
56+
57+
context.report({
58+
node: vText.node,
59+
loc: vText.loc,
60+
message: "Don't use 'v-text'.",
61+
fix(fixable) {
62+
if (node.startTag.selfClosing) return
63+
64+
return [
65+
fixable.remove(vText.node),
66+
fixable.insertTextAfterRange(
67+
node.startTag.range,
68+
`{{${vText.value}}}`
69+
)
70+
]
71+
}
72+
})
73+
}
74+
})
75+
}
76+
}

tests/lib/rules/no-v-text.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/**
2+
* @author tyankatsu <https://github.com/tyankatsu0105>
3+
* See LICENSE file in root directory for full license.
4+
*/
5+
6+
'use strict'
7+
8+
// ------------------------------------------------------------------------------
9+
// Requirements
10+
// ------------------------------------------------------------------------------
11+
12+
const RuleTester = require('eslint').RuleTester
13+
const rule = require('../../../lib/rules/no-v-text')
14+
15+
// ------------------------------------------------------------------------------
16+
// Tests
17+
// ------------------------------------------------------------------------------
18+
const ruleTester = new RuleTester({
19+
parser: require.resolve('vue-eslint-parser'),
20+
parserOptions: { ecmaVersion: 2015 }
21+
})
22+
23+
ruleTester.run('no-v-text', rule, {
24+
valid: [
25+
{
26+
filename: 'test.vue',
27+
code: ''
28+
},
29+
{
30+
filename: 'test.vue',
31+
code: '<template></template>'
32+
},
33+
{
34+
filename: 'test.vue',
35+
code: '<template><div>{{foobar}}</div></template>'
36+
}
37+
],
38+
invalid: [
39+
{
40+
filename: 'test.vue',
41+
code: '<template><div v-text="foobar"></div></template>',
42+
output: '<template><div >{{foobar}}</div></template>',
43+
errors: ["Don't use 'v-text'."]
44+
},
45+
{
46+
filename: 'test.vue',
47+
code: '<template><div v-text="foobar" /></template>',
48+
output: '<template><div v-text="foobar" /></template>',
49+
errors: ["Don't use 'v-text'."]
50+
}
51+
]
52+
})

0 commit comments

Comments
 (0)