壹影博客.
我在下午4点钟开始想你
原生Js手写模拟VUE数据响应式代码分析
  • 2023-12-16日
  • 0评论
  • 1531围观

原生Js手写模拟VUE数据响应式代码分析

vue作为目前前端开发的主流框架,有许多设计思想非常精妙,就比如数据响应式

数据响应式的本质:当数据变化时会自动运行一些相关函数

本篇文章将带你了解Vue底层是如何实现数据响应式的?数据发生改变页面也发生变化是如何做到的

废话不多说直接分享DEMO,有详细的注释


//数据响应式的本质:当数据变化时会自动运行一些相关函数
//记录一个全局的变量用于存储当前使用的函数
window.__func=null


/**
 * 观察某个对象的所有属性
 * @param {Object} obj
 */
function observe(obj){

  /**
   * records 依赖收集:记录是哪个函数在用我
   * @param arr 传入最终要存储的数组
   */
  function records(arr){
    //判断全局变量是否有值 并且 arr数组是否存在该函数 如果不存在就写入
    if(window.__func && !arr.includes(window.__func)){
      arr.push(window.__func)
    }
  }

  /**
   * applyFun 派发更新:执行用我的函数
   * @param arr 传入最终要执行的数组
   */
  function applyFun(arr){
    for (let i=0;i<arr.length;i++){
      arr[i]();
    }
  }

  for(const key in obj){
    let internalValue=obj[key];
    let funcs=[]; //记录使用的函数
    Object.defineProperty(obj,key,{
      get:function (){
        //依赖收集-记录:是哪个函数在用我
        records(funcs)
        return internalValue;//取值 将值返回
      },

      set:function (val){
        internalValue = val;//设置值的时候将值 存入internalValue变量 方便后期去取值

        //派发更新-运行:执行用我的函数
        applyFun(funcs)
      }
    })
  }
}

//自动记录使用对象的函数
function autoRun(fn){
  window.__func=fn; //记录函数
  fn();//使用函数 由于添加了get 会先执行get中的内容
  window.__func=null; //最后再将全局变量设置为null
}

//使用测试
var user={
  name:'壹影',
  role:'全栈开发工程师'
}

observe(user) //观察user对象

//使用的函数
function writeInner(){
  document.body.innerHTML="" //清空页面
  // 参数需要包含我们监听的对象参数
  document.write(user.name)
}

// 设置自动化改变
autoRun(writeInner)

当然代码还存在许多不完美的地方,但是这种设计思路确实比较实用,所有记录下来学习的内容,方便日后查阅

@Auth 壹影

发表评论