vue中使用jsx语法是怎样的,写法有几种
Admin 2022-07-18 群英技术资讯 811 次浏览
在实际应用中,我们有时候会遇到“vue中使用jsx语法是怎样的,写法有几种”这样的问题,我们该怎样来处理呢?下文给大家介绍了解决方法,希望这篇“vue中使用jsx语法是怎样的,写法有几种”文章能帮助大家解决问题。又到了愉快的摸鱼时间,我觉得不能荒废,H5页面我一直用的vant,出于对源码的好奇,我从git上拉了一份vant源码,里面竟然都是jsx写的组件,于是我开始了对在vue中使用jsx的探索
在这之前,先了解下虚拟DOM,vue和react框架都在内部使用了虚拟DOM,这样做的原因是通过js操作DOM的计算成本很高,虽然js更新速度很快,但是查找dom并更新的成本很高。那么有什么方法可以优化呢,vue等框架使用js对象,通过改变js对象,最后进行批量处理,一次更新DOM,所以虚拟DOM本质上就是一个js对象
渲染函数是用来生成虚拟DOM的。我们在vue单文件中编写模板语法,最终会在底层实现中被编译成渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML。然而在一些场景中,你真的需要 JavaScript 的完全编程的能力。这时你可以用渲染函数,它比模板更接近编译器。
当出现以下场景,虽然下列写法也能实现想要的效果,但是他不仅冗长,而且我们为每个级别标题重复书写了 。当我们添加锚元素时,我们必须在每个 v-if/v-else-if 分支中再次重复它
const { createApp } = Vue
const app = createApp({})
app.component('anchored-heading', {
template: `
<h1 v-if="level === 1">
<slot></slot>
</h1>
<h2 v-else-if="level === 2">
<slot></slot>
</h2>
<h3 v-else-if="level === 3">
<slot></slot>
</h3>
<h4 v-else-if="level === 4">
<slot></slot>
</h4>
<h5 v-else-if="level === 5">
<slot></slot>
</h5>
<h6 v-else-if="level === 6">
<slot></slot>
</h6>
`,
props: {
level: {
type: Number,
required: true
}
}
})
虽然模板在大多数组件中都非常好用,但是显然在这里它就不合适了。那么,我们来尝试使用 render 函数重写上面的例子:
const { createApp, h } = Vue
const app = createApp({})
app.component('anchored-heading', {
render() {
return h(
'h' + this.level, // tag name
{}, // props/attributes
this.$slots.default() // array of children
)
},
props: {
level: {
type: Number,
required: true
}
}
})
这样写渲染函数有点痛苦,有没有更接近模板的写法呢,vue提供了一个babel-plugin-jsx babel插件来让vue支持jsx写法
我这边使用的vuecli创建的vue3 + ts项目,脚手架已经集成了jsx和ts的相关依赖
直接将文件后缀名从vue改成tsx或者jsx
在vue3中,可以直接使用render选项编写
import { defineComponent } from "vue";
export default defineComponent({
name: "Jsx",
render() {
return <div>我是一个div</div>;
},
});
也可以在setup中返回
import { defineComponent } from "vue";
export default defineComponent({
name: "Jsx",
setup() {
return () => <div>我是div</div>;
},
});
两种方式都可以,具体看个人习惯,setup中访问不到this,但是render中可以通过this访问当前vue实例
class绑定,和react的jsx绑定的有区别,react中使用className,vue中使用class
setup() {
return () => <div class="test">我是div</div>;
},
style绑定
setup() {
return () => <div style={{ color: "red" }}>我是div</div>;
},
props绑定
// 父组件
setup() {
return () => (
<div style={{ color: "red" }}>
<span>我是父组件</span>
<Mycom msg={"我是父组件传的值"} />
</div>
);
// 子组件,setup的第一个参数,可以获取props里的值
setup(props) {
return () => <div>我是子组件{props.msg}</div>;
},
事件绑定
setup() {
function eventClick() {
console.log("点击");
}
return () => <button onClick={eventClick}>按钮</button>;
},
组件自定义事件
// 子组件
import { defineComponent } from "vue";
export default defineComponent({
name: "Mycom",
emits: ["event"],
setup(props, { emit }) {
function sendData() {
emit("event", "子组件传递的数据");
}
return () => (
<div>
<span>自定义事件</span>
<button onClick={sendData}>传递数据</button>
</div>
);
},
});
// 父组件
// @ts-nocheck
// 这样写在jsx中没问题,但是在tsx中会报ts类型错误,所以我在上面忽略了当前文件ts监测@ts-nocheck
import { defineComponent } from "vue";
import Mycom from "./mycom";
export default defineComponent({
name: "Jsx",
setup() {
function getSon(msg: string) {
console.log(msg);
}
return () => (
<div>
<Mycom onEvent={getSon} />
</div>
);
},
});
也可以这样解决ts类型报错
setup() {
function getSon(msg: string) {
console.log(msg);
}
return () => (
<div>
<Mycom {...{ onEvent: getSon }} />
</div>
);
},
插槽
// 父组件
setup() {
const slots = {
test: () => <div>具名插槽</div>,
default: () => <div>默认插槽</div>,
};
return () => (
<div>
<Mycom v-slots={slots}></Mycom>
</div>
);
},
setup(props, { slots }) {
// 子组件
return () => (
<div>
<span>插槽</span>
{slots.default?.()}
{slots.test?.()}
</div>
);
},
指令,v-if,v-for等指令在jsx中无法使用,jsx只支持v-model和v-show指令
setup() {
const inputData = ref("");
return () => (
<div>
<span v-show={true}>显示</span>
<span v-show={false}>隐藏</span>
<input type="text" v-model={inputData.value} />
<span>{inputData.value}</span>
</div>
);
},
话不多说,我先打开vant源码,准备开启我的第一个组件源码阅读 src =>button=>button.tsx
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章主要为大家详细介绍了node+express实现分页效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要介绍了JS实现元素的拖动与占位功能,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要介绍了chrome监听cookie变化与赋值问题,cookie监听与赋值操作需要manifest文件里声明权限问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
这篇文章主要为大家详细介绍了js实现简单图片切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
众所周知javascript语言中只提供了几种基本类型的数据类型,而二叉树是一种数据结构,在一些查询等操作中能提供较好的性能,这篇文章主要给大家介绍了关于利用JS实现二叉树遍历算法的相关资料,需要的朋友可以参考下
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008