VueJs中使用JSX
新项目前端使用的是vue框架,写了1个多月的vue,大部分使用Jsx,记录一下在vue中jsx遇到的问题,我最讨厌框架之争,语言之争.
关于html中写Js
还是Js中写html
孰优孰劣不作评价,都是个人喜好.
就像Vue
和React
哪个好,个人感觉vue易入门,适合刚入门的程序员或非前端人员快速出东西,轻量化应用.React更适合有专门的前端团队,组件化工程化.
为了减少Vue和React之间差异化,减少使用vue中的语法糖,我选择使用Jsx来封装通用组件,template来调用.1个月来封装了:数据表格组件,常用表单组件,弹框组件,权限控制组件,页面组件,抽屉组件,日历排期组件等.由于vue和react设计不同,jsx并不完全一样,有很多差异的地方.下面介绍,几个注意的地方.
webpack插件
开始使用,使用babel转换插件,babel-plugin-transform-vue-jsx
,
安装参考:https://github.com/vuejs/babel-plugin-transform-vue-jsx
vue文档:https://cn.vuejs.org/v2/guide/render-function.html
render
render,也叫渲染函数,无论React还是Vue在组件最关键的是render,它也是前端的灵魂.
在React离不开它,Vue中设计者有意隐藏了,降低了入门成本,也就是大家常用的<template>
标签.
网上有专门讲解这部分的文章,详情搜索引擎搜索”vue template 原理”.
渲染编译过程
vue的渲染编译大概过程:
graph TB; A(解析模板)-->B(编译成AST语法树); B-->C(生成render函数); C.->J(解析JSX); J.->F(渲染表达式); C-->F; F-->D(生成虚拟DOM); D-->E(生成html);
react:
graph TB; J(解析JSX)-->F(渲染表达式); F-->D(生成虚拟DOM); D-->E(生成html);
vue和react渲染过程都一样,都是通过babel
转化成真正的渲染表达式,最后转成虚拟Dom,生成html.
渲染表达函数
渲染表达式,简单理解就是,虚拟dom生成函数.
vue中叫vnode
,react中叫virtual-dom
,具体参考官方文档.
想知道virtual-dom的原理,可以参考网上文章,手写virtual-dom.
看一下渲染表达式函数长得什么亚子.
举例渲染:<h1>大表哥</h1>
vue:
参考:https://cn.vuejs.org/v2/guide/render-function.html#%E8%99%9A%E6%8B%9F-DOM1
2
3render: function (createElement) {
return createElement('h1',{},'大表哥')
}
react:1
2
3render(){
return React.createElement('h1',{},'大表哥')
}
对比一下是不是一蚂一样.
通过babel把jsx转成这样的函数就行了.就是第一节中的babel插件做的事情.
这种写法是完整的功能,但明显不直观.所以.vue使用template,react使用jsx.
通一使用jsx
写法,更直观.
template:1
2
3<template>
<h1>大表哥</h1>
</template>
jsx:1
2
3render(){
return (<h1>大表哥</h1>)
}
对比一下.template只能使用vue提供的语法糖.如 v-for,v-if,v-show等
.缺少原生JS的所有能力.需要配合method使用.
而Jsx不提供语法糖.
如加事件.
vue template写法:1
2
3
4
5
6
7
8
9
10<template>
<h1 v-on:click="onClick">大表哥</h1>
</template>
<script>
methods:{
onClick(){
console.log('click')
}
}
</script>
jsx 写法:1
2
3
4
5render(){
<h1 onClick={()=>{console.log('click')}} >
大表哥
</h1>
}
哪种写法好呢?我个人认为,综合使用.
显示为主的用template,操作控制为主的使用jsx.
一般在通用组件使用jsx写法,调用组件使用template写法.
举个例子,5分钟手写个弹框组件.
弹框组件.dialog.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47<script>
export default {
name: "MyDialog",
props: {
title: {
type: String,
default: ""
}
},
data(){
return {
visible:false,
};
},
methods:{
show(){
this.visible=true
}
},
render(h){
const sub = this.$slots.default;
const display=this.visible?'block':'none';
return (
<div class="dialog" style={{display:display}}>
<h3>{this.title}</h3>
<div class="body">
{sub}
</div>
<div class="footer">
<button onClick={()=>{
this.visible=false;
this.$emit('close','我要自闭了.')
}}>关闭</button>
</div>
</div>)
}
</script>
<style>
.dialog{
position:fixed;
width:320px;
height:400px;
top:10%;
left:50%;
margin-left:-160px;
}
</style>
调用时1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22<script>
import MyDialog from "./MyDialog.vue"
export default {
components:{
MyDialog
}
methods:{
onOpen(){
this.$refs.dialog.show();
},
onClose(msg){
console.log(msg)
}
}
}
</script>
<template>
<div class="app">
<button @click="onOpen">打开弹窗</button>
<MyDialog ref="dialog" @close="onClose" />
</div>
</template>
todo: 补充event,props,v-model等使用.
本文作者:阿金
本文链接:http://www.hi-arkin.com/2019/08/01/Javascript/vue-jsx/
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
扫描二维码,分享此文章