Skip to content

Commit 952ae33

Browse files
posvayyx990803
authored andcommitted
polish: warn when an existing property starting with $ is not pro… (#8214)
1 parent 496635e commit 952ae33

File tree

2 files changed

+60
-3
lines changed

2 files changed

+60
-3
lines changed

Diff for: src/core/instance/proxy.js

+16-3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,16 @@ if (process.env.NODE_ENV !== 'production') {
2424
)
2525
}
2626

27+
const warnReservedPrefix = (target, key) => {
28+
warn(
29+
`Property "${key}" must be accessed with "$data.${key}" because ` +
30+
'properties starting with "$" or "_" are not proxied in the Vue instance to ' +
31+
'prevent conflicts with Vue internals' +
32+
'See: https://vuejs.org/v2/api/#data',
33+
target
34+
)
35+
}
36+
2737
const hasProxy =
2838
typeof Proxy !== 'undefined' && isNative(Proxy)
2939

@@ -45,9 +55,11 @@ if (process.env.NODE_ENV !== 'production') {
4555
const hasHandler = {
4656
has (target, key) {
4757
const has = key in target
48-
const isAllowed = allowedGlobals(key) || (typeof key === 'string' && key.charAt(0) === '_')
58+
const isAllowed = allowedGlobals(key) ||
59+
(typeof key === 'string' && key.charAt(0) === '_' && !(key in target.$data))
4960
if (!has && !isAllowed) {
50-
warnNonPresent(target, key)
61+
if (key in target.$data) warnReservedPrefix(target, key)
62+
else warnNonPresent(target, key)
5163
}
5264
return has || !isAllowed
5365
}
@@ -56,7 +68,8 @@ if (process.env.NODE_ENV !== 'production') {
5668
const getHandler = {
5769
get (target, key) {
5870
if (typeof key === 'string' && !(key in target)) {
59-
warnNonPresent(target, key)
71+
if (key in target.$data) warnReservedPrefix(target, key)
72+
else warnNonPresent(target, key)
6073
}
6174
return target[key]
6275
}

Diff for: test/unit/features/instance/render-proxy.spec.js

+44
Original file line numberDiff line numberDiff line change
@@ -45,5 +45,49 @@ if (typeof Proxy !== 'undefined') {
4545

4646
expect(vm.$el.textContent).toBe('foo')
4747
})
48+
49+
it('should warn properties starting with $ when found', () => {
50+
new Vue({
51+
data: { $a: 'foo' },
52+
template: `<div>{{ $a }}</div>`
53+
}).$mount()
54+
expect(`Property "$a" must be accessed with "$data.$a"`).toHaveBeenWarned()
55+
})
56+
57+
it('should warn properties starting with _ when found', () => {
58+
new Vue({
59+
data: { _foo: 'foo' },
60+
template: `<div>{{ _foo }}</div>`
61+
}).$mount()
62+
expect(`Property "_foo" must be accessed with "$data._foo"`).toHaveBeenWarned()
63+
})
64+
65+
it('should warn properties starting with $ when not found', () => {
66+
new Vue({
67+
template: `<div>{{ $a }}</div>`
68+
}).$mount()
69+
expect(`Property or method "$a" is not defined`).toHaveBeenWarned()
70+
expect(`Property "$a" must be accessed with "$data.$a"`).not.toHaveBeenWarned()
71+
})
72+
73+
it('should warn properties starting with $ when not found (with stripped)', () => {
74+
const render = function (h) {
75+
return h('p', this.$a)
76+
}
77+
render._withStripped = true
78+
new Vue({
79+
data: { $a: 'foo' },
80+
render
81+
}).$mount()
82+
expect(`Property "$a" must be accessed with "$data.$a"`).toHaveBeenWarned()
83+
})
84+
85+
it('should not warn properties starting with $ when using $data to access', () => {
86+
new Vue({
87+
data: { $a: 'foo' },
88+
template: `<div>{{ $data.$a }}</div>`
89+
}).$mount()
90+
expect(`Property or method "$a" is not defined`).not.toHaveBeenWarned()
91+
})
4892
})
4993
}

0 commit comments

Comments
 (0)