vue2和vue3响应式原理(一)

vue2

原理:在vue2中利用的是原生js下边的object.defineProperty()进行数据劫持,在通过里面的getter和setter方法,进行查看数据的修改,通过发布、订阅者模式进行数据与试图的响应式。

1.定义初始化数据

                

2.加工数据

        为了实现响应式,在javascript中,Object.defineProperty()给每个初始数据都形成了get和set的写法,只要读取数据就会执行get方法,编辑数据执行set方法

(1)定义响应式数据

                

(2)get查看age属性 执行get

                 

(3)set 修改数据的时候调用

                

              

(4) 当数据发生变化时 触发响应的监听回调(get/set),就已经实现了数据的双向绑定。

3.vue2双向绑定的缺点

(1)不能监听对象的新增属性和删除属性

(2)无法正确的监听数组的方法,当监听的下标对应的数据发生改变时

4.解决方案

(1)、重写数组或者对象

(2)、vue中 通过this.$set(目前属性,新增的属性,新增的值)来解决  注 括号是三个参数

 

vue3

基本原理:

1、对于基本数据类型来说,响应式依然是靠Object.defineProperty()的get和set来完成的

2、对于对象类型的数据:

  • 通过Proxy代理:拦截对象中任意属性的变化,包括属性值得读写、添加、删除等操作等..
  • 通过Reflect反射函数进行操作

 vue3中响应式是通过函数来实现的

1.ref函数
  • 作用:定义一个响应式数据
  • 语法:let   xxx = ref(xxx)
  • 创建一个包含响应式数据的引用对象
  • js中操作数据:xxx.value
  • 模板中读取数据:不需要 .value 直接使用插值语法即可
  • 注:接收的数据可以是基本类型也可以是对象类型  
2.reactive函数

1、作用:定义一个对象类型的响应式数据(基本数据类型 最好用ref函数)

2、语法:const xxx = reactive(源对象)接收一个数组或者对象,返回一个Proxy的实例对象,简称Proxy对象

返回proxy对象 

整个new Vue阶段做了什么?

1,执行init操作。包括且不限制initLifecycleinitState

2,执行mount 进行元素挂载

3,compiler步骤在runtime-only版本中没有。

  • compiler步骤对template属性进行编译,生成render函数。
  • 一般在项目中是在.vue文件开发,通过vue-loader处理生成render函数。

4,执行render  生成vnode

render例子,如下

 <div id="app">{{ message }}</div>

对应手写的render函数

render (h) {
  return h('div', {
     attrs: {
        id: 'app'
      },
  }, this.message)
}

 5.patch 新旧vnode经过diff后,渲染到真实dom上

     


 普通dom元素如何渲染到页面?

以下代码案例讲解更加清晰哦 就是一个初始化的Vue项目

// mian.js
import Vue from 'vue'
import App from './App.vue'

new Vue({
  render: h => h(App),
}).$mount('#app')
// App.vue
<template>
    <div id="app">
      <p>{{ msg }}</p>
    </div>
</template>
<script>
    export default {
        name: 'App',
        data () {
            return {
                msg: 'hello world'
            }
        }
    }

 主要讲解组件普通元素的不同之处 主要有2点:

1,如何生成VNode——创建组件VNode createComponent

  • 区分普通元素VNode
    • 普通VNode:tag是html的保留标签,如tag: 'div'
    • 组件VNode:tag是以vue-component开头,如tag: 'vue-component-1-App'

         

2,如何patch——组件new Vue到patch流程createComponent

  1. $vnode:占位符vnode。最终渲染vnode挂载的地方。所有的组件通过递归调用createComponent直至不再存在组件VNode,最终都会转化成普通的dom。
{
    tag: 'vue-component-1-App',
    componentInstance: {组件实例},
    componentOptions: {Ctor, ..., }
}

 3,_vnode:渲染vnode。

{
    tag: 'div',
    {
        "attrs": {
            "id": "app"
        }
    },
    // 对应占位符vnode: $vnode
    parent: {
        tag: 'vue-component-1-App',
        componentInstance: {组件实例},
        componentOptions: {Ctor, ..., }
    },
    children: [
        // 对应p标签
        { 
            tag: 'p',
            // 对应p标签内的文本节点{{ msg }}
            children: [{ text: 'hello world' }]
        }, {
          // 如果还有组件VNode其实也是一样的
          tag: 'vue-component-2-xxx'
        }              
    ]
}

 

 4,Vue组件化简化流程

        前面应该看的晕头转向了吧 下面我会用一个简化版的流程图进行回顾 加深理解

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值