在TSX文件中定义组件有几种常用方式:
setup
函数,但是不同之处它可以直接返回JSXexport default (props, ctx) => tree
defineComponent
:传递render
选项,也就是Options API,这种缺点是要访问this
export default defineComponent({
render() {
return tree
}
})
setup
选项,利用Composition API,避免this
,是推荐的形式export default defineComponent({
setup(props, ctx) {
return () => tree
}
})
Vue3中使用tsx,借助了babel-plugin-jsx,大部分语法和react-jsx相同,除了几个Vue独有的概念:修饰符、slot
、directive
、emit
,因此这里仅关注这些特殊部分:
import { withModifiers, defineComponent } from "vue";
const App = defineComponent({
setup() {
const count = ref(0);
const inc = () => {
count.value++;
};
return () => (
{count.value}
);
},
});
指令使用需要我们转换思维,有几种不同情况:
{}
,不是""
{ condition ? A : B }
import { defineComponent, ref } from "vue";
const App = defineComponent({
setup(){
const list = ref([])
return () => {
list.value.map((data,index) => {data}
)
}
}
});
defineComponent({
directives: {
focus: {
mounted(el) {
el.focus()
}
}
},
setup() {
return () =>
}
})
JSX中想要实现Vue中的插槽写法也有很大不同,主要利用一个叫做v-slots
的指令来实现:
Parent.tsx
export default defineComponent({
setup() {
return () => (
prefix, // 具名插槽
suffix: (props: Record<"name", string>) => {props.name}, // props可作插槽作用域的作用
}}
>
默认插槽内容
);
},
});
const Child = defineComponent({
setup(props, { slots }) {
return () => (
<>
默认插槽: {slots.default && slots.default()}
具名插槽: {slots.prefix && slots.prefix()}
作用域插槽:{slots.suffix && slots.suffix({ name: "suffix" })}
>
);
},
});
vue中子向父传值一般都是emit的方式,这个在vue3中大致写法相似,只是多了一个定义emit的步骤,这也是为了后续的类型推倒做准备。
defineComponent({
emits: ["click"],
setup(props ,{ emit }) {
return () => (
);
},
});