functional api support
Kingwl opened this issue ยท 6 comments
The ofType<Props>().covert
method should support ComponentOptions
and FunctionalComponentOptions
and should even support pure functions that return VNode | VNode[]
.
import { RenderContext } from 'vue';
import { ofType } from 'vue-tsx-support';
export interface HelloProps {
msg: string;
}
const Hello = ({ props }: RenderContext<HelloProps>) => (
<div class="hello">{props.msg}</div>
);
// Now you need to use `as any` or `// @ts-ignore` to ignore type checking.
export default ofType<HelloProps>().convert(Hello as any);
import Vue from 'vue';
import { createComponent, value, onMounted } from 'vue-function-api';
import { ofType } from 'vue-tsx-support';
type Inject = {
count: number;
};
const Counter = createComponent({
setup() {
const count = value(0);
onMounted(() => {
window.setTimeout(() => {
count.value++;
}, 3000);
});
return { count };
},
render(this: Vue & Inject) {
const { count } = this;
return <div class="counter">{count}</div>;
},
});
// @ts-ignore
export default ofType().covert(Counter);
I'm still considering how should we support composition-api.
This is workaround for now.
-
setup @vue/composition-api and babel-preset-vca-jsx according to their READMEs.
-
Put this code into your project. (for explanation, save as
vca.ts
)
import Vue, { VNode } from "vue";
import {
PropsForOutside,
RequiredPropNames,
TsxComponent
} from "vue-tsx-support";
import { createComponent } from "@vue/composition-api";
import { RecordPropsDefinition } from "vue/types/options";
import { SetupContext } from "@vue/composition-api";
export interface CompositionComponentOptions<
Props,
PropsDef extends RecordPropsDefinition<Props>
> {
name?: string;
props?: PropsDef;
setup(this: void, props: Props, ctx: SetupContext): () => VNode;
}
export interface ComponentFactory<EventsOn> {
create<
Props,
PropsDef extends RecordPropsDefinition<Props>,
RequiredProps extends keyof Props = RequiredPropNames<PropsDef> &
keyof Props
>(
options: CompositionComponentOptions<
Props,
PropsDef & RecordPropsDefinition<Props>
>
): TsxComponent<Vue & Props, PropsForOutside<Props, RequiredProps>, EventsOn>;
}
const factory = {
create(options: any): any {
return createComponent(options);
}
} as ComponentFactory<{}>;
export const component = factory.create;
export function componentFactoryOf<EventsOn>(): ComponentFactory<EventsOn> {
return factory;
}
And you can use composition-api with TSX like below
import { ref, onMounted } from "@vue/composition-api";
import * as vca from "./vca";
export const Counter = vca.component({
props: {
initialValue: { type: Number, default: 0 }
},
setup(props) {
const count = ref(props.initialValue);
onMounted(() => {
window.setTimeout(() => {
count.value++;
}, 3000);
});
return () => <div>{count.value}</div>;
}
});
@wonderful-panda maybe it's better to implement the support for TSX types directly in @vue/composition-api
? I can imagine a lot of people would be happy about this :)
@wonderful-panda Two things I wanted to ask:
- Maybe we should rename this issue to
composition-api
๐ - I'm confused about the difference between
vue-tsx-support
andbabel-preset-vca-jsx
, are they both Vue compilers to convert TSX files into regular Vue files? Is there anywhere I can read more information about that?
I've released 3.0.0-beta.7 which works with @vue/composition-api and babel-preset-vca-jsx.
@wonderful-panda I'm thinking of upgrading to v3 to be able to use the composition api.
I see it's still under heavy development though. When you think you think is a good time to upgrade? I want to avoid my project from crashing when I upgrade all package minor updates. : D