File tree 2 files changed +69
-1
lines changed
test/unit/features/options
2 files changed +69
-1
lines changed Original file line number Diff line number Diff line change 1
1
/* @flow */
2
2
3
3
import { hasSymbol } from 'core/util/env'
4
+ import { warn } from '../util/index'
5
+ import { defineReactive } from '../observer/index'
4
6
5
7
export function initProvide ( vm : Component ) {
6
8
const provide = vm . $options . provide
@@ -29,7 +31,18 @@ export function initInjections (vm: Component) {
29
31
let source = vm
30
32
while ( source ) {
31
33
if ( source . _provided && provideKey in source . _provided ) {
32
- vm [ key ] = source . _provided [ provideKey ]
34
+ if ( process . env . NODE_ENV !== 'production' ) {
35
+ defineReactive ( vm , key , source . _provided [ provideKey ] , ( ) => {
36
+ warn (
37
+ `Avoid mutating a injections directly since the value will be ` +
38
+ `overwritten whenever the provided component re-renders. ` +
39
+ `injections being mutated: "${ key } "` ,
40
+ vm
41
+ )
42
+ } )
43
+ } else {
44
+ defineReactive ( vm , key , source . _provided [ provideKey ] )
45
+ }
33
46
break
34
47
}
35
48
source = source . $parent
Original file line number Diff line number Diff line change @@ -162,4 +162,59 @@ describe('Options provide/inject', () => {
162
162
expect ( vm . $el . textContent ) . toBe ( '123' )
163
163
} )
164
164
}
165
+
166
+ // Github issue #5223
167
+ it ( 'should work with reactive array' , done => {
168
+ const vm = new Vue ( {
169
+ template : `<div><child></child></div>` ,
170
+ data ( ) {
171
+ return {
172
+ foo : [ ]
173
+ }
174
+ } ,
175
+ provide ( ) {
176
+ return {
177
+ foo : this . foo
178
+ }
179
+ } ,
180
+ components : {
181
+ child : {
182
+ inject : [ 'foo' ] ,
183
+ template : `<span>{{foo.length}}</span>`
184
+ }
185
+ }
186
+ } ) . $mount ( )
187
+
188
+ expect ( vm . $el . innerHTML ) . toEqual ( `<span>0</span>` )
189
+ vm . foo . push ( vm . foo . length )
190
+ vm . $nextTick ( ( ) => {
191
+ expect ( vm . $el . innerHTML ) . toEqual ( `<span>1</span>` )
192
+ vm . foo . pop ( )
193
+ vm . $nextTick ( ( ) => {
194
+ expect ( vm . $el . innerHTML ) . toEqual ( `<span>0</span>` )
195
+ done ( )
196
+ } )
197
+ } )
198
+ } )
199
+
200
+ it ( 'should warn when injections has been modified' , ( ) => {
201
+ const key = 'foo'
202
+ const vm = new Vue ( {
203
+ provide : {
204
+ foo : 1
205
+ }
206
+ } )
207
+
208
+ const child = new Vue ( {
209
+ parent : vm ,
210
+ inject : [ 'foo' ]
211
+ } )
212
+
213
+ expect ( child . foo ) . toBe ( 1 )
214
+ child . foo = 2
215
+ expect (
216
+ `Avoid mutating a injections directly since the value will be ` +
217
+ `overwritten whenever the provided component re-renders. ` +
218
+ `injections being mutated: "${ key } "` ) . toHaveBeenWarned ( )
219
+ } )
165
220
} )
You can’t perform that action at this time.
0 commit comments