Vue3中 响应式 API( shallowReactive、shallowRef、triggerRef 、customRef )详解

简介: Vue3中 响应式 API( shallowReactive、shallowRef、triggerRef 、customRef )详解

传送门:Vue3中 响应式API ( reactive、ref、toRef、toRefs ) 详解

传送门:Vue3中 响应式 API ( readonly、shallowReadonly、toRaw、markRaw ) 详解

1. shallowReactiv 函数。

reactive() 的浅层作用形式。

只处理对象最外层属性的响应式(浅响应式)。

应用场景: 如果一个对象属性数据,结构较深,但变化时只是外层属性变化。

<template>
  <div>
    <div>
      {{obj1.name}} {{obj1.info.age}}
      <button @click="obj1Age">obj1Age</button>
    </div>
    <div>
      {{obj2.name}} {{obj2.info.age}} {{obj2.money}}
      <button @click="obj2Age">obj2Age</button>
    </div>
  </div>
</template>
<script>
import { reactive,shallowReactive } from 'vue';
export default {
  setup(){
    const obj1 = reactive({
      name:'张三',
      info:{
        age:18
      }
    })
    const obj2 = shallowReactive({
      name:'李四',
      money:100,
      info:{
        age:18
      }
    })
    const obj1Age = () => {
      obj1.info.age++;
    }
    const obj2Age = () => {
      //obj2.money++; // 放开注释视图才会进行更新(原因是 shallowRefState 首层 value 发生了改变)
      obj2.info.age++;
      console.log(obj1,obj2)
    }
    return {
      obj1,
      obj2,
      obj1Age,
      obj2Age,
    }
  } 
}
</script>

先触发 obj1Age 两次,再触发 obj2Age 两次。

1ecd1b2606ed46e9956a89f231c9802c.png

2. shallowRef 函数

ref() 的浅层作用形式。

  • shallowRef() 函数是浅层响应,只有对 value 整体修改,才能更新到视图层;
  • 对属性值的修改是可以的,只是不更新到视图层;
  • 对属性值修改之后,可通过 triggerRef() 函数手动更新到视图;

应用场景: 如果一个对象属性数据,后续功能不会修改该对象中的属性,而是新生对象来替换。

<template>
  <div>
    <div>
      {{count}}
      <button @click="changeCount">changeCount</button>
    </div>
    <div>
      {{count2.num}}
      <button @click="changeCount2">changeCount2</button>
    </div>
    <div>
      {{count3.num}}
      <button @click="changeCount3">changeCount3</button>
    </div>
    <div>
      {{count4.num}}
      <button @click="changeCount4">changeCount4</button>
    </div>
  </div>
</template>
<script>
import { shallowRef,triggerRef } from 'vue';
export default {
  setup(){
    const count = shallowRef(0);
    const count2 = shallowRef({ num:0 });
    const count3 = shallowRef({ num:0 });
    const count4 = shallowRef({ num:0 });
    const changeCount = () => {
      count.value++
    }
    // 只更改num属性值,不会更新视图
    const changeCount2 = () => {
      count2.value.num++;
      console.log('count2',count2)
    }
    // 整体更新value,会更新视图
    const changeCount3 = () => {
      count3.value = { num: 10}
    }
    // 手动更新视图
    const changeCount4 = () => {
      count4.value.num++;
      triggerRef(count4)
    }
    return {
      count,
      count2,
      count3,
      count4,
      changeCount,
      changeCount2,
      changeCount3,
      changeCount4,
    }
  } 
}
</script>

只触发 changeCount2 两次(未触发其他方法,防止视图更新)

1ecd1b2606ed46e9956a89f231c9802c.png

3. triggerRef 函数

强制触发依赖于一个浅层 ref 的副作用,这通常在对浅引用的内部值进行深度变更后使用。

  • 手动执行与 shallowRef 关联的任何作用 (effect);
  • 配合 shallowRef 用的,并且 shallowRef 传入的是个引用类型;
<template>
  <div>
    <div>
      {{count4.num}}
      <button @click="changeCount4">changeCount4</button>
    </div>
  </div>
</template>
<script>
import { shallowRef,triggerRef } from 'vue';
export default {
  setup(){
    const count4 = shallowRef({ num:0 });
    // 手动更新视图
    const changeCount4 = () => {
      count4.value.num++;
      console.log(count4);
      triggerRef(count4);
    }
    return {
      count4,
      changeCount4,
    }
  } 
}
</script>

只触发 changeCount4 两次

1ecd1b2606ed46e9956a89f231c9802c.png

注意:没有 triggerReactive

4. customRef 函数

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

function customRef<T>(factory: CustomRefFactory<T>): Ref<T>
type CustomRefFactory<T> = (
  track: () => void,
  trigger: () => void
) => {
  get: () => T
  set: (value: T) => void
}

customRef() 预期接收一个工厂函数作为参数,这个工厂函数接受 track 和 trigger 两个函数作为参数,并返回一个带有 get 和 set

方法的对象。

一般来说,track() 应该在 get() 方法中调用,而 trigger() 应该在 set() 中调用。然而事实上,你对何时调用、是否应该调用他们有完全的控制权。

<template>
  <input type="text" v-model="keyWord">
  <h3>{{ keyWord }}</h3>
</template>
<script>
import { ref,customRef } from 'vue';
export default {
  setup(){
    function myRef(value,delay = 200){
      let timer = null;
      // return 指代 把自定义的ref函数交出去
      return customRef((track,trigger) => {
        // return 指代 customeRef 形参中的返回体必须返回一个对象,所以必须写return{}
        return {
          get(){
            console.log('从myRef中读取值',value); // 因为模板<h3>和输入框<input>各读取了一次keyWord属性,所以打印2次
            track();// 通知 Vue 追踪 value 的变化
            return value
          },
          set(newVal){
            // myRef(value)中的形参value代表调用自定义函数传入的参数,而set(newValue)中的newValue代表input输入框修改后的值。
            console.log('设置值',newVal)
            clearTimeout(timer);
            timer = setTimeout(() => {
              value = newVal;
              trigger(); // 通知 Vue 重新解析模板
            },delay)
          }
        }
      })  
    }
    let keyWord = myRef('hello',300);
    return {
      keyWord
    }
  } 
}
</script>

效果:

20201204182323419.gif





相关文章
|
1月前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
31 1
|
1月前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
32 1
|
1月前
|
监控 JavaScript 算法
深度剖析 Vue.js 响应式原理:从数据劫持到视图更新的全流程详解
本文深入解析Vue.js的响应式机制,从数据劫持到视图更新的全过程,详细讲解了其实现原理和运作流程。
|
2月前
|
缓存 JavaScript 前端开发
深入理解 Vue 3 的 Composition API 与新特性
本文详细探讨了 Vue 3 中的 Composition API,包括 setup 函数的使用、响应式数据管理(ref、reactive、toRefs 和 toRef)、侦听器(watch 和 watchEffect)以及计算属性(computed)。我们还介绍了自定义 Hooks 的创建与使用,分析了 Vue 2 与 Vue 3 在响应式系统上的重要区别,并概述了组件生命周期钩子、Fragments、Teleport 和 Suspense 等新特性。通过这些内容,读者将能更深入地理解 Vue 3 的设计理念及其在构建现代前端应用中的优势。
48 1
深入理解 Vue 3 的 Composition API 与新特性
|
1月前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
36 2
|
1月前
|
JavaScript 前端开发 API
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
Vue.js响应式原理深度解析:从Vue 2到Vue 3的演进
58 0
|
2月前
|
API
vue3知识点:响应式数据的判断
vue3知识点:响应式数据的判断
32 3
|
2月前
|
缓存 JavaScript UED
优化Vue的响应式性能
【10月更文挑战第13天】优化 Vue 的响应式性能是一个持续的过程,需要不断地探索和实践,以适应不断变化的应用需求和性能挑战。
39 2
|
2月前
|
缓存 JavaScript API
Vue 3的全新Reactivity API:解锁响应式编程的力量
Vue 3引入了基于Proxy的全新响应式系统,提升了性能并带来了更强大的API。本文通过示例详细介绍了`reactive`、`ref`、`computed`、`watch`等核心API的使用方法,帮助开发者深入理解Vue 3的响应式编程。无论你是初学者还是资深开发者,都能从中受益,构建更高效的应用程序。
33 1
|
2月前
|
JavaScript 前端开发 API
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
33 0