vue3中 ref函数、reactive函数

234 阅读3分钟

这是我参与11月更文挑战的第17天,活动详情查看:2021最后一次更文挑战

ref函数:

  • 作用:定义一个响应式的数据

  • 语法: const xxx = ref(initValue)

  1. 创建一个包含响应式数据的 **引用对象** (reference对象,简称ref对象)
    
  2. JS中=操作数据:XXX.value
    
  3. 模板中读取数据:不用.value,直接:<div>{{xxx}}</div>
    

备注:

  1. 接收的数据可以是:基本类型,也可以是对象类型

  2. 基本类型的数据:响应式依然是靠Object.defineProperty()的get与set完成的

  3. 对象类型的数据:内部“求助”了vue3.0中的一个新函数reactive函数(内部具体实现是由proxy来做的)

示例:

我们先用ref来定义一个基本类型数据:

 import { ref} from 'vue'
 setup(){
     let name = ref('liudan')
 }
 

然后在控制台打印这个定义的变量看看是什么样子的

image.png

如上图所示,该变量是一个refimpl对象,并且vue3给他加了个value属性,是他定义的值,同时, 我们可以看到,在这个refimpl对象的原型上有get和set方法,也证明了我们说的,对于基本类型的数据,ref底层实现响应式的方式和vue2中实现响应式的方法是一样的,用的都是Object.defineProperty()的get和set

我们再试着用ref定义一个对象类型的数据:

import { ref } from 'vue'
setup(){
    let job = ref({
        type: '前端工程师',
        salary: '30k'
    })
    return{...}
}

我们先把job变量在控制台打印出来看看

image.png

如上,我们可以看到,job变量依然是一个refimpl对象,但是我们发现,vue3给我们加上去的value属性不再是他原本定义的值了,而是一个es6 Proxy的实例对象,如下:

image.png

那我们要用ref实现对象的响应式应该怎么写呢? 其实很简单,我们只需要再加一层.value就可以了

setup(){
    job.value.type = '高级前端工程师'
}

这样也能改变job中的属性并实现响应式,但是我们一般不这么写,vue3已经给我们提供了定义对象类型的方法:reactive函数

下面我们就来看看reactive函数

reactive函数:

  1. 作用:定义一个对象类型的响应式数据(基本类型不要用它,要用ref)

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

  3. reactive定义的响应式数据是“深层次”的

  4. 内部基于ES6的Proxy实现,通过代理对象对源对象内部数据进行操作

如果我们用reactive定义一个基本类型的数据会怎么样,来看看

import { ref, reactive } from 'vue'
setup() {
        let num = reactive(56)
    }

image.png 可以看到,直接警告了,所以我们不能这么写

正确的写法是:

let job = reactive({
    type:'前端工程师',
    salary:'30k'
 })

我们在控制台打印下看看这个job变量是什么样子的

image.png 可以看到她是一个代理对象(Proxy的实例对象),reactive内部基于ES6的Proxy实现的

reactive定义的响应式数据是“深层次”的
let deepObject = reactive({
      a:{
          b:{
              c:{
                  d:10
               }
          }
       }
   })
 let deepArray = reactive(['sfsd','sfgadsg',2323,'sadfsad'])
 
//修改属性,查看其是否能实现响应式
deepObject.a.b.c.d = 100
deepObject[0] = 111

image.png reactive定义的响应式数据是“深层次”的