Skip to content

Commit 4139e76

Browse files
committed
Improve the vue/no-setup-props-destructure rule
1 parent 6a4a7da commit 4139e76

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

lib/rules/no-setup-props-destructure.js

+34-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ module.exports = {
2323
'Getting a value from the `props` in root scope of `{{scopeName}}` will cause the value to lose reactivity.'
2424
}
2525
},
26-
/** @param {RuleContext} context */
26+
/**
27+
* @param {RuleContext} context
28+
* @returns {RuleListener}
29+
**/
2730
create(context) {
2831
/**
2932
* @typedef {object} ScopePropsReferences
@@ -59,13 +62,38 @@ module.exports = {
5962
}
6063

6164
const rightNode = utils.skipChainExpression(right)
65+
66+
if (rightNode.type === 'CallExpression') {
67+
const propRefs = [...propsReferences.refs.values()]
68+
const isPropsMemberAccessed = propRefs.some((props) => {
69+
const isPropsInCallExpression = utils.inRange(rightNode.range, props)
70+
71+
if (isPropsInCallExpression) {
72+
const isPropMemberExpression =
73+
props.parent.type === 'MemberExpression' &&
74+
props.parent.object === props
75+
76+
if (isPropMemberExpression) {
77+
return true
78+
}
79+
}
80+
81+
return false
82+
})
83+
84+
if (isPropsMemberAccessed) {
85+
return report(left, 'getProperty', propsReferences.scopeName)
86+
}
87+
}
88+
6289
if (
6390
left.type !== 'ArrayPattern' &&
6491
left.type !== 'ObjectPattern' &&
6592
rightNode.type !== 'MemberExpression'
6693
) {
6794
return
6895
}
96+
6997
/** @type {Expression | Super} */
7098
let rightId = rightNode
7199
while (rightId.type === 'MemberExpression') {
@@ -114,6 +142,11 @@ module.exports = {
114142
}
115143
const propsReferenceIds = new Set()
116144
for (const reference of variable.references) {
145+
// If reference is in another scope, we can't check it.
146+
if (reference.from !== context.getScope()) {
147+
continue
148+
}
149+
117150
if (!reference.isRead()) {
118151
continue
119152
}

tests/lib/rules/no-setup-props-destructure.js

+76
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,27 @@ tester.run('no-setup-props-destructure', rule, {
205205
line: 4
206206
}
207207
]
208+
},
209+
{
210+
filename: 'test.vue',
211+
code: `
212+
<script>
213+
export default {
214+
setup: (props) => {
215+
const count = computed(() => props.count)
216+
}
217+
}
218+
</script>
219+
`
220+
},
221+
{
222+
filename: 'test.vue',
223+
code: `
224+
<script setup>
225+
const props = defineProps({ count: Number })
226+
const count = computed(() => props.count)
227+
</script>
228+
`
208229
}
209230
],
210231
invalid: [
@@ -411,6 +432,18 @@ tester.run('no-setup-props-destructure', rule, {
411432
{
412433
messageId: 'getProperty',
413434
line: 7
435+
},
436+
{
437+
messageId: 'getProperty',
438+
line: 9
439+
},
440+
{
441+
messageId: 'getProperty',
442+
line: 10
443+
},
444+
{
445+
messageId: 'getProperty',
446+
line: 11
414447
}
415448
]
416449
},
@@ -525,6 +558,49 @@ tester.run('no-setup-props-destructure', rule, {
525558
line: 5
526559
}
527560
]
561+
},
562+
{
563+
filename: 'test.vue',
564+
code: `
565+
<script>
566+
export default {
567+
setup: (props) => {
568+
const count = ref(props.count)
569+
count = fn(props.count)
570+
}
571+
}
572+
</script>
573+
`,
574+
errors: [
575+
{
576+
messageId: 'getProperty',
577+
line: 5
578+
},
579+
{
580+
messageId: 'getProperty',
581+
line: 6
582+
}
583+
]
584+
},
585+
{
586+
filename: 'test.vue',
587+
code: `
588+
<script setup>
589+
const props = defineProps({ count: Number })
590+
const count = ref(props.count)
591+
count = fn(props.count)
592+
</script>
593+
`,
594+
errors: [
595+
{
596+
messageId: 'getProperty',
597+
line: 4
598+
},
599+
{
600+
messageId: 'getProperty',
601+
line: 5
602+
}
603+
]
528604
}
529605
]
530606
})

0 commit comments

Comments
 (0)