• 浅析v-model语法糖的实现原理与细节知识及如何让你开发的组件支持v-model


    • 弄明白: v-model 是什么的语法糖? vue2 对原生组件究竟做了什么特殊处理?
    • 弄明白: v-model 到底是单向数据流还是数据双向绑定
    • 弄明白: v-model 在语法糖之外的『副作用』?
    • 学会如何让你的组件也支持 v-model 语法。

    一、v-model 的本质是语法糖

    v-model 本质上不过是语法糖。它负责监听用户的输入事件以更新数据,并对一些极端场景进行一些特殊处理。』 -- 官方文档

    什么是语法糖?

    语法糖,简单来说就是『便捷写法』。

    在大部分情况下, v-model="foo" 等价于 :value="foo" 加上 @input="foo = $event"

    1. <el-input v-model="foo" />
    2. <el-input :value="foo" @input="foo = $event" />

    没错,在大部分情况下如此。
    但也有例外:

    1. vue2 给组件提供了 model 属性,可以让用户自定义传值的prop名更新值的事件名。这个暂且略过,第四节会细说。

    2. 对于原生 html 原生元素,vue 干了大量『脏活儿』,目的是为了能让我们忽视 html 在api上的差异性。以下元素的左右两种写法是等价的:

    • textarea 元素:

    • select 下拉框:

    • input type='radio' 单选框:

    • input type='checkbox' 多选框:

    在编程思想上,这种帮助使用者『隐藏细节』的方式叫封装

    二、v-model 仅仅是语法糖吗?(冷知识)

    v-model 不仅仅是语法糖,它还有副作用。

    副作用如下:如果 v-model 绑定的是响应式对象上某个不存在的属性,那么 vue 会悄悄地增加这个属性,并让它响应式。

    举个例子,看下面的代码:

    1. // template中:
    2. "user.tel">
    3. // script中:
    4. export default {
    5. data() {
    6. return {
    7. user: {
    8. name: '公众号: 前端要摸鱼',
    9. }
    10. }
    11. }
    12. }

    响应式数据中没有定义 user.tel 属性,但是 template 里却用 v-model 绑定了 user.tel,猜一猜当你输入时会发生什么?

    看效果:

    揭晓答案吧: user 上会新增 tel 属性,并且 tel 这个属性还是响应式的。

    这就是『副作用』带来的效果,你学会了吗?

    三、 v-model 是双向绑定还是单向数据流?

    2.1 v-model 是双向绑定吗?

    是,官方说是。

    『你可以用 v-model 指令在表单