Skip to content

Commit

Permalink
ensure mutating extended constructor options does not affect parent (fix
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jan 22, 2017
1 parent b1e66b4 commit 769c4dc
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 6 deletions.
8 changes: 5 additions & 3 deletions src/core/instance/state.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,14 @@ const isReservedProp = { key: 1, ref: 1, slot: 1 }

function initProps (vm: Component, props: Object) {
const propsData = vm.$options.propsData || {}
const keys = vm.$options._propKeys = Object.keys(props)
// cache prop keys so that future props updates can iterate using Array
// instead of dyanmic object key enumeration.
const keys = vm.$options._propKeys = []
const isRoot = !vm.$parent
// root instance props should be converted
observerState.shouldConvert = isRoot
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
for (const key in props) {
keys.push(key)
/* istanbul ignore else */
if (process.env.NODE_ENV !== 'production') {
if (isReservedProp[key]) {
Expand Down
6 changes: 3 additions & 3 deletions src/core/util/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ strats.data = function (
}

/**
* Hooks and param attributes are merged as arrays.
* Hooks and props are merged as arrays.
*/
function mergeHook (
parentVal: ?Array<Function>,
Expand Down Expand Up @@ -155,7 +155,7 @@ config._assetTypes.forEach(function (type) {
*/
strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
/* istanbul ignore if */
if (!childVal) return parentVal
if (!childVal) return Object.create(parentVal || null)
if (!parentVal) return childVal
const ret = {}
extend(ret, parentVal)
Expand All @@ -178,7 +178,7 @@ strats.watch = function (parentVal: ?Object, childVal: ?Object): ?Object {
strats.props =
strats.methods =
strats.computed = function (parentVal: ?Object, childVal: ?Object): ?Object {
if (!childVal) return parentVal
if (!childVal) return Object.create(parentVal || null)
if (!parentVal) return childVal
const ret = Object.create(null)
extend(ret, parentVal)
Expand Down
9 changes: 9 additions & 0 deletions test/unit/features/global-api/extend.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,13 @@ describe('Global API: extend', () => {
const B = Vue.extend(options)
expect(A).toBe(B)
})

// #4767
it('extended options should use different identitfy from parent', () => {
const A = Vue.extend({ computed: {}})
const B = A.extend()
B.options.computed.b = () => 'foo'
expect(B.options.computed).not.toBe(A.options.computed)
expect(A.options.computed.b).toBeUndefined()
})
})

0 comments on commit 769c4dc

Please sign in to comment.