Vue3中的ref和reactive函数如何使用?区别是什么?

ref函数

语法:

复制const xxx=ref(initValue)

接受的数据类型:基本类型,对象类型

作用:

把参数加工成一个响应式对象,全称为reference对象(我们下面一律简称为ref对象)

核心原理:

响应式依赖Object.defineProperty()的get()和set()。

Ref函数对于基本数据类型的参数

基本使用:

复制 

{{Str}}

import {ref} from 'vue'export default {  setup(){    const Str =ref('hello')    return{      Str    }  }}

上面我们定义了一个Str变量来接收ref加工生成的ref对象,我们都知道对象的数据都是以键值对的形式存储的,但是在这里为什么直接把Str给return出去, 并且模板里可以直接写Str这个对象呢,我们的源数据呢?带着这个疑问我们来输出一下Str:

复制setup(){    const Str =ref('hello')    console.log(Str)    return{      Str    }}

打印结果如下:

复制RefImpl__v_isRef: true_rawValue: "hello"_shallow: false_value: "hello"value: "hello"[[Prototype]]: Object

在这里我们看到了ref对象身上的一个属性 value,没错,我们存入的值就对应在value属性上,至于为什么直接return出是Str而不是Str.value。是因为Vue帮了我们一个忙,我们在这里可以简写,return出去的Str就相当于Str.value,当然,非要写.value的形式也不是不可以。不过这里需要注意的是,在setup函数中操作Str中的数据不可以简写。

响应式原理:

对于基本数据类型说完了它的基本用法,下面我们来说说他的响应式原理,也就是我们为什么非要用一个ref对象来接受数据,而不是直接就定义好一个字符串'hello',然后去直接操作这个字符串?

对于ref函数,数据参数和它加工生成的ref对象二者存在着某种“契约”,我们把加工好的参数也就是ref对象交出去之后,我们直接操作修改的就是ref对象上的value属性,因为这个契约的存在,以至于在修改属性值的时候对应的源数据参数也会连同被修改,但在原数据被修改之前vue就会监听到我们修改了数据,立马进行解析模板更新页面,这就是ref对象的响应式原理。这里的契约其实就是Object.defineProperty的get()和set(),篇幅有限我们不对底层核心代码做示范.

我们知道了ref函数定义基本类型,下面会讲解reactive函数,该函数参数是对象类型和ref的对象类型参数有着千丝万缕的联系,所以学会reactive函数学会了ref函数存储的对象数据类型也就自然理解了。

reactive函数

语法:

复制const xxx=ref(源对象)

接受的数据类型:对象类型

作用:

把参数加工成一个代理对象,全称为proxy对象

核心原理:

基于Es6的Proxy实现,通过代理操作源对象,相比于reactive定义的浅层次响应式数据对象,reactive定义的是更深层次的响应式数据对象。

reactive对于对象类型的参数

基本使用:

复制 

姓名:{{Person.name}}

 

薪水:{{Person.job.salary}}

import {reactive} from 'vue'export default {  setup(){    const p ={      name:'Ben',      job:{        salary:'30k'      }    }    const Person =reactive(p)    return{      Person    }  }}

这里不同于上面的ref函数,参数是一个对象类型的数据,那么对于接受返回值的Person对象也会和上面的ref对象一样都是把数据对应到value属性上吗?带着这个疑问打印一下Person对象:

复制Proxy[[Handler]]: Object[[Target]]: Objectjob: {salary: "30k"}name: "Ben"[[Prototype]]: Object[[IsRevoked]]: false

我们发现Person对象身上并没有value属性并且Person对象是一个proxy类型的对象,这里我们可以理解为Person是一个加强版的p对象,对于p来说Person是一个代理对象,所以我们可以直接访问到自身的属性,而不是和ref函数一样把数据对应到value属性上,所以我们return出去的Person对象可以直接放在模板里读取属性。

响应式原理:

reactive的响应式是更加“深层次”的,底层依赖于ES6中的Proxy实现,用reactive函数加工出来的对象都是Proxy对象,无论原数据对象里面有多少层对象他们都会被加工成Proxy类型对象(深层次)。它的响应式核心思想和ref是大同小异的,这里我们定义的Person对象来代理p对象,二者也会建立“契约”,我们在把Person对象return出去后,在我们操作修改Person对象的数据时,在原对象数据改变之前Vue都会监听到这一举动并且同时解析模板、更新页面。

Ref函数对于对象类型的参数

说到这里大家会有个疑问,ref定义对象类型的数据和这个reactive函数有什么关系呢?

ref对象只能去操作浅层次的数据,把基本数据类型当做自己的属性值,如果ref函数的参数是对象这种深层次的数据类型时它会求助一个人,这个人不是别人正是reactive函数,在底层Vue会把对象参数通过reactive函数加工成一个Proxy代理对象放到ref的value属性上。

复制 

姓名:{{Person.name}}

 

薪水:{{Person.job.salary}}

import {reactive,ref} from 'vue'export default {  setup(){    const p ={      name:'Ben',      job:{        salary:'30k'      }    }    const Person =ref(p)    console.log(Person)    return{      Person    }  }}

打印Person对象的结果:

复制RefImpl {_shallow: false, __v_isRef: true, _rawValue: {…}, _value: Proxy}__v_isRef: true_rawValue: {name: "Ben", job: {…}}_shallow: false_value: Proxy {name: "Ben", job: {…}}value: Proxy[[Handler]]: Object[[Target]]: Objectjob: {salary: "30k"}name: "Ben"[[Prototype]]: Object[[IsRevoked]]: false[[Prototype]]: Object

我们可以很清楚的看到,value属性下对应的正是给p原数据对象加工生成Proxy对象。

区别

存储类型:ref对象可以接受基本数据类型得数据也可以接受对象类型的数据,而reactive只可以接受对象类型的数据;

响应式:相比于ref对象reactive函数是更深层次的,ref函数参数为对象类型时依赖的也是reactive函数;

用法:Proxy代理对象的数据键值对是和原数据对象的键值对一一对应的,在使用时可以直接使用 对象(接受返回值的对象).键名 的形式,ref对象会把数据参数对应到自己;

value属性上,在模板里我们可以直接省略.value的形式,这看起来好像是“把源数据赋值给了ref类型的变量,可以直接在模板上使用这个ref类型的变量”;

响应式原理:ref的响应式原理是依赖于Object.defineProperty()的get()和set()而reactive的响应式原理是依赖于ES6中的Proxy。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,340评论 5 467
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,762评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,329评论 0 329
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,678评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,583评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,995评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,493评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,145评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,293评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,250评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,267评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,973评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,556评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,648评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,873评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,257评论 2 345
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,809评论 2 339

推荐阅读更多精彩内容