Skip to content

Commit

Permalink
Add vue/no-v-text-v-html-on-component rule (#1760)
Browse files Browse the repository at this point in the history
* Add `vue/no-v-text-v-html-on-component` rule

* add test case
  • Loading branch information
ota-meshi committed Jan 19, 2022
1 parent 9c6910e commit ae34c65
Show file tree
Hide file tree
Showing 5 changed files with 241 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -349,6 +349,7 @@ For example:
| [vue/no-use-computed-property-like-method](./no-use-computed-property-like-method.md) | disallow use computed property like method | |
| [vue/no-useless-mustaches](./no-useless-mustaches.md) | disallow unnecessary mustache interpolations | :wrench: |
| [vue/no-useless-v-bind](./no-useless-v-bind.md) | disallow unnecessary `v-bind` directives | :wrench: |
| [vue/no-v-text-v-html-on-component](./no-v-text-v-html-on-component.md) | disallow v-text / v-html on component | |
| [vue/no-v-text](./no-v-text.md) | disallow use of v-text | |
| [vue/padding-line-between-blocks](./padding-line-between-blocks.md) | require or disallow padding lines between blocks | :wrench: |
| [vue/prefer-separate-static-class](./prefer-separate-static-class.md) | require static class names in template to be in a separate `class` attribute | :wrench: |
Expand Down
43 changes: 43 additions & 0 deletions docs/rules/no-v-text-v-html-on-component.md
@@ -0,0 +1,43 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-v-text-v-html-on-component
description: disallow v-text / v-html on component
---
# vue/no-v-text-v-html-on-component

> disallow v-text / v-html on component
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>

## :book: Rule Details

This rule disallows the use of v-text / v-html on component.

If you use v-text / v-html on a component, it will overwrite the component's content and may break the component.

<eslint-code-block :rules="{'vue/no-v-text-v-html-on-component': ['error']}">

```vue
<template>
<!-- ✓ GOOD -->
<div v-text="content"></div>
<div v-html="html"></div>
<MyComponent>{{content}}</MyComponent>
<!-- ✗ BAD -->
<MyComponent v-text="content"></MyComponent>
<MyComponent v-html="html"></MyComponent>
</template>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-v-text-v-html-on-component.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-v-text-v-html-on-component.js)
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -145,6 +145,7 @@ module.exports = {
'no-v-for-template-key': require('./rules/no-v-for-template-key'),
'no-v-html': require('./rules/no-v-html'),
'no-v-model-argument': require('./rules/no-v-model-argument'),
'no-v-text-v-html-on-component': require('./rules/no-v-text-v-html-on-component'),
'no-v-text': require('./rules/no-v-text'),
'no-watch-after-await': require('./rules/no-watch-after-await'),
'object-curly-newline': require('./rules/object-curly-newline'),
Expand Down
59 changes: 59 additions & 0 deletions lib/rules/no-v-text-v-html-on-component.js
@@ -0,0 +1,59 @@
/**
* @author Yosuke Ota
* See LICENSE file in root directory for full license.
*/
'use strict'

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const utils = require('../utils')

// ------------------------------------------------------------------------------
// Rule Definition
// ------------------------------------------------------------------------------

module.exports = {
meta: {
type: 'problem',
docs: {
description: 'disallow v-text / v-html on component',
// TODO We will change it in the next major version.
// categories: ['essential', 'vue3-essential'],
categories: undefined,
url: 'https://eslint.vuejs.org/rules/no-v-text-v-html-on-component.html'
},
fixable: null,
schema: [],
messages: {
disallow:
"Using {{directiveName}} on component may break component's content."
}
},
/** @param {RuleContext} context */
create(context) {
/**
* Verify for v-text and v-html directive
* @param {VDirective} node
*/
function verify(node) {
const element = node.parent.parent
if (utils.isCustomComponent(element)) {
context.report({
node,
loc: node.loc,
messageId: 'disallow',
data: {
directiveName: `v-${node.key.name.name}`
}
})
}
}

return utils.defineTemplateBodyVisitor(context, {
"VAttribute[directive=true][key.name.name='text']": verify,
"VAttribute[directive=true][key.name.name='html']": verify
})
}
}
137 changes: 137 additions & 0 deletions tests/lib/rules/no-v-text-v-html-on-component.js
@@ -0,0 +1,137 @@
/**
* @author Yosuke Ota
* See LICENSE file in root directory for full license.
*/
'use strict'

const RuleTester = require('eslint').RuleTester
const rule = require('../../../lib/rules/no-v-text-v-html-on-component')

const tester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
parserOptions: {
ecmaVersion: 2020,
sourceType: 'module'
}
})

tester.run('no-v-text-v-html-on-component', rule, {
valid: [
{
filename: 'test.vue',
code: `
<template>
<div v-text="content" />
</template>
`
},
{
filename: 'test.vue',
code: `
<template>
<div v-html="content" />
</template>
`
},
{
filename: 'test.vue',
code: `
<template>
<MyComponent v-if="content" />
</template>
`
}
],
invalid: [
{
filename: 'test.vue',
code: `
<template>
<MyComponent v-text="content" />
</template>
`,
errors: [
{
message: "Using v-text on component may break component's content.",
line: 3,
column: 22
}
]
},
{
filename: 'test.vue',
code: `
<template>
<MyComponent v-html="content" />
</template>
`,
errors: [
{
message: "Using v-html on component may break component's content.",
line: 3,
column: 22
}
]
},
{
filename: 'test.vue',
code: `
<template>
<component :is="component" v-text="content" />
</template>
`,
errors: [
{
message: "Using v-text on component may break component's content.",
line: 3,
column: 36
}
]
},
{
filename: 'test.vue',
code: `
<template>
<component :is="component" v-html="content" />
</template>
`,
errors: [
{
message: "Using v-html on component may break component's content.",
line: 3,
column: 36
}
]
},
{
filename: 'test.vue',
code: `
<template>
<div :is="component" v-text="content" />
</template>
`,
errors: [
{
message: "Using v-text on component may break component's content.",
line: 3,
column: 30
}
]
},
{
filename: 'test.vue',
code: `
<template>
<div :is="component" v-html="content" />
</template>
`,
errors: [
{
message: "Using v-html on component may break component's content.",
line: 3,
column: 30
}
]
}
]
})

0 comments on commit ae34c65

Please sign in to comment.