File tree Expand file tree Collapse file tree 2 files changed +69
-1
lines changed
test/unit/features/options Expand file tree Collapse file tree 2 files changed +69
-1
lines changed Original file line number Diff line number Diff line change 11/* @flow */
22
33import { hasSymbol } from 'core/util/env'
4+ import { warn } from '../util/index'
5+ import { defineReactive } from '../observer/index'
46
57export function initProvide ( vm : Component ) {
68 const provide = vm . $options . provide
@@ -29,7 +31,18 @@ export function initInjections (vm: Component) {
2931 let source = vm
3032 while ( source ) {
3133 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+ }
3346 break
3447 }
3548 source = source . $parent
Original file line number Diff line number Diff line change @@ -162,4 +162,59 @@ describe('Options provide/inject', () => {
162162 expect ( vm . $el . textContent ) . toBe ( '123' )
163163 } )
164164 }
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+ } )
165220} )
You can’t perform that action at this time.
0 commit comments