Skip to content

Commit

Permalink
fix(runtime-core): fix data merge order for mixins/extends
Browse files Browse the repository at this point in the history
fix #1953
  • Loading branch information
yyx990803 committed Aug 25, 2020
1 parent b742384 commit c15311c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 28 deletions.
33 changes: 19 additions & 14 deletions packages/runtime-core/__tests__/apiOptions.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -446,7 +446,7 @@ describe('api: options', () => {
calls.push('mixinA created')
expect(this.a).toBe(1)
expect(this.b).toBe(2)
expect(this.c).toBe(3)
expect(this.c).toBe(4)
},
mounted() {
calls.push('mixinA mounted')
Expand All @@ -468,7 +468,7 @@ describe('api: options', () => {
expect(this.a).toBe(1)
expect(this.b).toBe(2)
expect(this.bP).toBeUndefined()
expect(this.c).toBe(3)
expect(this.c).toBe(4)
expect(this.cP1).toBeUndefined()
},
mounted() {
Expand All @@ -484,7 +484,8 @@ describe('api: options', () => {
},
created() {
calls.push('mixinC created')
expect(this.c).toBe(3)
// component data() should overwrite mixin field with same key
expect(this.c).toBe(4)
expect(this.cP1).toBeUndefined()
},
mounted() {
Expand All @@ -498,6 +499,7 @@ describe('api: options', () => {
mixins: [defineComponent(mixinA), defineComponent(mixinB), mixinC],
data() {
return {
c: 4,
z: 4
}
},
Expand All @@ -506,7 +508,7 @@ describe('api: options', () => {
expect(this.a).toBe(1)
expect(this.b).toBe(2)
expect(this.bP).toBeUndefined()
expect(this.c).toBe(3)
expect(this.c).toBe(4)
expect(this.cP2).toBeUndefined()
expect(this.z).toBe(4)
},
Expand All @@ -517,7 +519,7 @@ describe('api: options', () => {
return `${this.a}${this.b}${this.c}`
}
})
expect(renderToString(h(Comp))).toBe(`123`)
expect(renderToString(h(Comp))).toBe(`124`)
expect(calls).toEqual([
'mixinA created',
'mixinB created',
Expand Down Expand Up @@ -546,7 +548,8 @@ describe('api: options', () => {
const Base = {
data() {
return {
a: 1
a: 1,
b: 1
}
},
methods: {
Expand Down Expand Up @@ -582,7 +585,8 @@ describe('api: options', () => {
const Base = {
data() {
return {
a: 1
a: 1,
x: 'base'
}
},
methods: {
Expand All @@ -595,22 +599,23 @@ describe('api: options', () => {
calls.push('base')
}
}
const Base2 = {
const Mixin = {
data() {
return {
b: true
b: true,
x: 'mixin'
}
},
mounted(this: any) {
expect(this.a).toBe(1)
expect(this.b).toBeTruthy()
expect(this.c).toBe(2)
calls.push('base2')
calls.push('mixin')
}
}
const Comp = defineComponent({
extends: defineComponent(Base),
mixins: [defineComponent(Base2)],
mixins: [defineComponent(Mixin)],
data() {
return {
c: 2
Expand All @@ -620,12 +625,12 @@ describe('api: options', () => {
calls.push('comp')
},
render() {
return `${this.a}${this.b}${this.c}`
return `${this.a}${this.b}${this.c}${this.x}`
}
})

expect(renderToString(h(Comp))).toBe(`1true2`)
expect(calls).toEqual(['base', 'base2', 'comp'])
expect(renderToString(h(Comp))).toBe(`1true2mixin`)
expect(calls).toEqual(['base', 'mixin', 'comp'])
})

test('accessing setup() state from options', async () => {
Expand Down
25 changes: 11 additions & 14 deletions packages/runtime-core/src/componentOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,24 +485,13 @@ export function applyOptions(
}
}

if (dataOptions) {
if (__DEV__ && !isFunction(dataOptions)) {
warn(
`The data option must be a function. ` +
`Plain object usage is no longer supported.`
)
}

if (asMixin) {
deferredData.push(dataOptions as DataFn)
} else {
resolveData(instance, dataOptions, publicThis)
}
}
if (!asMixin) {
if (deferredData.length) {
deferredData.forEach(dataFn => resolveData(instance, dataFn, publicThis))
}
if (dataOptions) {
resolveData(instance, dataOptions, publicThis)
}
if (__DEV__) {
const rawData = toRaw(instance.data)
for (const key in rawData) {
Expand All @@ -518,6 +507,8 @@ export function applyOptions(
}
}
}
} else if (dataOptions) {
deferredData.push(dataOptions as DataFn)
}

if (computedOptions) {
Expand Down Expand Up @@ -666,6 +657,12 @@ function resolveData(
dataFn: DataFn,
publicThis: ComponentPublicInstance
) {
if (__DEV__ && !isFunction(dataFn)) {
warn(
`The data option must be a function. ` +
`Plain object usage is no longer supported.`
)
}
const data = dataFn.call(publicThis, publicThis)
if (__DEV__ && isPromise(data)) {
warn(
Expand Down

0 comments on commit c15311c

Please sign in to comment.