vue3响应式对象:ref和reactive

ref()

<template>
  <button @click="changeMsg">改变信息</button>
  <div>{{ msg }}</div>
  <div>{{ man }}</div>
</template>

<script lang="ts">
import { defineComponent,ref,Ref } from 'vue'

export default defineComponent({
  setup() {
    let msg: Ref<string> = ref("你好")
      let man = ref({name:"wj"})
    const changeMsg = () => {
      msg.value = "我还好"
      console.log(msg);
      man.value.name = "hhhh"
      console.log(man);
      
    }

    return {
      msg,
      man,
      changeMsg
    }
  }
})
</script>

针对简单对象

针对复杂对象,但是内部的value被proxy代理了

isRef()

判断是不是一个ref对象

<template>
  <button @click="handleClick">点击</button>
  <div>{{ msg1 }}</div>
  <div>{{ msg2 }}</div>
</template>

<script setup lang="ts">
import { ref,isRef } from 'vue'

let msg1 = ref("我是msg1")
let msg2 = "我是msg2"

const handleClick=()=>{
  console.log(isRef(msg1)); //true
  console.log(isRef(msg2));	//false
}
</script>

<style scoped></style>

shallowRef()

浅层响应式。创建一个跟踪自身 .value 变化的 ref,但不会使其值也变成响应式的

<template>
  <button @click="handleClick">点击</button>
  <div>{{ man }}</div>
</template>

<script setup lang="ts">
import { ref,shallowRef } from 'vue'

let man = shallowRef({
  name: "wj",
  code: {
    js:true
  }
})

const handleClick=()=>{
  man.value.code.js = false;
  console.log(man);
}
</script>

shallowRef针对复杂对象,其value内部直接是值,不是一个proxy对象,无法做到深层响应

shallowRef不可以和ref同时使用,如果同时使用,shallowRef也会深层响应

<template>
  <button @click="handleClick">点击</button>
  <div>ref:{{ refMan }}</div>
  <div>shallowRef:{{ man }}</div>  
</template>

<script setup lang="ts">
import { ref,shallowRef } from 'vue'

let man = shallowRef({
  name: "wj",
  code: {
    js:false
  }
})

let refMan = ref({
  name: "小米",
  code: {
    ts:false
  }
})

const handleClick = () => {
  refMan.value.code.ts = true
  man.value.code.js = true;
  console.log(refMan);
  console.log(man);
}
</script>

总结:

  1. ref 是深层次响应式,shallowRef 是浅层次响应式
  2. ref 和 shallowRef 不能写在一块,不然会影响shallowRef 造成视图更新

tiggerRef()

强制更新页面的DOM

<template>
  <button @click="handleClick">点击</button>  
  <div>shallowRef:{{ man }}</div>  
</template>

<script setup lang="ts">
import { shallowRef,triggerRef } from 'vue'

let man = shallowRef("我是shallowRef")


const handleClick = () => {  
  man.value = "我是shallowRef,我被改变了";
  triggerRef(man)
  console.log(man);
}
</script>

customRef()

官网介绍:https://cn.vuejs.org/api/reactivity-advanced.html#customref

创建一个自定义的 ref,显式声明对其依赖追踪和更新触发的控制方式。

<template>
  <button @click="handleClick">点击</button>  
  <div>customRef:{{ obj }}</div>  
</template>

<script setup lang="ts">
import { customRef } from 'vue'

function myRef<T>(value:T) {
  return customRef((track, trigger)=> {
    return {
      get() {
        track()
        return value
      },
      set(newVal) {
        console.log("触发了");
        
        value = newVal
        trigger()
      }
    }
  })
}
let obj = myRef<string>("我是customRef")

const handleClick = () => {  
  obj.value = "我是我是customRef,我被改变了";
  console.log(obj);
}
</script>

使用场景:可以自由控制响应式处理,比如在接口调用时候(官网示例)

import { customRef } from 'vue'

export function useDebouncedRef(value, delay = 200) {
  let timeout
  return customRef((track, trigger) => {
    return {
      get() {
        track()
        return value
      },
      set(newValue) {
        clearTimeout(timeout)
        timeout = setTimeout(() => {
          value = newValue
          trigger()
        }, delay)
      }
    }
  })
}

reactive()

官网:https://cn.vuejs.org/guide/essentials/reactivity-fundamentals.html#reactive

1、reactive 限定了值类型,只能用于对象类型(Object、Array、集合(Map、Set))


<template>
  <button @click="change">按钮</button>
  <hr/>
  <div>persion: {{ person }}</div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

let person = reactive({
  name: "Tom",
  age: 23,
  gender:1
})

const change = () => {
  person.name = "timi"
  console.log(person);
}

</script>

2、不能替换整个对象:reactive是proxy对象,不能直接赋值,否则会破会其响应式

<template>
  <button @click="noProxyChange">直接修改</button>
  <hr/>
  <div>list: {{ list }}</div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

let list:string[] = reactive<string[]>([])

const noProxyChange = () => {  
  let temp = ["1", "2", "3"]
  //替换了整个list对象
  list = temp
  console.log(list);  
}
</script>

解决方法:使用数组自带方法改变数组

<template>  
  <button @click="proxyChange">响应式修改</button>  
  <hr/>
  <div>list: {{ list }}</div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

let list:string[] = reactive<string[]>([])

const proxyChange = () => {  
  list.push("1")
  list.push("2")
  list.push("3")
  console.log(list);  
}
</script>

<style scoped></style>

shallowReactive()

reactive() 的浅层作用形式

详情见文档:https://cn.vuejs.org/api/reactivity-advanced.html#shallowreactive

ref和reactive

  1. ref绑定对象类型时,通过源码知道也是调用的 reactive
  2. ref 取值和赋值都需要加 .value,reactive 不需要
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值