什么是双向绑定?
废话不多说,我们先来看一个 v-model
基本的示例:
<input type="text" v-model="search">
首先,我们要明白一点的是:v-model
的本质是指令。因此,它跟我们一般的自定义指令是一样的,需要实现 Vue.js
生命周期的钩子函数。
其次,v-model
实现了双向绑定,也就是:数据到 DOM 的单向流动、DOM 到数据的单向流动。
明白了上面这两点,再来看代码就清晰多了。
// packages/runtime-dom/src/directives/vModel.ts
export const vModelText: ModelDirective<
HTMLInputElement | HTMLTextAreaElement
> = {
created() {
},
mounted() {
},
beforeUpdate() {
}
}
打开 v-model
的源码我们可以看到,它实现了对应的 Vue.js
生命周期钩子函数,实际上它就是一个内置的自定义指令。
那么,v-model
如何实现双向绑定的呢?具体来说,数据到 DOM 的单向流动以及DOM 到数据的单向流动是如何实现的。
数据到 DOM 的单向流动
// packages/runtime-dom/src/directives/vModel.ts
export const vModelText: ModelDirective<
HTMLInputElement | HTMLTextAreaElement
> = {
// set value on mounted so it's after min/max for type="range"
mounted(el, {
value }) {
el.value = value == null ? '' : value
}
}
数据到 DOM 的单向流动实现非常简单,一行代码就搞定了,就是把 v-model
绑定的值赋值给 el.value
。
DOM 到数据的单向流动
// packages/runtime-dom/src/directives/vModel.ts
export const vModelText: ModelDirective<
HTMLInputElement | HTMLTextAreaElement
> = {
created(el, {
modifiers: {
lazy, trim