美文网首页
Vue 3.0 响应性API(一)

Vue 3.0 响应性API(一)

作者: Joymerry | 来源:发表于2023-09-20 20:56 被阅读0次

说起响应性api,我们不得不谈到reactive与ref。

一、reactive

  1. 什么是reactive?
  • reactive是Vue3中提供的实现响应式数据的方法
  • 在Vue2中响应式数据是通过defineProperty来实现的,而在Vue3中响应式数据是通过ES6的Proxy来实现的
  1. reactive的注意点:
  • reactive参数必须是对象(json/arr)
import { reactive } from 'vue';
export default {
    setup(){
      /*
      *参数必须是对象
      */
      let state = reactive({
          age: 19
      })
      return {state}
    }
}
  • 如果给reactive传递其他对象
    默认情况下修改对象,界面不会自动更新
    如果想更新,可以通过重新赋值的方式
import { reactive } from 'vue';
export default {
    setup(){
      /*
      *参数必须是对象
      */
      // 非json/arr类对象
      let state = reactive({
        time : new Date()
      })
      function myFunc(){
          // 直接修改之前的数据,页面显示不会刷新
          // state.time.setDate(state.time.getDate() + 1);    
        
          // 计算之后,直接赋值,页面显示会更新
          const newTime = new Date(state.time.getTime());
          newTime.setDate(state.time.getDate() + 1);
          state.time = newTime
          console.log(state)
      }
      return {state, myFunc}
    }
}

二、ref

  1. 什么是ref?
  • ref和reactive一样,也是用来实现响应式数据的方法
  • 由于reactive必须传递一个对象,所以导致在企业开发中,如果我们只想让某个变量实现响应式的时候会非常麻烦,所以Vue3就给我们提供了ref方法,实现对简单值的监听
  1. ref本质:
  • ref底层的本质其实还是reactive
    系统会自动根据我们给ref传入的值将它转换成reactive
/*
*ref是key为value,value为xx的reactive
*/
ref(xx) -> reactive({value:xx})
  1. ref注意点
  • 在Vue中使用ref的值不用通过value获取
    如果是通过ref创建的数据,那么在template中使用的时候不用通过.value来获取,因为Vue会自动帮我们添加.value
  • JS中使用ref的值必须通过value获取
<template>
    <!--  模版中使用不需要.value,因为Vue已经自动帮我们做了,
      如果自己添加.value,实际值相当于age.value.value-->
    <p>{{age}}</p>
</template>
<script>
import { ref } from 'vue';
export default {
    let age = ref(10)
    function myFunc(){  
      // 不在template中,Vue不会帮我们添加.value,所以必须添加.value
      age.value = 11;
    }
    return {age,myFunc}
}

三、ref和reactive区别

  1. 虽然说ref的底层是一个reactive,但是其实它们还是有一些区别的。
  • ref和reactive的区别:
    如果在template里使用的是ref类型的数据,那么Vue会自动帮我们添加.value
    如果在template里使用的是reactive类型的数据,那么Vue不会自动帮我们添加.value
  1. Vue如何决定是否需要自动添加.value的
  • Vue在解析数据之前,会自动判断这个数据是否是ref类型的,如果是就自动添加.value,如果不是就不添加
  1. Vue是如何判断当前的数据是否是ref类型的?
  • 通过当前数据的__v_ref的私有属性来判断的
  • 如果有这个私有属性,并且取值为true,那么就代表是一个ref类型的数据


    打印ref对象
  • 我们自己也是可以判断数据是否是ref类型,但是我们不能通过访问数据的私有属性__v_ref来判断,但是Vue提供了一个isRef()的对应方法
<template>
    <p>{{age}}</p>
</template>
<script>
import { ref , isRef } from 'vue';
export default {
    let age = ref(10)
    function myFunc(){  
      age.value = 11;
      // 这里返回数据的详细信息,如上图“打印ref对象”所示
      console.log(age)
      // isRef方法返回一个Boolean值
      console.log(isRef(age))
    }
    return {age,myFunc}
}
  1. 同理,Vue也提供了isReactive()方法判断是否是reactive类型

四、递归监听

  1. 递归监听
  • 默认情况下,无论是通过ref还是reactive都是递归监听
    无论数据嵌套多少层,都可以监听到数据变化
  1. 递归监听存在的问题
  • 如果数据量比较大,非常消耗性能
    为什么说它非常消耗性能呢,我们说过,Vue3.0为了实现响应性,它是通过Proxy实现的,所以为了实现递归监听,每一层数据都包装成Proxy对象,也就是数据嵌套的越深,Proxy对象就越多,这本身是非常消耗性能的
<template>
    <p>{{state.four}}</p>
</template>
<script>
import { reactive } from 'vue';
export default {
    // 多层数据,reactive会进行递归监听
    let state = reactive({
        one : 'one',
        gf:{
            two : 'two',
            f:{
                three : 'three',
                s : {
                  four : 'four'
                }
           }
        }
    })
        
    function myFunc(){
      state.four = 'haha';
      console.log(state);
      console.log(state.gf);
      console.log(state.gf.f);
      console.log(state.gf.f.s);
    }
    return {state,myFunc}
}

代码执行的结果:


递归监听(将每层数据包装成Proxy对象)

五. 非递归监听

  1. 既然有递归监听,为什么要非递归监听呢?
  • 正如上面说的,递归监听是非常消耗性能的,所以才会有非递归监听来解决这个问题,但并不是说,非递归监听就可以取代递归监听,接下来我们进一步了解非递归监听,我们就知道这两种监听在应用中是相得益彰的,各有利弊
  1. 什么是非递归监听?
  • 非递归监听是只监听数据的第一层,不会监听数据其他层
  1. 如果创建非递归监听呢?
    ref -> shallowRef
    reactive -> shallowReactive
    如果说ref、reactive是专门创建递归监听数据,那么shallowRef、shallowReactive就是专门创建非递归监听数据
  2. 非递归监听是怎么实现监听数据变化的?
  • 因为只监听第一层数据,所以如果数据第一层不发生变化,我们是监听不到变化的,要想实现响应性,我们必须保证第一层数据值重新赋值(即发生变化)
  • 我们打印数据会发现,第一层数据是Proxy对象,其他层数据并不是
<template>
    <p>{{state.one}}</p>
</template>
<script>
import { shallowReactive } from 'vue';
export default {
    // 多层数据,shallowReactive会进行非递归监听
    let state = shallowReactive({
        one : 'one',
        gf:{
            two : 'two',
            f:{
                three : 'three',
                s : {
                  four : 'four'
                }
           }
        }
    })
        
    function myFunc(){
      state.one = 'haha';
      console.log(state);
      console.log(state.gf);
      console.log(state.gf.f);
      console.log(state.gf.f.s);
    }
    return {state,myFunc}
}
非递归监听
  • 注意点:
    如果是通过shallowRef创建数据,那么Vue监听的是.value的变化,value才是真正的第一层数据
  1. triggerRef()
  • 如果我们想直接更改不是第一层数据的值,让页面发生变化,这时候就需要用triggerRef()
  • 根据你传入的数据,主动去更新页面
<template>
    <p>{{state.four}}</p>
</template>
<script>
import { shallowRef, triggerRef } from 'vue';
export default {
    // 多层数据,shallowRef会进行非递归监听
    let state = shallowRef({
        one : 'one',
        gf:{
            two : 'two',
            f:{
                three : 'three',
                s : {
                  four : 'four'
                }
           }
        }
    })
        
    function myFunc(){
      state.four = 'haha';
          triggerRef(state);
    }
    return {state,myFunc}
}
  • 注意点:
    Vue3只提供了triggerRef方法,没有提供triggerReactive方法
  1. 应用场景
    一般情况下我们使用 ref和reactive即可
    只有在需要监听的数据量比较大的时候,我们才使用shallowRef/shallowReactive

六、shallowRef的本质

之前我们说过ref的本质就是reactive(ref -> reactive)

/*
*ref的本质就是reactive
*/
ref(10) -> reactive({value:10})
/*
* shallowRef的本质就是shallowReactive
*/
shallowRef(10) -> shallowReactive({value:10})

所有如果用shallowRef创建的数据,它监听的是.value的变化
因为底层的本质上value才是第一层

总结:关于响应性API的东西还有很多,接下来我们一起探索Vue 3.0,共同进步。

相关文章

  • vue3.0-响应性基础API

    reactive返回对象的响应式副本 响应式转换是“深层”的——它影响所有嵌套 property。在基于 ES20...

  • vue 3.0 笔记

    vue 3.0 笔记 1、Vue 3.0 如何做到性能提升 响应式系统升级使用 Proxy 对象重写响应式系统:v...

  • vue3 生命周期

    vue2 到 vue3 生命周期钩子映射关系 Vue 2.0Vue 3.0 选项式 api(Options API...

  • Vue响应式原理

    Vue2.x 核心响应式原理 Vue3.0 核心响应式原理 Vue 自定义事件 Vue 发布订阅模式 发布/订阅模...

  • vue3.0新特性学习笔记1(基本特性)

    vue3.0的设计目标 更小更快加强TypeScript支持加强API设计一致性提高自身可维护性开放更多底层功能 ...

  • vue3相对于vue2的优点

    Vue3.0设计目标 一.更小 二.更快 三.加强API设计一致性 四.加强TypeScripe支持 五.提高自身...

  • Vue3.0响应式原理

    实现方法: 参考资料: Vue3.0 响应式原理第二节 参考资料: Vue 作者尤雨溪为你分享:Vue 3.0 进...

  • vue3.x

    一、体验vue3.0 API 1.初始化项目 vue-cli目前还没有发布支持vue3.0的版本,需要手动配置we...

  • 在Vue中为什么需要组合API

    目前在Vue世界中,最热门的话题是Composition API,这是Vue 3.0中引入的基于函数的API。在本...

  • Vue 3.0 学习笔记(李南江老师Vue3视频笔记)

    01-Vue 3.0开篇-理解 一、为什么现在才讲Vue3.0? 因为昨天才发布正式版本 正式版之前API不稳定(...

网友评论

      本文标题:Vue 3.0 响应性API(一)

      本文链接:https://www.haomeiwen.com/subject/ajjxcltx.html