Vue3源码:双向绑定

73 阅读1分钟

一、响应式(数据驱动视图改变)

以下代码为例:

<script setup>
import {ref} from "vue";
function changeNumber() {
  number.value++
}
let number = ref(100);
</script>

<template>
  <div @click="changeNumber">
    {{ number }}
  </div>
</template>

1、定义阶段

创建RefImpl实例: image.png\

2、绑定阶段

字符串number通过ref生成的class实例在instance.setupStated代理对象中,
执行_sfc_render函数获取vnode期间,执行_toDisplayString的时候会访问到;这里触发get并在class实例中创建dep: image.png

image.png

image.png

与effect做关联

3、触发阶段

number.value++ 会触发refImpl里的value函数,所以ref绑定字符串的响应式不是通过proxy实现的 (1)找到refImpl实例中的dep遍历拿到effect(ReactiveEffect实例)收集scheduler函数存放在queueEffectSchedulers中; image.png (2)收集完了后把update(更新视图)放在promise.then()中执行 image.png

(3)下面以函数树的形式展示一下视图更新大致流程

`flushJobs`
    `callWithErrorHandling`
        `instance.update`
            `effect.run`
                `componentUpdateFn`
                    `renderComponentRoot`
                        `_sfc_render`:生成新vnode
                    `patch`:下面开始比对新老节点
                        `processElement`
                            `patchElement`
                                `hostSetElementText`:text不一样直接改了

二、输入文字修改vue绑定的值

1、事件触发

(1)、输入法英文模式直接触发input事件,如果用v-model.lazy修饰符会触发change事件
(2)、输入法中文模式先触发onCompositionStart事件,输入完会触发onCompositionEnd事件,再用js触发一遍input事件

image.png

2、改变响应式值

image.png