前言:

前天我们学了 ref 和 reactive ,提到了响应式数据和 Proxy ,那我们今天就来了解一下,vue3 的响应式

在了解之前,先复习一下之前 vue2 的响应式原理

vue2 的响应式:

原理:

对象类型:通过 Object.defineProperty() 对象的读取,修改进行拦截,也就是数据劫持,响应式的根基

缺点:因为只有 读取和修改(get,set)所以新增属性,和删除属性,页面是不会刷新的

数组类型:通过重写,更新数组的一系列方法来实现拦截,假如你调了一个数组的 push 方法,其实 push 是被二次重写封装的(对数组的变更方法进行了重写)

缺点:直接通过下标修改数组,页面不会更新

解决方法:用 this.$set(数据,添加名字,添加内容),this.$delete(数据,删除的数据名)

vue3 的响应式:

通过 Proxy 代理 :拦截对象中任意属性的变化,包括增,删,改,查

通过 Reflect 反射 : 对被代理对象(源对象)的属性进行操作

new Proxy(data,{
//拦截读取的属性值
get(target,prop){
return Reflect.get(targert,prop)
}
//拦截设置和添加
set(target,prop,value){
return Reflect.set(targert,prop,value)
}
// 拦截删除
deleteProperty(target,prop){
return Reflect.deleteProperty(targert,prop)
}
})

这差不多就是 vue3 响应式的简单原理,Proxy 比较之前的 Object.defineProperty 功能更详细,和强壮

reactive 与 ref 的区别:

定义:

ref:用来定义基本数据类型

reactive:用来定义对象(数组)类型数据

ps:ref 也可以用来定义对象(或数组)类型数据,内部求助了 reactive 

原理:

ref: 通过 Object.defineProperty()的 get 与 set 来实现响应式也就是数据劫持

reactive:通过使用 Proxy 来实现响应式,并用 Reflect 操作源对象内部数据

使用:

ref:用 ref 定义的数据,操作需要 .value 

reactive : 定义的数据,操作不需要

setup 的注意:

setup 的执行时机是在 beforeCreate 之前执行,this 是 undefined

setup 的参数:

props :值为对象,包含:组件外部传递过来,并且组件内部声明接收了的属性

context :上下文对象,有三个值分别是 attrs,slots,emit

attrs :对象,没有在 props 声明配置的属性,相当于 vue2 的 this.$attrs

slots :插槽,相当于 this. $slots 

emit :分发自定义事件的函数,相当于 this.$emit

计算属性,computed函数

与 vue2 中的 computed 配置功能一致

watch 函数监听:

与 vue2 中的 watch 配置功能一致

watch 监视 ref 基本数据:

情况一 :监视 ref 定义的一个响应式数据

let sum = ref(0)
watch(sum,(newValue,oldValue)=>{
console.log('监听sum变了',newValue,oldValue)
})

情况二:监视 ref 定义的多个响应式数据

let msg = ref('你好啊')
let sum = ref(0)
watch([sum,msg],(newValue,oldValue)=>{
console.log('监听sum变了',newValue,oldValue)
},{immediate:true})

ps:watch 一共可以传递三个值,第一个 监视的数据,监视的行为,watch 的配置

watch 监视 reactive 对象:

情况三:监视 reactive  所定义数据中的全部属性

let preson = reactive({
name:'六扇老师',
age:18
})
watch(preson,(newValue,oldValue)=>{
console.log('监听preson变了',newValue,oldValue)
},{deep:false}) // 此处的 deep 配置无效

ps:此处无法正确的获得 oldValue,是 reactive 的问题无法解决

强制开启深度监视( deep 配置无效)

情况四:监视 reactive 所定义数据中的某一个属性

watch(()=>preson.name,(newValue,oldValue)=>{
console.log('监听preson.name变了',newValue,oldValue)
})

情况五:监视 reactive 所定义数据中的某些属性

watch([()=>preson.name,()=>preson.age],(newValue,oldValue)=>{
console.log('监听preson.name/preson.age变了',newValue,oldValue)
})

特殊情况:

let preson = reactive({
name:'六扇老师',
age:18,
job:{
j1:{ salary:30 }
}
})
watch(()=>preson.job,(newValue,oldValue)=>{
console.log('监听preson.job变了',newValue,oldValue)
},{deep:true})

ps:如果单独监视 reactive 对象里面的对象的数据,则必须开启 deep:true 深度监视,否则监视无效

watchEffect 函数:

watchEffect 函数是 vue3 新增的一个函数

watch 区别:

watch:既要指明监视属性,也要指明监视的回调

watchEffect :不用指明监视属性,监视的回调中使用了那个属性,就默认监视那几个属性

watchEffectcomputed 有点像似

不一样的是,computed 注重计算出来的值,回调函数的返回值,所以必须要写返回值

watchEffect 更注重过程,回调函数的函数体,所以不用写返回值

let sum = ref(0)
let preson = reactive({
name:'六扇老师',
age:18,
job:{
j1:{ salary:30 }
}
})
// watchEffect vue3 新增
// 默认开启 immediate,也有 deep
watchEffect(()=>{
const x1 = sum.value const
x2 = preson.job.j1.salary
console.log('所指定的 watchEffect 的回调执行了')
})

vue2 和 vue3 生命周期对比:

vue2 开始不管你有没有使用都会先执行俩个钩子,然后才会去判断,vue3 则不会得明确得告诉 app 你服务于那个容器,才开始走,更智能了

剩下得生命周期都相差不多,但在 vue3 里用 beforeUnmount (卸载之前)和 unmounted (卸载完毕)替换了 beforeDestroy (销毁之前) 和 destroyed (销毁完毕),和 react 像似了

组合式 api 里面的生命周期:

用组合式 api 往 setup 里面写的生命周期,这种写法不见得非要用,只是了解就行,问题不大

beforeCreate setup
created setup

beforeCreate 和 created 这俩钩子 vue3 并没有给我们提供组合式 api ,放不进去 setup,setup 就相当于他们俩个

beforeMount onbeforeMount
mounted onmounted
beforeUpdate onbeforeUpdate
updated onupdated
beforeUnmount onbeforeUnmount
unmounted onunmounted

就是在之前的生命周期,加上一个 on,而且 setup 的优先级更高

自定义 hook 函数:

hook 本质是一个函数,把 setup 函数中使用的 组合式 API 进行了自定义封装

类似于 vue2 中的 mixin

自定义 hook 复用代码,可以让 setup 中的逻辑更清楚,更容易懂,更简单

toRef:

创建一个 ref 对象,其 value 值指向另一个对象中的某个属性

回到我们之前的代码

可以看到页面上,想要获取数据,就要 preson 点什么什么一大堆,看着也不美观,这时候就要用到 toRef 了

toRef 语法 : const name = toRef (preson ,‘nama’) 第一个参数对象,第二个是对象里的那个值

toRefs:

toRef 的升级版,可以批量处理一个对象里的所有属性

以上就是我们常用的组合式 API 了,知道了这些差不多就完成了一个 vue3 的入门,明天我们开始学习一些不常用的组合式 API ,虽然不常用当还是要了解滴,所以我们明天再见

vue3响应式原理以及ref和reactive区别还有vue2/3生命周期的对比,第二天的更多相关文章

  1. 由浅入深,带你用JavaScript实现响应式原理(Vue2、Vue3响应式原理)

    由浅入深,带你用JavaScript实现响应式原理 前言 为什么前端框架Vue能够做到响应式?当依赖数据发生变化时,会对页面进行自动更新,其原理还是在于对响应式数据的获取和设置进行了监听,一旦监听到数 ...

  2. vue2响应式原理与vue3响应式原理对比

    VUE2.0 核心 对象:通过Object.defineProtytype()对对象的已有属性值的读取和修改进行劫持 数组:通过重写数组更新数组一系列更新元素的方法来实现元素的修改的劫持 Object ...

  3. vue3剖析:响应式原理——effect

    响应式原理 源码目录:https://github.com/vuejs/vue-next/tree/master/packages/reactivity 模块 ref: reactive: compu ...

  4. vue3响应式模式设计原理

    vue3响应式模式设计原理 为什么要关系vue3的设计原理?了解vue3构建原理,将有助于开发者更快速上手Vue3:同时可以提高Vue调试技能,可以快速定位错误 1.vue3对比vue2 vue2的原 ...

  5. vue2.0与3.0响应式原理机制

    vue2.0响应式原理 - defineProperty 这个原理老生常谈了,就是拦截对象,给对象的属性增加set 和 get方法,因为核心是defineProperty所以还需要对数组的方法进行拦截 ...

  6. 深入解析vue响应式原理

    摘要:本文主要通过结合vue官方文档及源码,对vue响应式原理进行深入分析. 1.定义 作为vue最独特的特性,响应式可以说是vue的灵魂了,表面上看就是数据发生变化后,对应的界面会重新渲染,那么响应 ...

  7. 认真总结Vue3中ref与reactive区别和isRef与isReactive 类型判断

    1.什么是ref? 1.ref和reactive-样 也是用来实现响应式数据的方法 由于reactive必须传递一个对象, 所以导致在企业开发中如果我们只想让某个变量实现响应式的时候会非常麻烦 所以V ...

  8. vue深入响应式原理

    vue深入响应式原理 深入响应式原理 — Vue.jshttps://cn.vuejs.org/v2/guide/reactivity.html 注意:这里说的响应式不是bootsharp那种前端UI ...

  9. 深度解析 Vue 响应式原理

    深度解析 Vue 响应式原理 该文章内容节选自团队的开源项目 InterviewMap.项目目前内容包含了 JS.网络.浏览器相关.性能优化.安全.框架.Git.数据结构.算法等内容,无论是基础还是进 ...

  10. [vuejs] 深入响应式原理

    深入响应式原理 现在是时候深入一下了!Vue 最独特的特性之一,是其非侵入性的响应式系统.数据模型仅仅是普通的 JavaScript 对象.而当你修改它们时,视图会进行更新.这使得状态管理非常简单直接 ...

随机推荐

  1. Openstack neutron:SDN现状

    目录 - SDN现状 - (一)SDN现状 - SDN诞生的背景 - SDN的介绍 - (二)SDN领域的相关组织和发展现状 - 1.ONF - 2.OpenDaylight - 3. IETF -  ...

  2. 详解字符编码与 Unicode

    人类交流使用 A.B.C.中 等字符,但计算机只认识 0 和 1.因此,就需要将人类的字符,转换成计算机认识的二进制编码.这个过程就是字符编码. ASCII 最简单.常用的字符编码就是 ASCII(A ...

  3. MQ的消息丢失/重复/积压的问题解决

    在我们实际的开发过程中,我们肯定会用到MQ中间件,常见的MQ中间件有kafka,RabbitMQ,RocketMQ.在使用的过程中,我们必须要考虑这样一个问题,在使用MQ的时候,我们怎么确保消息100 ...

  4. Typora如何配置gitee图床

    转载自:https://mp.weixin.qq.com/s/5dPLbr2vFgL18XKL1Y05Og 要求: 1.Typora需要升级到最新版 2.需要安装nodejs PicGo软件下载地址: ...

  5. display:block 和display:inline-block的区别和用法

    1).块状元素:(div,p,form,ul,ol,li) ,独占一行,默认情况width为100% 2).行内块状元素:(span,img,a),不会独占一行,相邻的元素一直排在同一行,排满了才会换 ...

  6. 从 C# 崩溃异常 中研究页堆布局

    一:背景 1.讲故事 最近遇到一位朋友的程序崩溃,发现崩溃点在富编辑器 msftedit 上,这个不是重点,重点在于发现他已经开启了 页堆 ,看样子是做了最后的挣扎. 0:000> !analy ...

  7. python+request+pymysql+pytest数据驱动

    一.pymysql简单使用 1.安装mysql 下载地址:https://www.mysql.com/,安装教程这里不做介绍了,网上一大推. 2.安装pymysql库 在Terminal终端输入:pi ...

  8. 空 Maven项目转成 Web项目 & SpringMVC调用其他 Module中的方法可能会遇到的小问题

    SpringMVC调用其他 模块内的方法的 坑 下次别在阴沟里翻船啦.. 一共花费 4个小时,解决项目中的这个问题 OMG 1. 首先是 Maven新建工程 一般使用 Maven都是先创建 空工程 当 ...

  9. 【pytest官方文档】解读- 插件开发之hooks 函数(钩子)

    上一节讲到如何安装和使用第三方插件,用法很简单.接下来解读下如何自己开发pytest插件. 但是,由于一个插件包含一个或多个钩子函数开发而来,所以在具体开发插件之前还需要先学习hooks函数. 一.什 ...

  10. 使用工厂方法模式设计能够实现包含加法(+)、减法(-)、乘法(*)、除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果。要求使用相关的工具绘制UML类图并严格按照类图的设计编写程序实

    2.使用工厂方法模式设计能够实现包含加法(+).减法(-).乘法(*).除法(/)四种运算的计算机程序,要求输入两个数和运算符,得到运算结果.要求使用相关的工具绘制UML类图并严格按照类图的设计编写程 ...