美文网首页
浅谈vue设计核心 01-数据响应式

浅谈vue设计核心 01-数据响应式

作者: 江川哇 | 来源:发表于2021-09-28 10:34 被阅读0次

vue的设计核心是 mvvm
mvvm的核心三要素:数据响应式、 模板引擎、 渲染
1、数据响应式:监听数据变化并且在视图中更新,vue中利用Object.defineProperty()实现变更检测
Object.defineProperty()
Proxy

简单实现:

const obj = {}
function definePropery(obj,key,val) {
  Object.definePropery(obj,key,{
    get() {
      console.log('get',val)
    }
    set(newval) {
      if(newval!=val) {
        val = newval
      }
    }
  })
}
definePropery(obj,'foo','foo')
obj.foo
obj.foo='fooooooo'

结合视图

<!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">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body>
    <div id="app"></div>
   <script>
      function defineReactive(obj,key,{
        get(val) {
          return val
        }
        set(newval)  {
          if(val!=newval) {
            val = newval
            update()
          }
        }
      })
      defineReactive(obj,'foo','')
      obj.foo = new Date().toLocaleTimeString()
      function update() {
        app.innetText = obj.foo
      }
      setInterval (()=>{
         obj.foo = new Date().toLocaleTimeString()
      },1000)
  </script>
  </body>
</html>

遍历要响应的对象

//对象响应化,遍历每个key,定义getter setter
function observe(obj) {
  if(typeof obj !='object' || obj==null) {
    return
  }
  Object.keys(obj).forEach(key=>{
    defineReactive(obj,key,obj[key])
  })
}
const obj = {foo:'foo',bar:'bar',baz:{a:1}}
obj.foo
obj.foo = 'fff'
obj.bar
obj.bar = 'barrrrrr'
obj.baz.a = 2 //嵌套对象no ok

解决嵌套对象 用递归

function defineReactive(obj,key,val) {
  observe(val)
  Object.defineProperty(obj,key,{
    //...
  })
}

解决赋值是对象的情况

obj.baz = {a:1}
obj.baz.a = 10 //no ok
set(newval) {
  if(newval!=val) {
    observe(newval) //新值是对象的情况
    notifyUpdate()
  }
}

解决添加/删除新属性无法检测 类似vue的$set

obj.dong = 'dong'
obj.dong //并没有get信息
function set(obj,key,val) {
  difineReactive(obj,key,val)
}
//测试
set(obj,'dong','dong')
obj.dong

完整代码

//对象响应式原理
//1 Object.defineProperty()
function defineReactive(obj, key, val) {
  //val 可能是对象,需要递归处理
  observe(val)
  Object.defineProperty(obj, key, {
    get() {
      console.log('get', val)
      return val
    },
    set(newval) {
      if (newval != val) {
        observe(newval)
        console.log('set', newval)
        val = newval
      }
    },
  })
}

//对象响应式处理
function observe(obj) {
  //判断obj类型必须是对象
  if (typeof obj != 'object' || obj == null) {
    return
  }
  Object.keys(obj).forEach((key) => defineReactive(obj, key, obj[key]))
}
//设置新的属性 类似$set
function set(obj, key, val) {
  defineReactive(obj, key, val)
}
const obj = { name: 'aa', age: 11, baz: { a: 1 } }
observe(obj)
// obj.name
// obj.name = 'fffff'
//1 对象嵌套 就用到了递归,在defineReactive 里面再调用一次 observe(val)
// obj.baz.a

//2 这种情况 在set里面再调用一次observe(val)
//obj.baz={a:10}

//3 设置新的obj属性 类似$set
set(obj, 'dong', 'dong')
obj.dong

2、模板引擎:提供描述视图的模板语法
插值:{{}}
指令: v-bind v-on v-for v-if v-model
3、渲染:如何将模板转换成html
模板=> vdom =>dom

相关文章

  • 浅谈vue设计核心 01-数据响应式

    vue的设计核心是 mvvmmvvm的核心三要素:数据响应式、 模板引擎、 渲染1、数据响应式:监听数据变化并且在...

  • 学习vue的响应式 mvvm -01 数据响应式

    理解VUE的设计思想:VUE的核心是MVVM MVVM框架的三要素:数据响应式 模板引擎以及渲染 数据响应式:监听...

  • 【浅谈Vue3 effect】

    Vue3 中引入了 proxy进行数据劫持,而effect是响应式系统的核心,而响应式系统又是 vue3 中的核心...

  • Vue 数据响应式原理

    前言 Vue.js 的核心包括一套“响应式系统”。 “响应式”,是指当数据改变后,Vue 会通知到使用该数据的代码...

  • 前端面试题【Day02】

    本篇绪论 1,Vue响应式原理 1,Vue响应式原理 在vue实例中声明的数据就是响应式的。响应式:数据发生改变,...

  • 手写 Vue Router、手写响应式实现、虚拟 DOM 和 D

    模拟 Vue.js 响应式原理 一、数据驱动 准备工作 数据驱动 响应式的核心原理 发布订阅模式和观察者模式 数据...

  • Vue响应式原理

    Vue2.x 核心响应式原理 Vue3.0 核心响应式原理 Vue 自定义事件 Vue 发布订阅模式 发布/订阅模...

  • vue双向绑定原理

    理解vue的设计思想 MVVM模式 MVVM框架的三要素:数据响应式、模版引擎及其渲染 数据响应式:监听数据变化并...

  • Vue.js入门(一):模板语法、计算属性/监听器

    1 Vue 设计思想 数据驱动应用 MVVM模式:Vue完成ViewModel功能:响应式:监听数据变化模板引擎:...

  • Vue原理

    vue原理相关 Vue核心概念 vue实例化 虚拟dom 模板编译 数据绑定(响应式) 组件化 MVVM mode...

网友评论

      本文标题:浅谈vue设计核心 01-数据响应式

      本文链接:https://www.haomeiwen.com/subject/qsmlnltx.html