只用四个函数, 不需要熟悉 JavaScript 各种奇怪的知识, 不需要复杂的配置, 就可以立刻写出比较复杂的前端页面. 一开始我也不相信, 但 Vue3 真的做到了. 而且很神奇的一点是, 在 Vue3 的架构里我发现了很多类似 elixir/erlang 的地方.
createApp
对于母语是 elixir/erlang 的程序员来说, App(lication)
是很熟悉的概念: 广义上值整个虚拟机中的一个基本独立的应用, 狭义上指实现了 Application behaviour
的模块. Vue 中的 App 比 elixir/erlang 的更加独立一些, 但实现方式很类似, 只要实现一个对应的回调函数即可.
import { createApp, h } from 'vue'
const hello = (props, context) => h('div', null, 'hello vue3')
createApp(hello)
.mount('#app')
等价 html:
<div>hello vue3</div>
App 的回调函数需要的返回值是一个 vnode, 即 vue 中虚拟的 html dom元素; 另外这个函数会传入两个参数, 其中 property 即是该 vnode 所接收的属性, 例如 <div id="app"></div>
里面的 id
就是一个属性. context 则提供了一系列该 vnode 可用的 vue 内置方法.
和 elixir/erlang 非常类似的还有: Vue App 可以 mount
和 unmount
, erlang application 可以 start
和 stop
.
h
在上面的例子里, 我们使用了 h
函数来创造 vnode, 一般这个函数被称为 "渲染函数". 它能接收三个参数, 分别是: component, attributes 和 slots. 它非常类似 elixir/erlang 里的 GenServer.start(modelue, init_arg, options \\ [])
.
在上面的例子中, 我们实际上使用了简略写法去设置 vnode 的内容(slots), 完整的写法是:
h('div', null, {
default: (props) => 'hello vue3'
})
使用完整写法可以帮我们在某些组件的指定位置使用自定义的 slot 模板.
resolveComponent
这里我们使用了基本的组件 div
. 对与在第三方库里的其他组件, 就需要先使用 resolveComponent
来寻找对应的组件的具体函数入口. 例如我们使用 ant-design-vue
的 a-button
组件:
import antd from 'ant-design-vue'
import { createApp, h, resolveComponent } from 'vue'
const hello = (props, context) => h(resolveComponent('a-button'), null, 'hello vue3')
createApp(hello)
.mount('#app')
等价 html:
<a-button>hello vue3</a-button>
reactive
利用上面三个函数, 我们已经可以使用任意的组件创造静态页面, 而 reactive
函数才是 Vue3 真正的魔法所在, 使用它可以很方便地让页面动起来. 再次类比到 elixir/erlang, 我们知道进程之间一般不共享数据, 除非使用 ETS 这样的内存数据库. 而 reactive 函数不仅可以帮我们在vnode 之间共享数据, 还以在数据被更新时立刻同步到每个 vnode.
const model = reactive({text: ''})
const input = () => h('input', {onInput: (e) => model.text = e.target.value}) // 绑定 onInput 事件, 在有输入时更新 model.text
const show = () => h('p', null, model.text) // 使用 model.text 的值
const app = (_p, _c) => h('div', null, [
input(),
show()
])
createApp(app)
.mount('#app')
等价 html:
<input />
<p>这里的内容会随 input 自动更新</p>
注意, 这里的 input
和 show
都需要是函数, 因为其在 model 被更新时都会被重复调用. 如果写成了表达式, 则不会动态更新.
结语
使用以上四个基本函数, 就可以自由地调用和组合第三方组件库, 写出可用的动态前端页面了.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。