JSX 是什么?
jsx 是javascript的语法拓宽,开始由React框架发明晰这种书写方法,在javascript 代码中灵活的书写xml语法,即兼容了JavaScript的语法的灵活性,一起也能够更好的书写咱们的模版xml代码。
为什么要在Vue中用JSX语法编写代码?
由于当前的Vue2.x 现已长期性的中止维护了,在公司的许多的项目当中仍是能够看到Vue2的Options 的安排的项目,在后续的项目晋级改造当中,想要直接运用React的代码然后节约咱们实践开发的时间,所以就想到了运用JSX的语法来直接改造Vue2的相关项目。
主要有以下的几种方法完成改造咱们的Vue2项意图代码
1 运用vue2 Options API 加上render function的方法。
在Vue2.x 的源码当中能够看到其实是支撑render写法的
…/types/options.d.ts 类型文件中:
data?: Data;
props?: PropsDef;
propsData?: object;
computed?: Accessors<Computed>;
methods?: Methods;
watch?: Record<string, WatchOptionsWithHandler<any> | WatchHandler<any> | string>;
el?: Element | string;
// 这儿能够看到其实是支撑咱们的 自界说template的模版的写法的
template?: string;
// hack is for functional component type inference, should not be used in user code
// 这儿能够看到能够用render 方法完成咱们的模版的功用
render?(createElement: CreateElement, hack: RenderContext<Props>): VNode;
renderError?(createElement: CreateElement, err: Error): VNode;
staticRenderFns?: ((createElement: CreateElement) => VNode)[];
beforeCreate?(this: V): void;
created?(): void;
beforeDestroy?(): void;
destroyed?(): void;
beforeMount?(): void;
mounted?(): void;
beforeUpdate?(): void;
updated?(): void;
activated?(): void;
deactivated?(): void;
errorCaptured?(err: Error, vm: Vue, info: string): boolean | void;
serverPrefetch?(this: V): Promise<void>;
directives?: { [key: string]: DirectiveFunction | DirectiveOptions };
components?: { [key: string]: Component<any, any, any, any> | AsyncComponent<any, any, any, any> };
transitions?: { [key: string]: object };
filters?: { [key: string]: Function };
provide?: object | (() => object);
inject?: InjectOptions;
model?: {
prop?: string;
event?: string;
};
parent?: Vue;
mixins?: (ComponentOptions<Vue> | typeof Vue)[];
name?: string;
// TODO: support properly inferred 'extends'
extends?: ComponentOptions<Vue> | typeof Vue;
delimiters?: [string, string];
comments?: boolean;
inheritAttrs?: boolean;
eg:render 的默许写法 留意: 需要删去咱们的单文件组件中的template块 ,默许应该是template的优先级要高于render方法界说的JSX。
render(h) {
return h('span', 'hello world')
}
或者直接return一个VNode
render(h) {
// return h('span', 'hello world')
return (
<div>
这是render VNode
</div>
)
}
class 与 style 的样式绑定,当咱们运用h函数 来完成咱们的模版时,经过TS的类型界说能够知道主要是VNodeData的这个类型。
export interface VNodeData {
key?: string | number;
slot?: string;
scopedSlots?: { [key: string]: ScopedSlot | undefined };
ref?: string;
refInFor?: boolean;
tag?: string;
staticClass?: string;
class?: any;
staticStyle?: { [key: string]: any };
style?: string | object[] | object;
props?: { [key: string]: any };
attrs?: { [key: string]: any };
domProps?: { [key: string]: any };
hook?: { [key: string]: Function };
on?: { [key: string]: Function | Function[] };
nativeOn?: { [key: string]: Function | Function[] };
transition?: object;
show?: boolean;
inlineTemplate?: {
render: Function;
staticRenderFns: Function[];
};
directives?: VNodeDirective[];
keepAlive?: boolean;
}
class 的绑定一般引荐运用 string 或者 string[] 类型, style 行内样式一般引荐运用
object 类型。
eg:
let classList = ['aaa','ccc']
return h('span', {
class: ['xxx', classList],
{
fontSize:'20px',
height: '10px',
}
});
当咱们直接运用回来VNode 的方法时,class 绑定运用string的方法, style绑定和React JSX 的运用方法共同。
eg:
return (
<div class={'aaa'} style={{ lineHeight: '10px' }}>
xxxxxx
</div>
)
在Vue2.7版别之下,假如想要体会Vue3的CompositionAPI 的组合式API的函数功用,咱们能够装置
@vue/composition-api
包,然后大局运用插件。
import VueCompositionAPI from '@vue/composition-api'
Vue.use(VueCompositionAPI)
之后便能够大局运用API
// 运用 API
import { ref, reactive } from '@vue/composition-api'
包括支撑 TSX | JSX的具体的界说模式可参阅:
2 晋级Vue2.7 的一起,运用Composition API 和 setup function来完成改造咱们的Vue项目。
首先,更新咱们的项目Vue版别为Vue2.7.x ,Vue2.7.x 以上版别内置了组合式API 的功用,因而咱们能够直接运用
import { defineComponent } from 'vue'
导入咱们的组件界说方法:
// demo.tsx
import { defineComponent } from 'vue'
export default defineComponent({
// type inference enabled
})
当咱们晋级到Vue2.7.x 版别的时候 能够运用setup 函数
来完成咱们组件的基本功用,一起也是支撑TypeScript的类型检查的功用的。
组件安排方法:
setup?: (
this: void,
props: Props,
ctx: SetupContext
) => Promise<RawBindings> | RawBindings | ((h: CreateElement) => VNode) | void
能够看到咱们也是能够经过template
模版和setup 函数
回来VNode来完成咱们的组件的。
1 xxx.vue 方法的单文件组件:
<template>
xxxxx
</template>
<script>
import { defineComponent,ref,reactive } from 'vue'
export default defineComponent({
// type inference enabled
})
</script>
<style lang='scss' scoped>
xxx
</style>
2 jsx | tsx 方法的组件安排形式: 回来一个VNode
// demo.(j|t)sx
import style from './HelloWorld.module.css';
import { defineComponent, PropType } from 'vue';
export default defineComponent({
name: 'HelloWorld',
props: {
msg: {
type: String,
required: true,
},
eventClick: {
type: (null as unknown) as PropType<(event: MouseEvent) => void>,
}
},
setup(props) {
return (h) => (
<div>
<h1 onClick={props.eventClick}>{props.msg}</h1>
<h3 class={style.listTitle}>Installed CLI Plugins</h3>
</div>
);
},
});
依据类型文件可知,咱们在setup函数中回来的Vnode 也能够运用h函数
来界说即:
setup(props){
return (h)=>{
return h('span', { class: ['xxx', classList], { fontSize:'20px', height: '10px', } });
}
}
当咱们晋级到Vue2.7之后,便能够去掉Options 的方法的安排代码的形式,一起装置@vue/composition-api
便能够运用到咱们的最新的Vue3特性的组合式API的方法来安排代码,例如ref,reactive
等api。onMounted,onUpdated
等生命周期hooks。 能够有用的整理咱们的代码和安排逻辑。复用组件以及自界说和复用hooks
。装置 @vueuse/core
包等。
支撑SSR
当咱们晋级到 Vue2.7.x 上时,也是能够运用ComponsitionAPI 来构建一个SSR代码的。
import { onServerPrefetch } from 'vue'
export default {
setup(props, { ssrContext }) {
const result = ref()
onServerPrefetch(async () => {
result.value = await callApi(ssrContext.someId)
})
return {
result,
}
}
}
总结
本文具体的介绍了咱们如何运用Vue2.x的项目,来改造晋级成JSX|TSX代码格局的组件格局。便利咱们搬迁React jsx| tsx 的相关代码。一起也对一些组件格局和Vue组件编写的方法做了一定的讨论。
相关链接
Vue2.x晋级: v2.cn.vuejs.org/v2/guide/mi…
VueUse: www.vueusejs.com/guide/