• 从零到一手写迷你版Vue


    Vue响应式设计思路

    Vue响应式主要包含:

    • 数据响应式
    • 监听数据变化,并在视图中更新
    • Vue2使用Object.defineProperty实现数据劫持
    • Vu3使用Proxy实现数据劫持
    • 模板引擎
    • 提供描述视图的模板语法
    • 插值表达式{ {}}
    • 指令 v-bind, v-on, v-model, v-for,v-if
    • 渲染
    • 将模板转换为html
    • 解析模板,生成vdom,把vdom渲染为普通dom

    数据响应式原理

    在这里插入图片描述

    数据变化时能自动更新视图,就是数据响应式
    Vue2使用Object.defineProperty实现数据变化的检测

    原理解析
    • new Vue()⾸先执⾏初始化,对data执⾏响应化处理,这个过程发⽣在Observer
    • 同时对模板执⾏编译,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发⽣在 Compile
    • 同时定义⼀个更新函数和Watcher实例,将来对应数据变化时,Watcher会调⽤更新函数
    • 由于data的某个key在⼀个视图中可能出现多次,所以每个key都需要⼀个管家Dep来管理多个 Watcher
    • 将来data中数据⼀旦发⽣变化,会⾸先找到对应的Dep,通知所有Watcher执⾏更新函数

    在这里插入图片描述

    一些关键类说明

    CVue:自定义Vue类 Observer:执⾏数据响应化(分辨数据是对象还是数组) Compile:编译模板,初始化视图,收集依赖(更新函数、 watcher创建) Watcher:执⾏更新函数(更新dom) Dep:管理多个Watcher实例,批量更新

    参考 前端手写面试题详细解答

    涉及关键方法说明

    observe: 遍历vm.data的所有属性,对其所有属性做响应式,会做简易判断,创建Observer实例进行真正响应式处理

    html页面
    DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>cvuetitle>
      <script src="./cvue.js">script>
    head>
    <body>
      <div id="app">
        <p>{
      { count }}p>
      div>
    
      <script>
        const app = new CVue({
               el: '#app',      data: {
                 count: 0
          }    })    setInterval(() => {
               app.count +=1
        }, 1000);  script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    CVue

    • 创建基本CVue构造函数:
    • 执⾏初始化,对data执⾏响应化处理
    // 自定义Vue类
    class CVue {
       
      constructor(options) {
       
        this.$options = options
        this.$data = options.data
    
        // 响应化处理
        observe(this.$data)
      }
    }
    
    // 数据响应式, 修改对象的getter,setter
    function defineReactive(obj, key, val) {
       
      // 递归处理,处理val是嵌套对象情况
      observe(val)
      Object.defineProperty(obj, key, {
       
        get() {
       
          return val
        },
        set(newVal) {
       
          if(val !== newVal) {
       
            console.log(`set ${
         key}:${
         newVal}, old is ${
         val}`)
    
            val = newVal
            // 继续进行响应式处理,处理newVal是对象情况
            observe(val)
          }
        }
      })
    }
    
    // 遍历obj,对其所有属性做响应式
    function observe(obj) {
       
      // 只处理对象类型的
      if(typeof obj !== 'object' || obj == null) {
       
        return
      }
      // 实例化Observe实例
      new Observe(obj)
    }
    
    // 根据传入value的类型做相应的响应式处理
    class Observe {
       
      constructor(obj) {
       
        if(Array.isArray(obj
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
  • 相关阅读:
    go语言Array 与 Slice
    猿创征文丨赶紧进来!!!带你0距离全面接触 变量和常量
    [SpringMVC笔记] SpringMVC-15-SSM整合-项目异常处理
    【C语言趣味教程】(1) 深入浅出 HelloWorld:通过 HelloWorld 展开教学 | 头文件详解 | main 函数详解
    新的职业已经出现,怎么能够停滞不前 ,人社部公布建筑新职业
    MySQL应用——常见故障分析和检查
    安科瑞故障电弧探测器在建筑电气的设计与应用
    Au 效果器详解:母带处理
    物联网AI MicroPython传感器学习 之 ADXL345 3轴加速度传感器
    成集云 | 金蝶K3集成聚水潭ERP(金蝶K3主管库存)| 解决方案
  • 原文地址:https://blog.csdn.net/helloworld1024fd/article/details/127682481