vue2源码学习(3)响应式原理-1.初体验

103 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 7 天,点击查看活动详情

3.响应式原理-1.初体验

start

在正式阅读源码之前,需要大脑有一个简单的脑图。

目标

我按照我现有的理解,将学习 Vue 源码拆分为这么几块:

  1. 响应式原理
  2. 虚拟 DOM
  3. 编译渲染
  4. 其他

image.png

后续以脑图的思路为主线,依次阅读。 ok,第一步,学习响应式原理。

1. 定义数据

写个简单的 HTML 案例

index.html

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>lazy_tomato</title>
  </head>

  <body>
    <div id="app">
      <input type="text" v-model="a" />
    </div>

    <!-- 1. 我引入的是 ES Module 的Vue,所以需要在script标签中添加属性 type="module" -->
    <!-- 2. 运行本demo,需要借助 Vscode插件 live server启动本地服务(当然有其他方法也是ok的) -->
    <script type="module">
      import Vue from './dist/vue.esm.browser.js'
      new Vue({
        el: '#app',
        data() {
          return {
            a: 1,
            b: {
              c: 2,
            },
            d: [1, 2],
          }
        },
        created() {
          // 3. 在created的时候,打印一下this, 也就是我们的Vue实例
          console.log(this)
        },
      })
    </script>
  </body>
</html>

注意事项: 如果图方便,引入./dist/vue.js效果一样。

  1. 我引入的是 ES Module 的 Vue,所以需要在 script 标签中添加属性 type="module"。
  2. 运行本 demo,需要借助 Vscode 插件 live server 启动本地服务(当然有其他方法也是 ok 的)
  3. 我这个案例主要做的操作:在 created 的时候,打印一下 this, 也就是我们的 Vue 实例

运行效果

image.png

注意事项:

  1. 首先我们打印的 this 指向我们的 Vue 实例;

  2. 实例有很多属性;

    实例的属性需要注意:

    • _ 下划线开头的属性,表示是我们 Vue 内部的属性。
    • $ 开头的属性,表示是我们 Vue 暴露给用户使用的属性。
  3. 由于我们的重点是响应式原理,所以我们重点关注一下 data 中的数据。

数据

image.png

  1. 我们使用 data 中数据如何使用的。直接通过 this 获取即可,例如this.a; this.b;。可以看到我截图的第一个红框,对应着 data 中定义的属性。

  2. 但是打印的属性和定义的有些不一样,对象类型的数据会多一个 __ob__ 属性,例如 b,d中都多了一个 __ob__属性。为什么会有这个属性,有什么用?这里暂时先记录一下,后续读完源码,我们再回头看这里。

  3. this 上有一个 _data属性(截图的第二个红框),里面存储的数据和我们 data 中记录的数据一模一样?为什么?

console.log('看看_data做什么的', this._data.b === this.b)
// 看看_data做什么的 true

2. 响应式

简单说说什么叫做响应式:

  • 数据改变视图改变;

  • 视图改变数据改变;

<!DOCTYPE html>
<html lang="zh">
  <head>
    <meta charset="UTF-8" />
    <title>lazy_tomato</title>
  </head>

  <body>
    <div id="app"></div>

    <script type="module">
      import Vue from './dist/vue.esm.browser.js'
      new Vue({
        el: '#app',
        template: `
      <div>
        <input type="text" v-model="a">
        <div>a的值: {{a}}</div>
        <button @click="say">点击我改变 a的值</button>
      </div>
      `,
        data() {
          return {
            a: 1,
          }
        },
        methods: {
          say() {
            this.a = '我爱番茄'
          },
        },
      })
    </script>
  </body>
</html>

运行示例

20220917-191443.gif

end

  • 确定我们阅读源码的大致方向;
  • 初步体验了响应式的效果。