前言: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>
      

  • 备注

    • 接收的数据可以是:基本类型、也可以是对象类型。
    • 基本类型的数据:响应式依然是靠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>
      

二、reactive函数

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

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

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

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

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

      <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>
      

使用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:'✨✨✨'
            }
          ],
        })
    

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐