You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
501 lines
9.7 KiB
501 lines
9.7 KiB
import Vue, { PropType, VNode } from "../index";
|
|
import { ComponentOptions, Component } from "../index";
|
|
import { CreateElement } from "../vue";
|
|
|
|
interface MyComponent extends Vue {
|
|
a: number;
|
|
}
|
|
|
|
const option: ComponentOptions<MyComponent> = {
|
|
data() {
|
|
return {
|
|
a: 123
|
|
}
|
|
}
|
|
}
|
|
|
|
// contravariant generic should use never
|
|
const anotherOption: ComponentOptions<never> = option
|
|
const componentType: Component = option
|
|
|
|
Vue.component('sub-component', {
|
|
components: {
|
|
a: Vue.component(""),
|
|
b: {}
|
|
}
|
|
});
|
|
|
|
Vue.component('prop-component', {
|
|
props: {
|
|
size: Number,
|
|
name: {
|
|
type: String,
|
|
default: '0',
|
|
required: true,
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
fixedSize: this.size.toFixed(),
|
|
capName: this.name.toUpperCase()
|
|
}
|
|
}
|
|
});
|
|
|
|
Vue.component('string-prop', {
|
|
props: ['size', 'name'],
|
|
data() {
|
|
return {
|
|
fixedSize: this.size.whatever,
|
|
capName: this.name.isany
|
|
}
|
|
}
|
|
});
|
|
|
|
class User {
|
|
private u = 1
|
|
}
|
|
class Cat {
|
|
private u = 1
|
|
}
|
|
|
|
interface IUser {
|
|
foo: string,
|
|
bar: number
|
|
}
|
|
|
|
interface ICat {
|
|
foo: any,
|
|
bar: object
|
|
}
|
|
type ConfirmCallback = (confirm: boolean) => void;
|
|
|
|
Vue.component('union-prop', {
|
|
props: {
|
|
cat: Object as PropType<ICat>,
|
|
complexUnion: { type: [User, Number] as PropType<User | number> },
|
|
kittyUser: Object as PropType<ICat & IUser>,
|
|
callback: Function as PropType<ConfirmCallback>,
|
|
union: [User, Number] as PropType<User | number>
|
|
},
|
|
data() {
|
|
this.cat;
|
|
this.complexUnion;
|
|
this.kittyUser;
|
|
this.callback(true);
|
|
this.union;
|
|
return {
|
|
fixedSize: this.union,
|
|
}
|
|
}
|
|
});
|
|
|
|
Vue.component('union-prop-with-no-casting', {
|
|
props: {
|
|
mixed: [RegExp, Array],
|
|
object: [Cat, User],
|
|
primitive: [String, Number],
|
|
regex: RegExp
|
|
},
|
|
data() {
|
|
this.mixed;
|
|
this.object;
|
|
this.primitive;
|
|
this.regex.compile;
|
|
}
|
|
})
|
|
|
|
Vue.component('prop-with-primitive-default', {
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
default: () => String(Math.round(Math.random() * 10000000))
|
|
}
|
|
},
|
|
created(): void {
|
|
this.id;
|
|
}
|
|
});
|
|
|
|
Vue.component('component', {
|
|
data() {
|
|
this.$mount
|
|
this.size
|
|
return {
|
|
a: 1
|
|
}
|
|
},
|
|
props: {
|
|
size: Number,
|
|
name: {
|
|
type: String,
|
|
default: '0',
|
|
required: true,
|
|
}
|
|
},
|
|
propsData: {
|
|
msg: "Hello"
|
|
},
|
|
computed: {
|
|
aDouble(): number {
|
|
return this.a * 2;
|
|
},
|
|
aPlus: {
|
|
get(): number {
|
|
return this.a + 1;
|
|
},
|
|
set(v: number) {
|
|
this.a = v - 1;
|
|
},
|
|
cache: false
|
|
}
|
|
},
|
|
methods: {
|
|
plus(): void {
|
|
this.a++;
|
|
this.aDouble.toFixed();
|
|
this.aPlus = 1;
|
|
this.size.toFixed();
|
|
}
|
|
},
|
|
watch: {
|
|
'a': function(val: number, oldVal: number) {
|
|
console.log(`new: ${val}, old: ${oldVal}`);
|
|
},
|
|
'b': 'someMethod',
|
|
'c': {
|
|
handler(val, oldVal) {
|
|
this.a = val
|
|
},
|
|
deep: true
|
|
},
|
|
d: {
|
|
handler: 'someMethod',
|
|
immediate: true
|
|
}
|
|
},
|
|
el: "#app",
|
|
template: "<div>{{ message }}</div>",
|
|
render(createElement) {
|
|
return createElement("div", {
|
|
attrs: {
|
|
id: "foo"
|
|
},
|
|
props: {
|
|
myProp: "bar"
|
|
},
|
|
directives: [{
|
|
name: 'a',
|
|
value: 'foo'
|
|
}],
|
|
domProps: {
|
|
innerHTML: "baz"
|
|
},
|
|
on: {
|
|
click: new Function
|
|
},
|
|
nativeOn: {
|
|
click: new Function
|
|
},
|
|
class: {
|
|
foo: true,
|
|
bar: false
|
|
},
|
|
style: {
|
|
color: 'red',
|
|
fontSize: '14px'
|
|
},
|
|
key: 'myKey',
|
|
ref: 'myRef',
|
|
refInFor: true
|
|
}, [
|
|
createElement(),
|
|
createElement("div", "message"),
|
|
createElement(Vue.component("component")),
|
|
createElement({} as ComponentOptions<Vue>),
|
|
createElement({
|
|
functional: true,
|
|
render(c: CreateElement) {
|
|
return createElement()
|
|
}
|
|
}),
|
|
|
|
createElement(() => Vue.component("component")),
|
|
createElement(() => ( {} as ComponentOptions<Vue> )),
|
|
createElement((resolve, reject) => {
|
|
resolve({} as ComponentOptions<Vue>);
|
|
reject();
|
|
}),
|
|
|
|
"message",
|
|
|
|
[createElement("div", "message")]
|
|
]);
|
|
},
|
|
renderError(createElement, err) {
|
|
return createElement('pre', { style: { color: 'red' }}, err.stack)
|
|
},
|
|
staticRenderFns: [],
|
|
|
|
beforeCreate() {
|
|
(this as any).a = 1;
|
|
},
|
|
created() {},
|
|
beforeDestroy() {},
|
|
destroyed() {},
|
|
beforeMount() {},
|
|
mounted() {},
|
|
beforeUpdate() {},
|
|
updated() {},
|
|
activated() {},
|
|
deactivated() {},
|
|
errorCaptured(err, vm, info) {
|
|
err.message
|
|
vm.$emit('error')
|
|
info.toUpperCase()
|
|
return true
|
|
},
|
|
serverPrefetch () {
|
|
return Promise.resolve()
|
|
},
|
|
|
|
directives: {
|
|
a: {
|
|
bind() {},
|
|
inserted() {},
|
|
update() {},
|
|
componentUpdated() {},
|
|
unbind() {}
|
|
},
|
|
b(el, binding, vnode, oldVnode) {
|
|
el.textContent;
|
|
|
|
binding.name;
|
|
binding.value;
|
|
binding.oldValue;
|
|
binding.expression;
|
|
binding.arg;
|
|
binding.modifiers["modifier"];
|
|
}
|
|
},
|
|
components: {
|
|
a: Vue.component(""),
|
|
b: {} as ComponentOptions<Vue>
|
|
},
|
|
transitions: {},
|
|
filters: {
|
|
double(value: number) {
|
|
return value * 2;
|
|
}
|
|
},
|
|
parent: new Vue,
|
|
mixins: [Vue.component(""), ({} as ComponentOptions<Vue>)],
|
|
name: "Component",
|
|
extends: {} as ComponentOptions<Vue>,
|
|
delimiters: ["${", "}"]
|
|
});
|
|
|
|
|
|
Vue.component('custom-prop-type-function', {
|
|
props: {
|
|
callback: Function as PropType<(confirm: boolean) => void>,
|
|
},
|
|
methods: {
|
|
confirm(){
|
|
this.callback(true);
|
|
}
|
|
}
|
|
});
|
|
|
|
Vue.component('provide-inject', {
|
|
provide: {
|
|
foo: 1
|
|
},
|
|
inject: {
|
|
injectFoo: 'foo',
|
|
injectBar: Symbol(),
|
|
injectBaz: { from: 'baz' },
|
|
injectQux: { default: 1 },
|
|
injectQuux: { from: 'quuz', default: () => ({ value: 1 })}
|
|
}
|
|
})
|
|
|
|
Vue.component('provide-function', {
|
|
provide: () => ({
|
|
foo: 1
|
|
})
|
|
})
|
|
|
|
Vue.component('component-with-slot', {
|
|
render (h): VNode {
|
|
return h('div', this.$slots.default)
|
|
}
|
|
})
|
|
|
|
Vue.component('component-with-scoped-slot', {
|
|
render (h) {
|
|
interface ScopedSlotProps {
|
|
msg: string
|
|
}
|
|
|
|
return h('div', [
|
|
h('child', [
|
|
// default scoped slot as children
|
|
(props: ScopedSlotProps) => [h('span', [props.msg])]
|
|
]),
|
|
h('child', {
|
|
scopedSlots: {
|
|
// named scoped slot as vnode data
|
|
item: (props: ScopedSlotProps) => [h('span', [props.msg])]
|
|
}
|
|
}),
|
|
h('child', [
|
|
// return single VNode (will be normalized to an array)
|
|
(props: ScopedSlotProps) => h('span', [props.msg])
|
|
]),
|
|
h('child', {
|
|
// Passing down all slots from parent
|
|
scopedSlots: this.$scopedSlots
|
|
}),
|
|
h('child', {
|
|
// Passing down single slot from parent
|
|
scopedSlots: {
|
|
default: this.$scopedSlots.default
|
|
}
|
|
})
|
|
])
|
|
},
|
|
components: {
|
|
child: {
|
|
render (this: Vue, h: CreateElement) {
|
|
const defaultSlot = this.$scopedSlots['default']!({ msg: 'hi' })
|
|
defaultSlot && defaultSlot.forEach(vnode => {
|
|
vnode.tag
|
|
})
|
|
return h('div', [
|
|
defaultSlot,
|
|
this.$scopedSlots['item']!({ msg: 'hello' })
|
|
])
|
|
}
|
|
}
|
|
}
|
|
})
|
|
|
|
Vue.component('narrow-array-of-vnode-type', {
|
|
render (h): VNode {
|
|
const slot = this.$scopedSlots.default!({})
|
|
if (typeof slot === 'string') {
|
|
// <template slot-scope="data">bare string</template>
|
|
return h('span', slot)
|
|
} else if (Array.isArray(slot)) {
|
|
// template with multiple children
|
|
const first = slot[0]
|
|
if (!Array.isArray(first) && typeof first !== 'string' && first) {
|
|
return first
|
|
} else {
|
|
return h()
|
|
}
|
|
} else if (slot) {
|
|
// <div slot-scope="data">bare VNode</div>
|
|
return slot
|
|
} else {
|
|
// empty template, slot === undefined
|
|
return h()
|
|
}
|
|
}
|
|
})
|
|
|
|
Vue.component('functional-component', {
|
|
props: ['prop'],
|
|
functional: true,
|
|
inject: ['foo'],
|
|
render(createElement, context) {
|
|
context.props;
|
|
context.children;
|
|
context.slots();
|
|
context.data;
|
|
context.parent;
|
|
context.scopedSlots;
|
|
context.listeners.click;
|
|
return createElement("div", {}, context.children);
|
|
}
|
|
});
|
|
|
|
Vue.component('functional-component-object-inject', {
|
|
functional: true,
|
|
inject: {
|
|
foo: 'foo',
|
|
bar: Symbol(),
|
|
baz: { from: 'baz' },
|
|
qux: { default: 1 },
|
|
quux: { from: 'quuz', default: () => ({ value: 1 })}
|
|
},
|
|
render(h) {
|
|
return h('div')
|
|
}
|
|
})
|
|
|
|
Vue.component('functional-component-check-optional', {
|
|
functional: true
|
|
})
|
|
|
|
Vue.component('functional-component-multi-root', {
|
|
functional: true,
|
|
render(h) {
|
|
return [
|
|
h("tr", [h("td", "foo"), h("td", "bar")]),
|
|
h("tr", [h("td", "lorem"), h("td", "ipsum")])
|
|
]
|
|
}
|
|
})
|
|
|
|
Vue.component("async-component", ((resolve, reject) => {
|
|
setTimeout(() => {
|
|
resolve(Vue.component("component"));
|
|
}, 0);
|
|
return new Promise((resolve) => {
|
|
resolve({
|
|
functional: true,
|
|
render(h: CreateElement) { return h('div') }
|
|
});
|
|
})
|
|
}));
|
|
|
|
Vue.component('functional-component-v-model', {
|
|
props: ['foo'],
|
|
functional: true,
|
|
model: {
|
|
prop: 'foo',
|
|
event: 'change'
|
|
},
|
|
render(createElement, context) {
|
|
return createElement("input", {
|
|
on: {
|
|
input: new Function()
|
|
},
|
|
domProps: {
|
|
value: context.props.foo
|
|
}
|
|
});
|
|
}
|
|
});
|
|
|
|
|
|
Vue.component('async-es-module-component', () => import('./es-module'))
|
|
|
|
Vue.component('directive-expression-optional-string', {
|
|
render(createElement) {
|
|
return createElement("div", {
|
|
directives: [
|
|
{
|
|
name: 'has-expression',
|
|
value: 2,
|
|
expression: '1 + 1',
|
|
}, {
|
|
name: 'no-expression',
|
|
value: 'foo',
|
|
},
|
|
],
|
|
})
|
|
}
|
|
});
|
|
|