• vue3学习(二)--- ref和reactive


    ref

    1.1 ref将基础类型和对象类型数据转为响应式

    接受一个内部值,返回一个响应式的、可更改的 ref 对象,此对象只有一个指向其内部值的属性 .value。

    vue3中定义数据默认不是响应式的数据,需要手动将数据转化为响应式的,这里就用到了ref()

    let num1 = 20  //非响应式的
    
    import {ref} from 'vue'v
    let num1 = ref(20) // 响应式的
    
    • 1
    • 2
    • 3
    • 4
    1. ref()可以将数据转为响应式数据
    2. 获取ref(xx)的值需要使用.value的形式,html模板中使用不需要.value因为html中默认就是通过.value来获取值的

    1.2 ref()获取id元素

    <p ref="demo">获取ref的元素</p>
    
    import {ref,onmounted} from 'bue'
    
    onMounted(()=>{
    	let demo= ref()  这样就获取了id=demo的元素
    	console.log(demo.value)
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意!声明的变量名要跟dom元素的id一致才可以, ref不传任何参数。记得在dom挂载之后再获取

    1.3 isRef

    判断是不是一个ref对象

    import { ref, Ref,isRef } from 'vue'
    let message: Ref<string | number> = ref("我是message")
    let notRef:number = 123
    const changeMsg = () => {
      message.value = "change msg"
      console.log(isRef(message)); //true
      console.log(isRef(notRef)); //false
      
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    reactive

    1.1 reactive()将引用类型数据转为响应式数据,基本类型无效

    在这里插入图片描述

    let _obj = {
          num: 20,
        }
    
    let objRef = ref(_obj)
     console.log('ref  obj', objRef.value.num)
    
    let obj = reactive(_obj)
    console.log('reactive  obj', obj.num) 
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述
    其实ref().value内部是跟reactive()一样的,所以说ref内部是通过reactive实现的。

    1. ref()----用于基本数据类型和引用类型
    2. reactive()----用于引用类型

    1.2 ref和reactive的联系

    reactive针对引用类型,内部通过new Proxy实现,因为new proxy可以直接拦截引用类型,无法直接在基础类型进行拦截。

    ref针对基础类型和引用类型,内部会生成一个对象添加value属性指向数据类型,然后再通过reactivenew proxy)对生成的对象进行拦截。达到响应式的效果。

    所以为什么ref的值需要用.value来获取,因为内部生成一个新的带有value属性的对象,只有对象的形式才能使用new proxy进行拦截
    在这里插入图片描述


    toRef 和 toRefs

    作用:
    在解构 reactive()得到对象的时候,将解构的数据变成响应式ref()类型.
    当然解构出来的数据依旧需要通过.value的形式来操作.
    常用于es6的解构赋值操作,因为在对一个响应式对象直接解构时解构后的数据将不再有响应式,而使用toRefs和toRef 可以方便解决这一问题。

     let _obj = {
          num: 20,
        }
    let obj = reactive(_obj)
    
    //toRef 
    let num = toRef(obj,'num') 
    
    //toRefs
    let { num } = toRefs(obj)
    const handleClick = () => {
        // obj.num++
        // toRefs()模式
        num.value++
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    toRef针对对象的单个属性,toRefs直接针对对象,记得需要用.value来获取值

    1.1 如果原始对象是非响应式的就不会更新视图 数据是会变的

    const obj = {
       foo: 1,
       bar: 1
    }
    const state = toRef(obj, 'bar')
    // bar 转化为响应式对象
    const state = toRefs(obj)
    // obj 转化为响应式对象
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    obj对象是非响应式的 ,toRef/toRefs可以将obj转为响应式对象,但视图的更新方法在ref reactive中有实现,toRef/toRefs并没有更新视图的功能

    toRef/toRefs实现的大体思路是:判断是不是响应式对象,如果是直接返回,如果不是通过ObjectRefImpl()将数据变成响应式

    
    export function toRef<T extends object, K extends keyof T>(
      object: T,
      key: K,
      defaultValue?: T[K]
    ): ToRef<T[K]> {
      const val = object[key]
      return isRef(val)
        ? val
        : (new ObjectRefImpl(object, key, defaultValue) as any)
    }
    
     ObjectRefImpl的实现
    
    class ObjectRefImpl<T extends object, K extends keyof T> {
      public readonly __v_isRef = true
     
      constructor(
        private readonly _object: T,
        private readonly _key: K,
        private readonly _defaultValue?: T[K]
      ) {}
     
      get value() {
      	这里没有监听视图变化
        const val = this._object[this._key]
        return val === undefined ? (this._defaultValue as T[K]) : val
      }
     
      set value(newVal) {
     	 这里没有监听视图变化
        this._object[this._key] = newVal
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    下面是ref的源码实现,明显的区别在于toRef没有视图的更新

    在这里插入图片描述

  • 相关阅读:
    九、蜂鸣器
    如何安装GCC?
    DataBinding使用报错
    蜂鸣器电路设计中选用注意事项--【电路设计】
    机器学习笔记 - 什么是 MLOps?
    qt creater11 翻译国际化教程教程:
    点云从入门到精通技术详解100篇-基于激光点云的道路目标检测
    Vue3.0五问五答
    【概率论与数理统计(研究生课程)】知识点总结1(概率论基础)
    es和kibana单机搭建
  • 原文地址:https://blog.csdn.net/weixin_43932245/article/details/133705572