Skip to content

Commit 009ff3e

Browse files
committed
feat(RFC0011): add vue/no-custom-modifiers-on-v-model rule which checks if v-model has not allowed modifiers (Vue 2 backward compatibility)
1 parent 93a1ace commit 009ff3e

File tree

6 files changed

+185
-0
lines changed

6 files changed

+185
-0
lines changed

Diff for: docs/rules/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
3939
| Rule ID | Description | |
4040
|:--------|:------------|:---|
4141
| [vue/no-async-in-computed-properties](./no-async-in-computed-properties.md) | disallow asynchronous actions in computed properties | |
42+
| [vue/no-custom-modifiers-on-v-model](./no-custom-modifiers-on-v-model.md) | disallow custom modifiers on v-model used on the component | |
4243
| [vue/no-dupe-keys](./no-dupe-keys.md) | disallow duplication of field names | |
4344
| [vue/no-duplicate-attributes](./no-duplicate-attributes.md) | disallow duplication of attributes | |
4445
| [vue/no-parsing-error](./no-parsing-error.md) | disallow parsing errors in `<template>` | |

Diff for: docs/rules/no-custom-modifiers-on-v-model.md

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
pageClass: rule-details
3+
sidebarDepth: 0
4+
title: vue/no-custom-modifiers-on-v-model
5+
description: disallow custom modifiers on v-model used on the component
6+
---
7+
# vue/no-custom-modifiers-on-v-model
8+
> disallow custom modifiers on v-model used on the component
9+
10+
- :gear: This rule is included in all of `"plugin:vue/essential"`, `"plugin:vue/strongly-recommended"` and `"plugin:vue/recommended"`.
11+
12+
This rule checks whether `v-model `used on the component do not have custom modifiers.
13+
14+
## Rule Details
15+
16+
This rule reports `v-model` directives in the following cases:
17+
18+
- The directive used on the component has custom modifiers. E.g. `<MyComponent v-model.aaa="foo" />`
19+
20+
<eslint-code-block :rules="{'vue/no-custom-modifiers-on-v-model': ['error']}">
21+
22+
```vue
23+
<template>
24+
<!-- ✓ GOOD -->
25+
<MyComponent v-model="foo" />
26+
<MyComponent v-model.trim="foo" />
27+
<MyComponent v-model.lazy="foo" />
28+
<MyComponent v-model.number="foo" />
29+
30+
31+
<!-- ✗ BAD -->
32+
<MyComponent v-model.aaa="foo" />
33+
<MyComponent v-model.aaa.bbb="foo" />
34+
35+
</template>
36+
```
37+
38+
</eslint-code-block>
39+
40+
### Options
41+
42+
Nothing.
43+
44+
## :couple: Related rules
45+
46+
- [valid-v-model]
47+
48+
[valid-v-model]: valid-v-model.md
49+
50+
## :mag: Implementation
51+
52+
- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-custom-modifiers-on-v-model.js)
53+
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-custom-modifiers-on-v-model.js)

Diff for: lib/configs/essential.js

+1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module.exports = {
77
extends: require.resolve('./base'),
88
rules: {
99
'vue/no-async-in-computed-properties': 'error',
10+
'vue/no-custom-modifiers-on-v-model': 'error',
1011
'vue/no-dupe-keys': 'error',
1112
'vue/no-duplicate-attributes': 'error',
1213
'vue/no-parsing-error': 'error',

Diff for: lib/index.js

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ module.exports = {
3939
'no-async-in-computed-properties': require('./rules/no-async-in-computed-properties'),
4040
'no-boolean-default': require('./rules/no-boolean-default'),
4141
'no-confusing-v-for-v-if': require('./rules/no-confusing-v-for-v-if'),
42+
'no-custom-modifiers-on-v-model': require('./rules/no-custom-modifiers-on-v-model'),
4243
'no-deprecated-scope-attribute': require('./rules/no-deprecated-scope-attribute'),
4344
'no-deprecated-slot-attribute': require('./rules/no-deprecated-slot-attribute'),
4445
'no-deprecated-slot-scope-attribute': require('./rules/no-deprecated-slot-scope-attribute'),

Diff for: lib/rules/no-custom-modifiers-on-v-model.js

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/**
2+
* @author Przemyslaw Falowski (@przemkow)
3+
* @fileoverview This rule checks whether v-model used on the component do not have custom modifiers
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const utils = require('../utils')
12+
13+
// ------------------------------------------------------------------------------
14+
// Helpers
15+
// ------------------------------------------------------------------------------
16+
17+
const VALID_MODIFIERS = new Set(['lazy', 'number', 'trim'])
18+
19+
// ------------------------------------------------------------------------------
20+
// Rule Definition
21+
// ------------------------------------------------------------------------------
22+
23+
module.exports = {
24+
meta: {
25+
type: 'problem',
26+
docs: {
27+
description: 'disallow custom modifiers on v-model used on the component',
28+
category: 'essential',
29+
url: 'https://eslint.vuejs.org/rules/no-custom-modifiers-on-v-model.html'
30+
},
31+
fixable: null,
32+
schema: [],
33+
messages: {
34+
notSupportedModifier: "'v-model' directives don't support the modifier '{{name}}'."
35+
}
36+
},
37+
create (context) {
38+
return utils.defineTemplateBodyVisitor(context, {
39+
"VAttribute[directive=true][key.name.name='model']" (node) {
40+
const element = node.parent.parent
41+
42+
if (utils.isCustomComponent(element)) {
43+
for (const modifier of node.key.modifiers) {
44+
if (!VALID_MODIFIERS.has(modifier.name)) {
45+
context.report({
46+
node,
47+
loc: node.loc,
48+
messageId: 'notSupportedModifier',
49+
data: { name: modifier.name }
50+
})
51+
}
52+
}
53+
}
54+
}
55+
})
56+
}
57+
}

Diff for: tests/lib/rules/no-custom-modifiers-on-v-model.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/**
2+
* @author Przemyslaw Falowski (@przemkow)
3+
* @fileoverview This rule checks whether v-model used on the component do not have custom modifiers
4+
*/
5+
'use strict'
6+
7+
// ------------------------------------------------------------------------------
8+
// Requirements
9+
// ------------------------------------------------------------------------------
10+
11+
const rule = require('../../../lib/rules/no-custom-modifiers-on-v-model')
12+
const RuleTester = require('eslint').RuleTester
13+
14+
// ------------------------------------------------------------------------------
15+
// Tests
16+
// ------------------------------------------------------------------------------
17+
18+
const ruleTester = new RuleTester({
19+
parser: require.resolve('vue-eslint-parser'),
20+
parserOptions: { ecmaVersion: 2015 }
21+
})
22+
23+
ruleTester.run('no-custom-modifiers-on-v-model', rule, {
24+
25+
valid: [
26+
{
27+
filename: 'test.vue',
28+
code: '<template><MyComponent v-model:propName="foo"></template>'
29+
},
30+
{
31+
filename: 'test.vue',
32+
code: '<template><MyComponent v-model="foo"></template>'
33+
},
34+
{
35+
filename: 'test.vue',
36+
code: '<template><MyComponent v-model:propName.trim="foo"></template>'
37+
},
38+
{
39+
filename: 'test.vue',
40+
code: '<template><MyComponent v-model.trim="foo"></template>'
41+
},
42+
{
43+
filename: 'test.vue',
44+
code: '<template><MyComponent v-model:propName.lazy="foo"></template>'
45+
},
46+
{
47+
filename: 'test.vue',
48+
code: '<template><MyComponent v-model.lazy="foo"></template>'
49+
},
50+
{
51+
filename: 'test.vue',
52+
code: '<template><MyComponent v-model:propName.number="foo"></template>'
53+
},
54+
{
55+
filename: 'test.vue',
56+
code: '<template><MyComponent v-model.number="foo"></template>'
57+
}
58+
],
59+
60+
invalid: [
61+
{
62+
filename: 'test.vue',
63+
code: '<template><MyComponent v-model:propName.aaa="foo"></template>',
64+
errors: ["'v-model' directives don't support the modifier 'aaa'."]
65+
},
66+
{
67+
filename: 'test.vue',
68+
code: '<template><MyComponent v-model.aaa="foo"></template>',
69+
errors: ["'v-model' directives don't support the modifier 'aaa'."]
70+
}
71+
]
72+
})

0 commit comments

Comments
 (0)