Skip to content

Commit bdba4b4

Browse files
committed
Make no-ref-as-operand fixable close #1394
1 parent 1b75e28 commit bdba4b4

File tree

4 files changed

+212
-2
lines changed

4 files changed

+212
-2
lines changed

docs/rules/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ Enforce all the rules in this category, as well as all higher priority rules, wi
6464
| [vue/no-lifecycle-after-await](./no-lifecycle-after-await.md) | disallow asynchronously registered lifecycle hooks | |
6565
| [vue/no-mutating-props](./no-mutating-props.md) | disallow mutation of component props | |
6666
| [vue/no-parsing-error](./no-parsing-error.md) | disallow parsing errors in `<template>` | |
67-
| [vue/no-ref-as-operand](./no-ref-as-operand.md) | disallow use of value wrapped by `ref()` (Composition API) as an operand | |
67+
| [vue/no-ref-as-operand](./no-ref-as-operand.md) | disallow use of value wrapped by `ref()` (Composition API) as an operand | :wrench: |
6868
| [vue/no-reserved-keys](./no-reserved-keys.md) | disallow overwriting reserved keys | |
6969
| [vue/no-setup-props-destructure](./no-setup-props-destructure.md) | disallow destructuring of `props` passed to `setup` | |
7070
| [vue/no-shared-component-data](./no-shared-component-data.md) | enforce component's data property to be a function | :wrench: |

docs/rules/no-ref-as-operand.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ since: v7.0.0
1010
> disallow use of value wrapped by `ref()` (Composition API) as an operand
1111
1212
- :gear: This rule is included in all of `"plugin:vue/vue3-essential"`, `"plugin:vue/vue3-strongly-recommended"` and `"plugin:vue/vue3-recommended"`.
13+
- :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.
1314

1415
## :book: Rule Details
1516

@@ -49,6 +50,59 @@ export default {
4950

5051
</eslint-code-block>
5152

53+
<eslint-code-block fix :rules="{'vue/no-ref-as-operand': ['error']}">
54+
55+
```vue
56+
<script>
57+
import { ref } from 'vue'
58+
59+
export default {
60+
setup () {
61+
const count = ref(0)
62+
const ok = ref(true)
63+
/* ✗ BAD */
64+
count++
65+
count + 1
66+
1 + count
67+
var msg = ok ? 'yes' : 'no'
68+
69+
return {
70+
count
71+
}
72+
}
73+
}
74+
</script>
75+
```
76+
77+
</eslint-code-block>
78+
79+
<eslint-code-block fix :rules="{'vue/no-ref-as-operand': ['error']}">
80+
81+
```vue
82+
<script>
83+
import { ref } from 'vue'
84+
85+
export default {
86+
setup () {
87+
const count = ref(0)
88+
const ok = ref(true)
89+
90+
/* ✓ GOOD */
91+
count.value++
92+
count.value + 1
93+
1 + count.value
94+
var msg = ok.value ? 'yes' : 'no'
95+
96+
return {
97+
count
98+
}
99+
}
100+
}
101+
</script>
102+
```
103+
104+
</eslint-code-block>
105+
52106
## :wrench: Options
53107

54108
Nothing.

lib/rules/no-ref-as-operand.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ module.exports = {
1515
categories: ['vue3-essential'],
1616
url: 'https://eslint.vuejs.org/rules/no-ref-as-operand.html'
1717
},
18-
fixable: null,
18+
fixable: 'code',
1919
schema: [],
2020
messages: {
2121
requireDotValue:
@@ -46,6 +46,9 @@ module.exports = {
4646
messageId: 'requireDotValue',
4747
data: {
4848
method: data.method
49+
},
50+
fix(fixer) {
51+
return [fixer.insertTextAfter(node, '.value')]
4952
}
5053
})
5154
}

tests/lib/rules/no-ref-as-operand.js

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,14 @@ tester.run('no-ref-as-operand', rule, {
150150
console.log(count + 1) // error
151151
console.log(1 + count) // error
152152
`,
153+
output: `
154+
import { ref } from 'vue'
155+
let count = ref(0)
156+
157+
count.value++ // error
158+
console.log(count.value + 1) // error
159+
console.log(1 + count.value) // error
160+
`,
153161
errors: [
154162
{
155163
message:
@@ -195,6 +203,23 @@ tester.run('no-ref-as-operand', rule, {
195203
}
196204
</script>
197205
`,
206+
output: `
207+
<script>
208+
import { ref } from 'vue'
209+
export default {
210+
setup() {
211+
let count = ref(0)
212+
213+
count.value++ // error
214+
console.log(count.value + 1) // error
215+
console.log(1 + count.value) // error
216+
return {
217+
count
218+
}
219+
}
220+
}
221+
</script>
222+
`,
198223
errors: [
199224
{
200225
messageId: 'requireDotValue',
@@ -237,6 +262,23 @@ tester.run('no-ref-as-operand', rule, {
237262
}
238263
</script>
239264
`,
265+
output: `
266+
<script>
267+
import { ref } from '@vue/composition-api'
268+
export default {
269+
setup() {
270+
let count = ref(0)
271+
272+
count.value++ // error
273+
console.log(count.value + 1) // error
274+
console.log(1 + count.value) // error
275+
return {
276+
count
277+
}
278+
}
279+
}
280+
</script>
281+
`,
240282
errors: [
241283
{
242284
messageId: 'requireDotValue',
@@ -269,6 +311,13 @@ tester.run('no-ref-as-operand', rule, {
269311
//
270312
}
271313
`,
314+
output: `
315+
import { ref } from 'vue'
316+
const foo = ref(true)
317+
if (foo.value) {
318+
//
319+
}
320+
`,
272321
errors: [
273322
{
274323
messageId: 'requireDotValue',
@@ -284,6 +333,13 @@ tester.run('no-ref-as-operand', rule, {
284333
//
285334
}
286335
`,
336+
output: `
337+
import { ref } from 'vue'
338+
const foo = ref(true)
339+
switch (foo.value) {
340+
//
341+
}
342+
`,
287343
errors: [
288344
{
289345
messageId: 'requireDotValue',
@@ -300,6 +356,14 @@ tester.run('no-ref-as-operand', rule, {
300356
var c = !foo
301357
var d = ~foo
302358
`,
359+
output: `
360+
import { ref } from 'vue'
361+
const foo = ref(0)
362+
var a = -foo.value
363+
var b = +foo.value
364+
var c = !foo.value
365+
var d = ~foo.value
366+
`,
303367
errors: [
304368
{
305369
messageId: 'requireDotValue',
@@ -328,6 +392,14 @@ tester.run('no-ref-as-operand', rule, {
328392
baz += foo
329393
baz -= foo
330394
`,
395+
output: `
396+
import { ref } from 'vue'
397+
let foo = ref(0)
398+
foo.value += 1
399+
foo.value -= 1
400+
baz += foo.value
401+
baz -= foo.value
402+
`,
331403
errors: [
332404
{
333405
messageId: 'requireDotValue',
@@ -354,6 +426,12 @@ tester.run('no-ref-as-operand', rule, {
354426
var a = foo || other
355427
var b = foo && other
356428
`,
429+
output: `
430+
import { ref } from 'vue'
431+
const foo = ref(true)
432+
var a = foo.value || other
433+
var b = foo.value && other
434+
`,
357435
errors: [
358436
{
359437
messageId: 'requireDotValue',
@@ -371,6 +449,11 @@ tester.run('no-ref-as-operand', rule, {
371449
let foo = ref(true)
372450
var a = foo ? x : y
373451
`,
452+
output: `
453+
import { ref } from 'vue'
454+
let foo = ref(true)
455+
var a = foo.value ? x : y
456+
`,
374457
errors: [
375458
{
376459
messageId: 'requireDotValue',
@@ -395,6 +478,22 @@ tester.run('no-ref-as-operand', rule, {
395478
}
396479
</script>
397480
`,
481+
output: `
482+
<script>
483+
import { ref } from 'vue'
484+
let count = ref(0)
485+
export default {
486+
setup() {
487+
count.value++ // error
488+
console.log(count.value + 1) // error
489+
console.log(1 + count.value) // error
490+
return {
491+
count
492+
}
493+
}
494+
}
495+
</script>
496+
`,
398497
errors: [
399498
{
400499
messageId: 'requireDotValue',
@@ -451,6 +550,46 @@ tester.run('no-ref-as-operand', rule, {
451550
const n = foo + 1 // error
452551
</script>
453552
`,
553+
output: `
554+
<script>
555+
import { ref, computed, toRef, customRef, shallowRef } from 'vue'
556+
let count = ref(0)
557+
let cntcnt = computed(()=>count.value+count.value)
558+
559+
const state = reactive({
560+
foo: 1,
561+
bar: 2
562+
})
563+
564+
const fooRef = toRef(state, 'foo')
565+
566+
let value = 'hello'
567+
const cref = customRef((track, trigger) => {
568+
return {
569+
get() {
570+
track()
571+
return value
572+
},
573+
set(newValue) {
574+
clearTimeout(timeout)
575+
timeout = setTimeout(() => {
576+
value = newValue
577+
trigger()
578+
}, delay)
579+
}
580+
}
581+
})
582+
583+
const foo = shallowRef({})
584+
585+
count.value++ // error
586+
cntcnt.value++ // error
587+
588+
const s = \`\${fooRef.value} : \${cref.value}\` // error x 2
589+
590+
const n = foo.value + 1 // error
591+
</script>
592+
`,
454593
errors: [
455594
{
456595
message:
@@ -487,6 +626,13 @@ tester.run('no-ref-as-operand', rule, {
487626
foo.bar = 123
488627
</script>
489628
`,
629+
output: `
630+
<script>
631+
import { ref, computed, toRef, customRef, shallowRef } from 'vue'
632+
const foo = shallowRef({})
633+
foo.value.bar = 123
634+
</script>
635+
`,
490636
errors: [
491637
{
492638
messageId: 'requireDotValue'
@@ -501,6 +647,13 @@ tester.run('no-ref-as-operand', rule, {
501647
const bar = foo?.bar
502648
</script>
503649
`,
650+
output: `
651+
<script>
652+
import { ref } from 'vue'
653+
const foo = ref(123)
654+
const bar = foo.value?.bar
655+
</script>
656+
`,
504657
errors: [
505658
{
506659
messageId: 'requireDotValue'

0 commit comments

Comments
 (0)