学习JSX
,先了解一下createElement
提到JSX
,不可避免的就要提到createElement
,当你看完本节,你会发现,奇怪的知识又增多了。ok,我们接着上一部分继续讲。这一次的准备工作是了解createElement。
从Vue
编译后的代码看createElement
你是否看过写的Vue
代码经过编译之后的样子,比如下面这段代码
<template>
<div>我喜欢<span class="emphasize">前端</span></div>
</template>
小编对这段代码进行编译之后,得到下面这段代码
function () {
var e = this,
// e._self._c 对应源码里面的createElement
t = e._self._c;
// 返回了一个 createElement('div',[])
return t("div", [
// e._v 对应源码里面的createTextVNode
e._v("my"),
t("span", { staticClass: "emphasize" }, [e._v("前端")]),
]);
}
通过对上面的代码进行分析,不难发现,Vue
模板中的每一个元素编译之后都会对应一个createElement
,那么这个createElement
到底是什么,嗯,这个你面试的时候也许已经提到过了。
那么什么是createElement
无论是Vue
还是React
,都存在createElement
,而且作用基本一致。可能你对createElement
不是很了解,函数名翻译过来就是增加一个元素,但他的返回值你一定知道。createElement
函数返回的值称之为虚拟节点,即VNode
,而由VNode
扎堆组成的树便是大名鼎鼎,面试必问的虚拟DOM
。
createElement
函数的参数,在这里小编偷个懒抄一下Vue
官方文档
// @returns {VNode}
createElement(
// {String | Object | Function}
// 一个 HTML 标签名、组件选项对象,或者
// resolve 了上述任何一种的一个 async 函数。必填项。
'div',
// {Object}
// 一个与模板中 attribute 对应的数据对象。可选。
{
// (详情见下一节)
},
// {String | Array}
// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,
// 也可以使用字符串来生成“文本虚拟节点”。可选。
[
'先写一些文字',
createElement('h1', '一则头条'),
createElement(MyComponent, {
props: {
someProp: 'foobar'
}
})
]
)
从上面可以看出createElement
一共有三个参数,三个参数分别是
- 第一个参数是需要渲染的组件,可以是组件的标签,比如
div
;或者是一个组件对象,也就是你天天写的export default {}
;亦或者可以是一个异步函数。 - 第二个参数是这个组件的属性,是一个对象,如果组件没有参数,可以传null(关于组件的属性,下文将依次介绍)
- 第三个参数是这个组件的子组件,可以是一个字符串(textContent)或者一个由VNodes组成的数组
用createElement
写一个组件吧
表单示例
假设我们需要开发一个下面这样的表格(element-ui的)
用模板代码去开发
如果我们用模板代码去开发这个表单,那么代码大概就长这样
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="审批人">
<el-input v-model="formInline.user" placeholder="审批人"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="formInline.region" placeholder="活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
用createElement
去实现
如果我们直接将上面的代码转换为用createElement
去实现,那么代码将会是这样的
export default {
methods: {
$_handleChangeUser(value) {
this.formInline.user = value
}
},
render(createElement) {
return createElement(
'ElForm',
{
props: {
inline: true,
model: this.formInline
},
staticClass: 'demo-form-inline'
},
[
createElement(
'ElFormItem',
{
props: {
label: '审批人'
}
},
[
createElement('ElInput', {
props: {
value: this.formInline.user
},
attrs: {
placeholder: '审批人'
},
on: {
input: this.$_handleChangeUser
}
})
]
),
createElement(
'ElFormItem',
{
props: {
label: '活动区域'
}
},
[
createElement(
'ElSelect',
{
props: {
value: this.formInline.region,
placeholder: '活动区域'
}
},
[
createElement('ElOption', {
props: {
label: '区域一',
value: 'shanghai'
}
}),
createElement('ElOption', {
props: {
label: '区域二',
value: 'beijing'
}
})
]
)
]
),
createElement('ElFormItem', null, [
createElement(
'ElButton',
{
props: {
type: 'primary'
},
on: {
click: this.$_handleSubmit
}
},
'查询'
)
])
]
)
}
}
看到上面的代码,你可能会惊呼,代码好多啊,好痛苦,想当年发明JSX
的人刚开始天天也是写createElement
,写的直掉头发,太痛苦了,然后就使劲挠头,当额头锃光发亮的时候,终于想到了一种新的语法,就是JSX。从此之后,头发呼呼的又长回来了。
看到上面代码,你会发现有一个render
函数,这个函数叫做渲染函数,相当于通过createElement
或JSX
去实现功能的主入口方法。而且你熟悉的v-model
也没见了,而是用value
+ input
代替了。
ok,这一部分先写到这里,下一篇文章写下一部分:是时候使用JSX
代替createElement
了。喜欢的朋友可以继续看哦,我更新非常快哦。也会一直出优秀的文章给大家分享。