Skip to content

Commit a6b9454

Browse files
committed
prop bindings should inherit parent reactivity to allow local mutation (fix #2549)
1 parent 5e8d6fe commit a6b9454

File tree

2 files changed

+34
-1
lines changed

2 files changed

+34
-1
lines changed

src/compiler/compile-props.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,14 @@ export function initProp (vm, prop, value) {
226226
value = getPropDefaultValue(vm, prop.options)
227227
}
228228
if (assertProp(prop, value)) {
229-
var doNotObserve = !prop.dynamic || isSimplePath(prop.raw)
229+
var doNotObserve =
230+
// if the passed down prop was already converted, then
231+
// subsequent sets should also be converted, because the user
232+
// may mutate the prop binding in the child component (#2549)
233+
!(value && value.__ob__) &&
234+
// otherwise we can skip observation for props that are either
235+
// literal or points to a simple path (non-derived values)
236+
(!prop.dynamic || isSimplePath(prop.raw))
230237
defineReactive(vm, key, value, doNotObserve)
231238
}
232239
}

test/unit/specs/directives/internal/prop_spec.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,4 +721,30 @@ describe('prop', function () {
721721
done()
722722
})
723723
})
724+
725+
// #2549
726+
it('mutating child prop binding should be reactive if parent value was reactive', function (done) {
727+
var vm = new Vue({
728+
el: el,
729+
template: '<comp :list="list"></comp>',
730+
data: {
731+
list: [1, 2, 3]
732+
},
733+
components: {
734+
comp: {
735+
props: ['list'],
736+
template: '<div v-for="i in list">{{ i }}</div>',
737+
created: function () {
738+
this.list = [2, 3, 4]
739+
}
740+
}
741+
}
742+
})
743+
expect(vm.$el.textContent).toBe('234')
744+
vm.$children[0].list.push(5)
745+
Vue.nextTick(function () {
746+
expect(vm.$el.textContent).toBe('2345')
747+
done()
748+
})
749+
})
724750
})

0 commit comments

Comments
 (0)