在 Vue 中使用 JSX 及使用它的原因浅析
本文GitHubhttps://github.com/qq44924588...上已经收录,更多往期高赞文章的分类,也整理了很多我的文档,和教程资料。欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。
Vue.js具有简单的API和几个选项,可用于在我们的组件中定义HTML模板。
我们可以使用标签选项,在根组件实例上定义template属性,或者使用单文件组件。
上面的选项很棒并且可以完美地工作,但是,在您的应用程序的生命周期中,有时会感到笨拙,设计过度或非常不灵活。
那么,我们为什么要使用JSX而不是其他模板定义呢?
- JSX更易读,的写法一看就是比this.$createElement('div',{},[...])简洁很多。
- JSX也是JavaScript。
- Vue支持JSX。
- JSX使自定义Vue组件更容易导入和管理。
简介
先举一个例子来说明为什么JSX是好的。
我们要构建一个
从上面的代码片段中可以看到,我们很快就会遇到一些问题,比如重复代码等等。想象一下,必须支持input上面所列的各种属性。上面的这个小片段将会增长并成为一个难以维护的噩梦。
要解决这个问题,我们需要使用Vue进行降级处理,因此需要使用理接近Vue的内部API来解决这个问题。
render()方法
注意:这里并不是说没有JSX就没有一种简单的方法来处理上面的问题,只是说将这个逻辑移动到带有JSX的render()方法可以使组件更直观。
我们在Vue中创建的每个组件都有一个render方法。这个就是Vue选择渲染组件的地方。即使我们不定义这个方法,Vue也会为我们做这件事。
这意味着当我们在Vue中定义HTML模板时,Vue的模板编译器将其编译为一个createElement函数,该函数带有几个参数并从render函数返回结果。
为了修复上一节中的代码,我们删除了template属性或template标签,并在组件上定义了render()方法。如果在组件上定义了render方法,则Vue将忽略template定义。
...
exportdefault{
name:'TextField',
render(createElement){
consttag=this.multiline?'textarea':'input'
returncreateElement(tag,{
class:{
'text-input':true,
'is-disabled':false
},
attrs:{
name:this.name,
placeholder:this.placeholder,
'aria-invalid':false
}
})
}
}
...
上面的代码做了几件事:
- render方法从Vue获取一个createElement助手。
- 我们以编程方式定义我们的标签。
- 然后,我们创建标签并将其属性,类等作为对象传递。我们可以传递给createElement的选项很多。
- 我们返回新创建的元素进行渲染。
我们为Vue组件定义的每个模板都将转换为可返回createElement函数的render方法。因为这个原因,render方法将优先于模板定义。
举个例子:
//HTMLOnlyyoucanstopforestfires
模板编译器将把上面的HTML转换成:
...
render(createElement){
returncreateElement(
'div',
{},
createElement(
'p',
{},
'Onlyyoucanstopforestfires'
)
)
}
...
现在你可能会问这个问题:“对可读性来说这不好吗?”答案是肯定的。一旦定义了具有许多元素嵌套级别或具有多个同级元素的组件,我们就会遇到这个新问题。
这就是JSX出现的原因,它可以很好的解决此类问题。
JSX是什么
JSX是Facebook工程团队创造的一个术语。
JSX是JavaScript的类似XML的语法扩展,没有任何定义的语义。
JSX不打算由引擎或浏览器实现。相反,我们将使用Babel之类的转置器将JSX转换成常规的JS。
//此行是JSX的示例 constheading=WelcometoScotch
;
基本上,JSX允许我们在JS中使用类似Html的语法。
配置Vue以使用JSX
如果使用的Vue-cli大于或等于3.0版本,那么就直接可以使用JSX的语法了。
如果您使用的是不支持JSX的Vue-cli较旧版本,则可以通过安装babel-preset-vue-app来添加它,并将其添加到您的.babelrc文件中。
#Usingnpm npminstall--save-devbabel-preset-vue-app #Usingyarn yarnadd--devbabel-preset-vue-app
在.babelrc文件中,添加:
{
"presets":["vue-app"]
}
我们现在可以在组件的render函数中使用JSX。
在Vue中使用JSX需要注意的地方
在Vue中使用JSX需要注意几点。
要监听JSX中的事件,我们需要“on”前缀。例如,将onClick用于单击事件。
render(createElement){
return(
)
}
要修改事件,请使用
render(createElement){
return(
)
}
绑定变量,注意这里不是使用:
render(createElement){
return(
)
}
将HTML字符串设置为元素的内容,使用domPropsInnerHTML而不是使用v-html
render(createElement){
return(
)
}
我们也可以展开一个大对象:
render(createElement){
return(
)
}
在render中使用JSX
回到我们最初的“TextField”组件。现在我们已经在Vue应用程序中启用了JSX,我们现在可以这样做了。
render(createElement){
constinputAttributes={
class:'input-fieldhas-outline',//classdefinition
onClick:this.handleClick//eventhandler
backdrop:false//customprop
}
constinputMarkup=this.multiline
?
:
returninputMarkup
}
导入VueJS组件
在Vue中使用JSX的另一个好处是,我们不再需要注册所需的每个组件。我们只是导入和使用。
import{Button}from'../components'
exportdefault{
render(createElement){
returnEdit
}
}
如何使JSX与TypeScript一起使用
TypeScript用作一种向JavaScript添加类型检查的机制。要在JSX支持TypeScript中,需要修改tsconfig.json。
要在TypeScript中启用JSX,请先将该文件另存为.tsx文件,然后将tsconfig.json修改为包括:
{
"compilerOptions":{
....
"jsx":"preserve",
}
}
将jsx选项设置为“preserve”意味着TypeScript不应处理JSX。这样做使Babel可以控制所有JSX和TypeScript坚持使用类型,因为它尚不支持VueJSX。
然后在项目中创建一个jsx.d.ts文件,并为Vue添加TypeScriptJSX声明。
importVue,{VNode}from'vue'
declareglobal{
namespaceJSX{
interfaceElementextendsVNode{}
interfaceElementClassextendsVue{}
interfaceElementAttributesProperty{
$props:{}
}
interfaceIntrinsicElements{
[elemName:string]:any
}
}
}
确保TypeScript可以加载声明文件。或者,可以通过以下方式在tsconfig.json中为其添加自动加载功能:
{
"compilerOptions":{
...
"typesRoot":["./node_modules/@types","./types"]
}
}
代码部署后可能存在的BUG没法实时知道,事后为了解决这些BUG,花了大量的时间进行log调试,这边顺便给大家推荐一个好用的BUG监控工具Fundebug。
总结
以上所述是小编给大家介绍的在Vue中使用JSX及使用它的原因浅析,希望对大家有所帮助!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。