types: bump TS version + type test for createComponent
This commit is contained in:
parent
caad39c353
commit
e665a133e9
@ -41,7 +41,7 @@
|
|||||||
"rollup-plugin-terser": "^2.0.2",
|
"rollup-plugin-terser": "^2.0.2",
|
||||||
"rollup-plugin-typescript2": "^0.17.0",
|
"rollup-plugin-typescript2": "^0.17.0",
|
||||||
"ts-jest": "^23.10.0",
|
"ts-jest": "^23.10.0",
|
||||||
"typescript": "^3.1.3",
|
"typescript": "^3.5.0",
|
||||||
"yorkie": "^2.0.0"
|
"yorkie": "^2.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,8 +120,8 @@ export function trigger(
|
|||||||
// never been tracked
|
// never been tracked
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const effects = new Set()
|
const effects: Set<ReactiveEffect> = new Set()
|
||||||
const computedRunners = new Set()
|
const computedRunners: Set<ReactiveEffect> = new Set()
|
||||||
if (type === OperationTypes.CLEAR) {
|
if (type === OperationTypes.CLEAR) {
|
||||||
// collection being cleared, trigger all effects for target
|
// collection being cleared, trigger all effects for target
|
||||||
depsMap.forEach(dep => {
|
depsMap.forEach(dep => {
|
||||||
|
36
packages/runtime-core/__tests__/createComponent.spec.ts
Normal file
36
packages/runtime-core/__tests__/createComponent.spec.ts
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
import { createComponent } from '../src/component'
|
||||||
|
import { value } from '@vue/observer'
|
||||||
|
|
||||||
|
test('createComponent type inference', () => {
|
||||||
|
const MyComponent = createComponent({
|
||||||
|
props: {
|
||||||
|
a: Number,
|
||||||
|
b: {
|
||||||
|
type: String
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setup(props) {
|
||||||
|
props.a * 2
|
||||||
|
props.b.slice()
|
||||||
|
return {
|
||||||
|
c: value(1),
|
||||||
|
d: {
|
||||||
|
e: value('hi')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render({ state, props }) {
|
||||||
|
state.c * 2
|
||||||
|
state.d.e.slice()
|
||||||
|
props.a * 2
|
||||||
|
props.b.slice()
|
||||||
|
this.a * 2
|
||||||
|
this.b.slice()
|
||||||
|
this.c * 2
|
||||||
|
this.d.e.slice()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
MyComponent // avoid unused
|
||||||
|
// rename this file to .tsx to test TSX props inference
|
||||||
|
// ;(<MyComponent a={1} b="foo"/>)
|
||||||
|
})
|
@ -1,291 +0,0 @@
|
|||||||
import {
|
|
||||||
Component,
|
|
||||||
observable,
|
|
||||||
h,
|
|
||||||
nextTick,
|
|
||||||
KeepAlive,
|
|
||||||
ComponentPropsOptions,
|
|
||||||
ComponentWatchOptions
|
|
||||||
} from '@vue/runtime-core'
|
|
||||||
import { createInstance, renderInstance } from '@vue/runtime-test'
|
|
||||||
|
|
||||||
describe('class inheritance', () => {
|
|
||||||
it('should merge data', () => {
|
|
||||||
class Base extends Component {
|
|
||||||
foo = 1
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
bar: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
foo: number
|
|
||||||
bar: number
|
|
||||||
baz: number
|
|
||||||
qux: number = 4
|
|
||||||
|
|
||||||
data(): any {
|
|
||||||
return {
|
|
||||||
baz: 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const child = createInstance(Child)
|
|
||||||
|
|
||||||
expect(child.foo).toBe(1)
|
|
||||||
expect(child.bar).toBe(2)
|
|
||||||
expect(child.baz).toBe(3)
|
|
||||||
expect(child.qux).toBe(4)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should merge props', () => {
|
|
||||||
class Base extends Component {
|
|
||||||
static props: ComponentPropsOptions = {
|
|
||||||
foo: Number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
foo: number
|
|
||||||
bar: number
|
|
||||||
$props: { foo: number; bar: number }
|
|
||||||
static props: ComponentPropsOptions = {
|
|
||||||
bar: Number
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const child = createInstance(Child, {
|
|
||||||
foo: 1,
|
|
||||||
bar: 2
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(child.foo).toBe(1)
|
|
||||||
expect(child.bar).toBe(2)
|
|
||||||
expect(child.$props.foo).toBe(1)
|
|
||||||
expect(child.$props.bar).toBe(2)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should merge lifecycle hooks', async () => {
|
|
||||||
const calls: string[] = []
|
|
||||||
const state = observable({ ok: true })
|
|
||||||
|
|
||||||
class Base extends Component {
|
|
||||||
beforeCreate() {
|
|
||||||
calls.push('base beforeCreate')
|
|
||||||
}
|
|
||||||
created() {
|
|
||||||
calls.push('base created')
|
|
||||||
}
|
|
||||||
beforeMount() {
|
|
||||||
calls.push('base beforeMount')
|
|
||||||
}
|
|
||||||
mounted() {
|
|
||||||
calls.push('base mounted')
|
|
||||||
}
|
|
||||||
beforeUpdate() {
|
|
||||||
calls.push('base beforeUpdate')
|
|
||||||
}
|
|
||||||
updated() {
|
|
||||||
calls.push('base updated')
|
|
||||||
}
|
|
||||||
beforeUnmount() {
|
|
||||||
calls.push('base beforeUnmount')
|
|
||||||
}
|
|
||||||
unmounted() {
|
|
||||||
calls.push('base unmounted')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
beforeCreate() {
|
|
||||||
calls.push('child beforeCreate')
|
|
||||||
}
|
|
||||||
created() {
|
|
||||||
calls.push('child created')
|
|
||||||
}
|
|
||||||
beforeMount() {
|
|
||||||
calls.push('child beforeMount')
|
|
||||||
}
|
|
||||||
mounted() {
|
|
||||||
calls.push('child mounted')
|
|
||||||
}
|
|
||||||
beforeUpdate() {
|
|
||||||
calls.push('child beforeUpdate')
|
|
||||||
}
|
|
||||||
updated() {
|
|
||||||
calls.push('child updated')
|
|
||||||
}
|
|
||||||
beforeUnmount() {
|
|
||||||
calls.push('child beforeUnmount')
|
|
||||||
}
|
|
||||||
unmounted() {
|
|
||||||
calls.push('child unmounted')
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return state.ok ? 'foo' : 'bar'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Container extends Component {
|
|
||||||
show = true
|
|
||||||
render() {
|
|
||||||
return this.show ? h(Child) : null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const container = await renderInstance(Container)
|
|
||||||
expect(calls).toEqual([
|
|
||||||
'base beforeCreate',
|
|
||||||
'child beforeCreate',
|
|
||||||
'base created',
|
|
||||||
'child created',
|
|
||||||
'base beforeMount',
|
|
||||||
'child beforeMount',
|
|
||||||
'base mounted',
|
|
||||||
'child mounted'
|
|
||||||
])
|
|
||||||
|
|
||||||
calls.length = 0
|
|
||||||
state.ok = false
|
|
||||||
await nextTick()
|
|
||||||
expect(calls).toEqual([
|
|
||||||
'base beforeUpdate',
|
|
||||||
'child beforeUpdate',
|
|
||||||
'base updated',
|
|
||||||
'child updated'
|
|
||||||
])
|
|
||||||
|
|
||||||
calls.length = 0
|
|
||||||
container.show = false
|
|
||||||
await nextTick()
|
|
||||||
expect(calls).toEqual([
|
|
||||||
'base beforeUnmount',
|
|
||||||
'child beforeUnmount',
|
|
||||||
'base unmounted',
|
|
||||||
'child unmounted'
|
|
||||||
])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should merge lifecycle hooks (activated/deactivated)', async () => {
|
|
||||||
const calls: string[] = []
|
|
||||||
|
|
||||||
class Base extends Component {
|
|
||||||
activated() {
|
|
||||||
calls.push('base activated')
|
|
||||||
}
|
|
||||||
deactivated() {
|
|
||||||
calls.push('base deactivated')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
activated() {
|
|
||||||
calls.push('child activated')
|
|
||||||
}
|
|
||||||
deactivated() {
|
|
||||||
calls.push('child deactivated')
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return 'foo'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Container extends Component {
|
|
||||||
ok = true
|
|
||||||
render() {
|
|
||||||
return h(KeepAlive, this.ok ? h(Child) : null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const container = await renderInstance(Container)
|
|
||||||
expect(container.$el.text).toBe('foo')
|
|
||||||
|
|
||||||
container.ok = false
|
|
||||||
await nextTick()
|
|
||||||
expect(container.$el.text).toBe('')
|
|
||||||
expect(calls).toEqual(['base deactivated', 'child deactivated'])
|
|
||||||
|
|
||||||
calls.length = 0
|
|
||||||
container.ok = true
|
|
||||||
await nextTick()
|
|
||||||
expect(container.$el.text).toBe('foo')
|
|
||||||
expect(calls).toEqual(['base activated', 'child activated'])
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should merge watchers', async () => {
|
|
||||||
const fooCallback = jest.fn()
|
|
||||||
const barCallback = jest.fn()
|
|
||||||
|
|
||||||
class Base extends Component {
|
|
||||||
static watch: ComponentWatchOptions = {
|
|
||||||
foo: fooCallback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
foo = 1
|
|
||||||
bar = 2
|
|
||||||
static watch: ComponentWatchOptions = {
|
|
||||||
bar: barCallback
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const child = createInstance(Child)
|
|
||||||
child.foo = 2
|
|
||||||
await nextTick()
|
|
||||||
expect(fooCallback).toHaveBeenCalledWith(2, 1)
|
|
||||||
child.bar = 3
|
|
||||||
await nextTick()
|
|
||||||
expect(barCallback).toHaveBeenCalledWith(3, 2)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should inherit methods', () => {
|
|
||||||
const fooCallback = jest.fn()
|
|
||||||
const barCallback = jest.fn()
|
|
||||||
|
|
||||||
class Base extends Component {
|
|
||||||
foo() {
|
|
||||||
fooCallback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
bar() {
|
|
||||||
barCallback()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const child = createInstance(Child)
|
|
||||||
child.foo()
|
|
||||||
child.bar()
|
|
||||||
expect(fooCallback).toHaveBeenCalled()
|
|
||||||
expect(barCallback).toHaveBeenCalled()
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should inherit computed properties', () => {
|
|
||||||
class Base extends Component {
|
|
||||||
a = 1
|
|
||||||
get foo() {
|
|
||||||
return this.a + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Base {
|
|
||||||
b = 1
|
|
||||||
get bar() {
|
|
||||||
return this.b + this.foo + 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const child = createInstance(Child)
|
|
||||||
expect(child.foo).toBe(2)
|
|
||||||
expect(child.bar).toBe(4)
|
|
||||||
|
|
||||||
child.a = 2
|
|
||||||
expect(child.foo).toBe(3)
|
|
||||||
expect(child.bar).toBe(5)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,54 +0,0 @@
|
|||||||
import { h, Component, memoize, nextTick } from '../src'
|
|
||||||
import { renderInstance, serialize } from '@vue/runtime-test'
|
|
||||||
|
|
||||||
describe('memoize', () => {
|
|
||||||
it('should work', async () => {
|
|
||||||
class App extends Component {
|
|
||||||
count = 1
|
|
||||||
render() {
|
|
||||||
return h('div', [
|
|
||||||
this.count,
|
|
||||||
this.count % 2
|
|
||||||
? memoize(() => h('div', `A` + this.count), this, 0)
|
|
||||||
: null,
|
|
||||||
memoize(() => h('div', `B` + this.count), this, 1)
|
|
||||||
])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = await renderInstance(App)
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>1<div>A1</div><div>B1</div></div>`)
|
|
||||||
|
|
||||||
app.count++
|
|
||||||
await nextTick()
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>2<div>B1</div></div>`)
|
|
||||||
|
|
||||||
app.count++
|
|
||||||
await nextTick()
|
|
||||||
// test remounting a memoized tree
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>3<div>A1</div><div>B1</div></div>`)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should invalidate based on keys', async () => {
|
|
||||||
class App extends Component {
|
|
||||||
foo = 1
|
|
||||||
bar = 1
|
|
||||||
render() {
|
|
||||||
return memoize(() => h('div', this.foo + this.bar), this, 0, [this.bar])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = await renderInstance(App)
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>2</div>`)
|
|
||||||
|
|
||||||
app.foo++
|
|
||||||
await nextTick()
|
|
||||||
// should not update
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>2</div>`)
|
|
||||||
|
|
||||||
app.bar++
|
|
||||||
await nextTick()
|
|
||||||
// should update now
|
|
||||||
expect(serialize(app.$el)).toBe(`<div>4</div>`)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,294 +0,0 @@
|
|||||||
import { Component, ComponentClass, mixins } from '@vue/runtime-core'
|
|
||||||
import { createInstance } from '@vue/runtime-test'
|
|
||||||
import { prop } from '@vue/decorators'
|
|
||||||
|
|
||||||
const calls: string[] = []
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
calls.length = 0
|
|
||||||
})
|
|
||||||
|
|
||||||
class ClassMixinA extends Component<{ p1: string }, { d11: number }> {
|
|
||||||
// props
|
|
||||||
@prop
|
|
||||||
p1: string
|
|
||||||
// data
|
|
||||||
d1 = 1
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
d11: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// computed
|
|
||||||
get c1() {
|
|
||||||
return this.d1 + this.$data.d11
|
|
||||||
}
|
|
||||||
|
|
||||||
// lifecycle
|
|
||||||
created() {
|
|
||||||
calls.push('created from mixin A')
|
|
||||||
}
|
|
||||||
|
|
||||||
// methods
|
|
||||||
foo() {
|
|
||||||
return this.d1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ClassMixinB extends Component<{ p2: string }, { d21: number }> {
|
|
||||||
// props
|
|
||||||
static props = {
|
|
||||||
p2: String
|
|
||||||
}
|
|
||||||
|
|
||||||
// data
|
|
||||||
d2 = 1
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
d21: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get c2() {
|
|
||||||
return this.d2 + this.$data.d21
|
|
||||||
}
|
|
||||||
|
|
||||||
// lifecycle
|
|
||||||
created() {
|
|
||||||
calls.push('created from mixin B')
|
|
||||||
}
|
|
||||||
|
|
||||||
// methods
|
|
||||||
bar() {
|
|
||||||
return this.d2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ObjectMixinA = {
|
|
||||||
props: {
|
|
||||||
p1: String
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
d1: 1,
|
|
||||||
d11: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
c1() {
|
|
||||||
return this.d1 + this.d11
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
calls.push('created from mixin A')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
foo() {
|
|
||||||
return this.d1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const ObjectMixinB = {
|
|
||||||
props: {
|
|
||||||
p2: String
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
d2: 1,
|
|
||||||
d21: 2
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
c2() {
|
|
||||||
return this.d2 + this.d21
|
|
||||||
}
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
calls.push('created from mixin B')
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
bar() {
|
|
||||||
return this.d2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function assertMixins(Test: any) {
|
|
||||||
const instance = createInstance(Test, {
|
|
||||||
p1: '1',
|
|
||||||
p2: '2',
|
|
||||||
p3: '3'
|
|
||||||
}) as any
|
|
||||||
|
|
||||||
// data
|
|
||||||
expect(instance.d1).toBe(1)
|
|
||||||
expect(instance.d11).toBe(2)
|
|
||||||
expect(instance.d2).toBe(1)
|
|
||||||
expect(instance.d21).toBe(2)
|
|
||||||
expect(instance.d3).toBe(1)
|
|
||||||
expect(instance.d31).toBe(2)
|
|
||||||
|
|
||||||
// props
|
|
||||||
expect(instance.p1).toBe('1')
|
|
||||||
expect(instance.p2).toBe('2')
|
|
||||||
expect(instance.p3).toBe('3')
|
|
||||||
expect(instance.$props.p1).toBe('1')
|
|
||||||
expect(instance.$props.p2).toBe('2')
|
|
||||||
expect(instance.$props.p3).toBe('3')
|
|
||||||
|
|
||||||
// computed
|
|
||||||
expect(instance.c1).toBe(3)
|
|
||||||
expect(instance.c2).toBe(3)
|
|
||||||
expect(instance.c3).toBe(3)
|
|
||||||
|
|
||||||
// lifecycle
|
|
||||||
expect(calls).toEqual([
|
|
||||||
'created from mixin A',
|
|
||||||
'created from mixin B',
|
|
||||||
'created from Test'
|
|
||||||
])
|
|
||||||
|
|
||||||
// methods
|
|
||||||
expect(instance.foo()).toBe(1)
|
|
||||||
expect(instance.bar()).toBe(1)
|
|
||||||
expect(instance.baz()).toBe(1)
|
|
||||||
}
|
|
||||||
|
|
||||||
describe('mixins', () => {
|
|
||||||
it('should work with classes', () => {
|
|
||||||
class Test extends mixins(ClassMixinA, ClassMixinB)<
|
|
||||||
{ p3: string },
|
|
||||||
{ d31: number }
|
|
||||||
> {
|
|
||||||
static props = {
|
|
||||||
p3: String
|
|
||||||
}
|
|
||||||
|
|
||||||
d3 = 1
|
|
||||||
data(): any {
|
|
||||||
return {
|
|
||||||
d31: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get c3() {
|
|
||||||
return this.d3 + this.d31
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
|
||||||
calls.push('created from Test')
|
|
||||||
}
|
|
||||||
|
|
||||||
baz() {
|
|
||||||
return this.d3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const instance = createInstance(Test, {
|
|
||||||
p1: '1',
|
|
||||||
p2: '2',
|
|
||||||
p3: '3'
|
|
||||||
})
|
|
||||||
|
|
||||||
// we duplicate the assertions because they serve as type tests as well
|
|
||||||
|
|
||||||
// data
|
|
||||||
expect(instance.d1).toBe(1)
|
|
||||||
expect(instance.$data.d11).toBe(2)
|
|
||||||
expect(instance.d2).toBe(1)
|
|
||||||
expect(instance.$data.d21).toBe(2)
|
|
||||||
expect(instance.d3).toBe(1)
|
|
||||||
expect(instance.d31).toBe(2)
|
|
||||||
|
|
||||||
// props
|
|
||||||
expect(instance.p1).toBe('1')
|
|
||||||
expect(instance.$props.p2).toBe('2')
|
|
||||||
expect(instance.p3).toBe('3')
|
|
||||||
expect(instance.$props.p1).toBe('1')
|
|
||||||
expect(instance.$props.p2).toBe('2')
|
|
||||||
expect(instance.$props.p3).toBe('3')
|
|
||||||
|
|
||||||
// computed
|
|
||||||
expect(instance.c1).toBe(3)
|
|
||||||
expect(instance.c2).toBe(3)
|
|
||||||
expect(instance.c3).toBe(3)
|
|
||||||
|
|
||||||
// lifecycle
|
|
||||||
expect(calls).toEqual([
|
|
||||||
'created from mixin A',
|
|
||||||
'created from mixin B',
|
|
||||||
'created from Test'
|
|
||||||
])
|
|
||||||
|
|
||||||
// methods
|
|
||||||
expect(instance.foo()).toBe(1)
|
|
||||||
expect(instance.bar()).toBe(1)
|
|
||||||
expect(instance.baz()).toBe(1)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should work with objects', () => {
|
|
||||||
class Test extends ((mixins as any)(
|
|
||||||
ObjectMixinA,
|
|
||||||
ObjectMixinB
|
|
||||||
) as ComponentClass)<{ p3: string }, { d31: number }> {
|
|
||||||
static props = {
|
|
||||||
p3: String
|
|
||||||
}
|
|
||||||
|
|
||||||
d3 = 1
|
|
||||||
data(): any {
|
|
||||||
return {
|
|
||||||
d31: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get c3() {
|
|
||||||
return this.d3 + this.$data.d31
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
|
||||||
calls.push('created from Test')
|
|
||||||
}
|
|
||||||
|
|
||||||
baz() {
|
|
||||||
return this.d3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertMixins(Test)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should work with a mix of objects and classes', () => {
|
|
||||||
class Test extends ((mixins as any)(
|
|
||||||
ClassMixinA,
|
|
||||||
ObjectMixinB
|
|
||||||
) as ComponentClass)<{ p3: string }, { d31: number }> {
|
|
||||||
static props = {
|
|
||||||
p3: String
|
|
||||||
}
|
|
||||||
|
|
||||||
d3 = 1
|
|
||||||
data(): any {
|
|
||||||
return {
|
|
||||||
d31: 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
get c3() {
|
|
||||||
return this.d3 + this.$data.d31
|
|
||||||
}
|
|
||||||
|
|
||||||
created() {
|
|
||||||
calls.push('created from Test')
|
|
||||||
}
|
|
||||||
|
|
||||||
baz() {
|
|
||||||
return this.d3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
assertMixins(Test)
|
|
||||||
})
|
|
||||||
})
|
|
@ -1,120 +0,0 @@
|
|||||||
import {
|
|
||||||
h,
|
|
||||||
Component,
|
|
||||||
observable,
|
|
||||||
nextTick,
|
|
||||||
renderInstance
|
|
||||||
} from '@vue/runtime-test'
|
|
||||||
|
|
||||||
describe('Parent chain management', () => {
|
|
||||||
it('should have correct $parent / $root / $children', async () => {
|
|
||||||
let child: any
|
|
||||||
let grandChildren: any[] = []
|
|
||||||
|
|
||||||
const state = observable({ ok: true })
|
|
||||||
|
|
||||||
class Parent extends Component {
|
|
||||||
render() {
|
|
||||||
return h(Child)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Child extends Component {
|
|
||||||
created() {
|
|
||||||
child = this
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return [state.ok ? h(GrandChild) : null, h(GrandChild)]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class GrandChild extends Component {
|
|
||||||
created() {
|
|
||||||
grandChildren.push(this)
|
|
||||||
}
|
|
||||||
unmounted() {
|
|
||||||
grandChildren.splice(grandChildren.indexOf(this), 1)
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return h('div')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = await renderInstance(Parent)
|
|
||||||
|
|
||||||
expect(child.$parent).toBe(parent)
|
|
||||||
expect(child.$root).toBe(parent)
|
|
||||||
|
|
||||||
grandChildren.forEach(grandChild => {
|
|
||||||
expect(grandChild.$parent).toBe(child)
|
|
||||||
expect(grandChild.$root).toBe(parent)
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(parent.$children).toEqual([child])
|
|
||||||
expect(grandChildren.length).toBe(2)
|
|
||||||
expect(child.$children).toEqual(grandChildren)
|
|
||||||
|
|
||||||
state.ok = false
|
|
||||||
await nextTick()
|
|
||||||
expect(grandChildren.length).toBe(1)
|
|
||||||
expect(child.$children).toEqual(grandChildren)
|
|
||||||
})
|
|
||||||
|
|
||||||
it('should have correct $parent / $root w/ functional component in between', async () => {
|
|
||||||
let child: any
|
|
||||||
let grandChildren: any[] = []
|
|
||||||
|
|
||||||
const state = observable({ ok: true })
|
|
||||||
|
|
||||||
class Parent extends Component {
|
|
||||||
render() {
|
|
||||||
return h(FunctionalChild)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FunctionalChild = () => h(Child)
|
|
||||||
|
|
||||||
class Child extends Component {
|
|
||||||
created() {
|
|
||||||
child = this
|
|
||||||
}
|
|
||||||
render() {
|
|
||||||
return [
|
|
||||||
state.ok ? h(FunctionalGrandChild) : null,
|
|
||||||
h(FunctionalGrandChild)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const FunctionalGrandChild = () => h(GrandChild)
|
|
||||||
|
|
||||||
class GrandChild extends Component {
|
|
||||||
created() {
|
|
||||||
grandChildren.push(this)
|
|
||||||
}
|
|
||||||
unmounted() {
|
|
||||||
grandChildren.splice(grandChildren.indexOf(this), 1)
|
|
||||||
}
|
|
||||||
render() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
const parent = await renderInstance(Parent)
|
|
||||||
|
|
||||||
expect(child.$parent).toBe(parent)
|
|
||||||
expect(child.$root).toBe(parent)
|
|
||||||
|
|
||||||
grandChildren.forEach(grandChild => {
|
|
||||||
expect(grandChild.$parent).toBe(child)
|
|
||||||
expect(grandChild.$root).toBe(parent)
|
|
||||||
})
|
|
||||||
|
|
||||||
expect(parent.$children).toEqual([child])
|
|
||||||
expect(grandChildren.length).toBe(2)
|
|
||||||
expect(child.$children).toEqual(grandChildren)
|
|
||||||
|
|
||||||
state.ok = false
|
|
||||||
await nextTick()
|
|
||||||
expect(grandChildren.length).toBe(1)
|
|
||||||
expect(child.$children).toEqual(grandChildren)
|
|
||||||
})
|
|
||||||
})
|
|
2
packages/runtime-core/jsx.d.ts
vendored
2
packages/runtime-core/jsx.d.ts
vendored
@ -1,7 +1,7 @@
|
|||||||
declare namespace JSX {
|
declare namespace JSX {
|
||||||
interface Element {}
|
interface Element {}
|
||||||
interface ElementClass {
|
interface ElementClass {
|
||||||
render(props: any, slots: any, attrs: any): any
|
$props: {}
|
||||||
}
|
}
|
||||||
interface ElementAttributesProperty {
|
interface ElementAttributesProperty {
|
||||||
$props: {}
|
$props: {}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/runtime-core#readme",
|
"homepage": "https://github.com/vuejs/vue/tree/dev/packages/runtime-core#readme",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vue/observer": "3.0.0-alpha.1",
|
"@vue/observer": "3.0.0-alpha.1"
|
||||||
"@vue/scheduler": "3.0.0-alpha.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
packages/runtime-dom/jsx.d.ts
vendored
2
packages/runtime-dom/jsx.d.ts
vendored
@ -751,7 +751,7 @@ type NativeElements = {
|
|||||||
declare namespace JSX {
|
declare namespace JSX {
|
||||||
interface Element {}
|
interface Element {}
|
||||||
interface ElementClass {
|
interface ElementClass {
|
||||||
render(props: any, slots: any, attrs: any): any
|
$props: {}
|
||||||
}
|
}
|
||||||
interface ElementAttributesProperty {
|
interface ElementAttributesProperty {
|
||||||
$props: {}
|
$props: {}
|
||||||
|
@ -6072,10 +6072,10 @@ typedarray@^0.0.6:
|
|||||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||||
|
|
||||||
typescript@^3.1.3:
|
typescript@^3.5.0:
|
||||||
version "3.1.3"
|
version "3.5.1"
|
||||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
|
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.5.1.tgz#ba72a6a600b2158139c5dd8850f700e231464202"
|
||||||
integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==
|
integrity sha512-64HkdiRv1yYZsSe4xC1WVgamNigVYjlssIoaH2HcZF0+ijsk5YK2g0G34w9wJkze8+5ow4STd22AynfO6ZYYLw==
|
||||||
|
|
||||||
uglify-js@^3.1.4:
|
uglify-js@^3.1.4:
|
||||||
version "3.4.9"
|
version "3.4.9"
|
||||||
|
Loading…
Reference in New Issue
Block a user