目录
一、使用
1、安装插件
2、在中引入
二、声明tsx组件的三种方式
1、函数式组件
2、defineComponent() render的方式 Options API
3、defineComponent() setup的方式 Composition API
三、使用tsx的语法
语法1(只允许一个根节点)
语法2(v-model、v-show)
语法3(v-if 无效,找替代)
语法4:v-for 使用map代替
语法5:插槽
语法6:事件绑定 on+事件名
语法7:通过props向子组件传参
语法8:emit 事件派发
一、使用
1、安装插件
-
pnpm install @vitejs/plugin-vue-jsx -D
-
或 yarn add @vitejs/plugin-vue-jsx -D
2、在中引入
并在vue()后面添加上,所需的配置项 vueJsx,无配置就可以直接写为vueJsx()
-
vueJsx({
-
// options are passed on to @vue/babel-plugin-jsx
-
// 选项配置也是通过babel去设置的
-
}),
二、声明tsx组件的三种方式
1、函数式组件
-
// 缺点:一些复杂的配置项无法设置
-
export default () => <div>TestTsx</div>;
2、defineComponent() render的方式 Options API
-
export default defineComponent({
-
// 其他配置,data/props...
-
// 缺点:还要跟this打交道,访问变量需要用
-
render() {
-
return <div>TestTsx</div>;
-
},
-
});
3、defineComponent() setup的方式 Composition API
-
// defineComponent() setup Composition API
-
export default defineComponent({
-
// 其他配置,data/props...
-
setup() {
-
return () => <div>TestTsx1</div>;
-
},
-
});
三、使用tsx的语法
语法1(只允许一个根节点)
vue3中允许多个根节点同时存在,tsx不允许,我们可以设置一个<></>空标签来包裹
语法2(v-model、v-show)
v-model,v-show跟以前的用法类似,但注意后面不是双引号“”,而是大括号{}
注意:v-model里面绑定变量需要加上 .value ,这也是与vue3的区别
-
export default defineComponent({
-
// 其他配置,data/props...
-
setup() {
-
const counter = ref(0);
-
return () => (
-
<>
-
<div>TestTsx1</div>
-
<input type="text" v-model={counter.value} />
-
</>
-
);
-
},
-
});
语法3(v-if 无效,找替代)
需要用三目运算或&&来代替
<div>{isflag ? <span>A</span> : <span>B</span>}</div>
-
isActive && <p>123</p> //isActive === true的情况下,展示 && 后面的标签
-
-
isActive && title==='123' && <p>123</p>
-
//isActive === true && title==='123' 的情况下,展示 && 最后面的标签
语法4:v-for 使用map代替
-
<div>
-
{arr.value.map((item, i) => (
-
<p key={i}>
-
{item}--{i}
-
</p>
-
))}
-
</div>
运行结果:
语法5:插槽
jsx 中想实现vue中的插槽写法也有很大不同,主要利用 v-slots 的指令来实现:
插槽的三种接收方式:
-
export default defineComponent({
-
// 利用setup的第二个参数,可以接收插槽信息
-
setup(props, { slots }) {
-
return () => (
-
<>
-
默认插槽:{slots.default && slots.default()}
-
<br />
-
具名插槽:
-
{ && ()}
-
{slots.content && slots.content()}
-
<br />
-
作用域插槽:{ && ({ name: "作用域插槽内容" })}
-
<br />
-
</>
-
);
-
},
-
});
-
import Child from "./tchild";
-
export default defineComponent({
-
setup() {
-
return () => (
-
<>
-
<Child
-
v-slots={{
-
title: () => <h2>我是标题</h2>, //具名插槽
-
content: () => <h3>我是内容</h3>, //具名插槽
-
suffix: (props: { name: string }) => <span>{}</span>, //作用域插槽
-
}}
-
>
-
我是默认插槽内容
-
</Child>
-
</>
-
);
-
},
-
});
效果:
疑问来了,那我不用 v-slots 其实也可以实现,为啥还要用。只是用v-slots显得比较正规好理解~
-
<Child>
-
{{
-
default: "我是默认插槽的内容",
-
title: () => <h2>我是标题</h2>,
-
content: () => <h3>我是内容</h3>,
-
suffix: (props: { name: string }) => <span>{}</span>,
-
}}
-
</Child>
语法6:事件绑定 on+事件名
(小驼峰命名法)进行事件绑定
-
export default defineComponent({
-
emits: ["submit"],
-
setup() {
-
const handleClick = () => {
-
alert("我被点击了");
-
};
-
return (props, { emit }) => (
-
<>
-
<buttion onClick={handleClick}>按钮</buttion>
-
</>
-
);
-
},
-
});
语法7:通过props向子组件传参
看下面的例子,可以传递标签给子组件
-
import Child from "./tchild";
-
export default defineComponent({
-
setup() {
-
const msg = "我是来自父组件的消息";
-
return () => (
-
<>
-
<Child msg={msg} childs={[<h3>我是一</h3>, <h3>我是二</h3>]}></Child>
-
</>
-
);
-
},
-
});
-
export default defineComponent({
-
props: {
-
msg: String,
-
childs: Array,
-
},
-
// 利用setup的第二个参数,可以接收插槽信息
-
setup(props, { slots }) {
-
(props);
-
return () => (
-
<>
-
<p>{}</p>
-
<p>{[0]}</p>
-
</>
-
);
-
},
-
});
语法8:emit 事件派发
vue中子向父传值都是emit的方式,这个在vue3中写法相似,只是多了一个定义emit的步骤,这也是为了后续的类型推导做准备
注意:父组件接收子组件发射的方法同样需要加上 on
-
import Child from "./tchild";
-
export default defineComponent({
-
setup() {
-
const msg = "我是来自父组件的消息";
-
const numClick = (val) => {
-
alert(val);
-
};
-
return () => (
-
<>
-
<Child msg={msg} onNumClick={numClick}></Child>
-
</>
-
);
-
},
-
});
注意:子组件中需要添加 emits: ["numClick"],同vue3类似,vue3中也需要添加defineEmits将事件发射出去
-
export default defineComponent({
-
emits: ["numClick"],
-
props: {
-
msg: String,
-
childs: Array,
-
},
-
// 利用setup的第二个参数,可以接收插槽信息
-
setup(props, { emit }) {
-
const count = ref(1);
-
const childClick = () => {
-
emit("numClick", count.value);
-
};
-
return () => (
-
<>
-
<Button onClick={childClick}>触发父组件事件</Button>
-
</>
-
);
-
},
-
});
还有一些样式设置及进阶的知识,见下一篇文章哦~