二、【Vue3】——ref函数&reactive函数

755 阅读2分钟

本文已参与【新人创作礼】活动,一起开启掘金创作之旅。

前言:Vue3中实现数据响应式,用到的是组合式API中的refreactive函数,不同的是ref函数一般定义基本类型数据,而reactive函数用于定义一个对象类型的响应式数据。

一、ref函数

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

  • 语法: const xxx = ref(initValue)

    • 创建一个包含响应式数据的引用对象(reference对象,简称ref对象)

    • JS中操作数据: xxx.value,因为ref 接收参数并将其包裹在一个带有 value property 的对象中返回;

    • 模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>

<template>
  <h2>名称:{{name}}</h2>
  <button @click="changeName">修改名称</button>
</template>
<script>
import { ref } from 'vue' // 按需引入ref函数
export default {
  name: 'App',
  setup () {
    let name = ref('赵丽颖') // 定义基本类型响应式变量
    function changeName () {
      console.log('name',name)
      name.value = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
    }
    // 将变量和函数返回,以便在模版中使用
    return {
      name,
      changeName
    }
  }
}
</script>

image.png

  • 备注

    • 接收的数据可以是:基本类型、也可以是对象类型。
    • 基本类型的数据:响应式依然是靠Object.defineProperty()getset完成的。
    • 对象类型的数据:内部 “ 求助 ” 了Vue3.0中的一个新函数—— reactive函数(ES6 的 Proxy)。
<template>
  <h2>名称:{{name}}</h2>
  <h2>工作类型:{{job.type}}</h2>
  <button @click="changeName">修改人信息</button>
</template>
<script>
import { ref } from 'vue' // 按需引入ref函数
export default {
  name: 'App',
  setup () {
    let name = ref('赵丽颖') // 定义基本类型响应式变量
    let job = ref({ // ref也可以定义对象类型响应式变量
      type:'演员',
      hobby:'演戏'
    })
    function changeName () {
      console.log('name',name)
      name.value = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
      console.log('job',job)
      job.value.hobby = '看书'
    }
    // 将变量和函数返回,以便在模版中使用
    return {
      name,
      job,
      changeName
    }
  }
}
</script>

image.png

二、reactive函数

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

  • 语法const 代理对象= reactive(源对象)

    • 接收一个对象(或数组),返回一个代理对象(Proxy的实例对象,简称proxy对象);
    • js中操作不需要.value(与ref区别);
    • 模板中读取数据: 不需要.value,直接:<div>{{xxx}}</div>
  • 备注

    • reactive定义的响应式数据是“深层次的”。

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

    • Proxy 响应式原理请参考下篇文档:juejin.cn/post/708046…

<template>
  <h2>名称:{{name.title}}</h2>
  <h2>主要爱好:{{job.hobby[0].type}}</h2>
  <button @click="changeName">修改姓名和爱好</button>
</template>
<script>
import { ref,reactive } from 'vue' // 按需引入ref函数
export default {
  name: 'App',
  setup () {
    let name = ref({ // ref定义对象类型响应式变量
      title:'赵丽颖'
    }) 
    let job = reactive({ // reactive定义对象类型响应式变量
      type:'演员',
      hobby:[
        {
          type:'演戏',
          degree:'✨✨✨✨✨'
        },
        {
          type:'看书',
          degree:'✨✨✨'
        }
      ],
    })
    function changeName () {
      console.log('name',name)
      name.value.title = '刘亦菲' // 对ref定义的响应式数据进行操作,需要使用.value
      console.log('job',job)
      job.hobby[0].type = '运动' // 对reactive定义的响应式数据进行操作,无需使用.value,且是深层次响应
    }
    // 将变量和函数返回,以便在模版中使用
    return {
      name,
      job,
      changeName
    }
  }
}
</script>

image.png

使用ref定义基本类型数据,reactive定义对象类型数据原因:

  • ref定义对象,在js中使用时都应该.value,如果定义的对象嵌套太深,再多一层.value太冗余,而reactive则无需.value;
  • ref定义对象类型数据,里边使用的也是reactive中的Proxy代理,不如直接使用reactive;
  • reactive不能直接定义基本类型数据,不起作用,可以将基本类型数据整体放入一个对象中,将reactive当作Vue2中的data去使用。
let person = reactive({ // 将人信息整体放入一个对象中
      name:'赵丽颖',
      type:'演员',
      hobby:[
        {
          type:'演戏',
          degree:'✨✨✨✨✨'
        },
        {
          type:'看书',
          degree:'✨✨✨'
        }
      ],
    })