快速使用Vue3最新的15个常用API(中)

简介: 接上文。

(6)toRefs


了解完 toRef 后,就很好理解 toRefs 了,其作用就是将传入的对象里所有的属性的值都转化为响应式数据对象,该函数支持一个参数,即 obj 对象


我们来看一下它的基本使用


<script>
// 1. 导入 toRefs
import {toRefs} from 'vue'
export default {
    setup() {
        const obj = {
          name: '前端印象',
          age: 22,
          gender: 0
        }
        // 2. 将 obj 对象中属性count的值转化为响应式数据
        const state = toRefs(obj)
        // 3. 打印查看一下
        console.log(state)
    }
}
</script>


打印结果如下:


dd453cce9f6aca6500c2e9edb8ead00e.png


返回的是一个对象,对象里包含了每一个包装过后的响应式数据对象


(7)shallowReactive


听这个API的名称就知道,这是一个浅层的 reactive,难道意思就是原本的 reactive 是深层的呗,没错,这是一个用于性能优化的API


其实将 obj 作为参数传递给 reactive 生成响应式数据对象时,若 obj 的层级不止一层,那么会将每一层都用 Proxy 包装一次,我们来验证一下


<script>
import {reactive} from 'vue'
export default {
    setup() {
        const obj = {
          a: 1,
          first: {
            b: 2,
            second: {
              c: 3
            }
          }
        }
        const state = reactive(obj)
        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>


来看一下打印结果:


5318fcf6ccf60e6f881db54f72722a2c.png


设想一下如果一个对象层级比较深,那么每一层都用 Proxy 包装后,对于性能是非常不友好的


接下来我们再来看看 shallowReactive


<script>
import {shallowReactive} from 'vue'
export default {
    setup() {
        const obj = {
          a: 1,
          first: {
            b: 2,
            second: {
              c: 3
            }
          }
        }
        const state = shallowReactive(obj)
        console.log(state)
        console.log(state.first)
        console.log(state.first.second)
    }
}
</script>


来看一下打印结果:


d793928b75d0d748845d3e598ca1be12.png


结果非常的明了了,只有第一层被 Proxy 处理了,也就是说只有修改第一层的值时,才会响应式更新,代码如下:


<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改变1</button>
 <button @click="change2">改变2</button>
</template>
<script>
import {shallowReactive} from 'vue'
export default {
    setup() {
        const obj = {
          a: 1,
          first: {
            b: 2,
            second: {
              c: 3
            }
          }
        }
        const state = shallowReactive(obj)
        function change1() {
          state.a = 7
        }
        function change2() {
          state.first.b = 8
          state.first.second.c = 9
          console.log(state);
        }
        return {state}
    }
}
</script>


来看一下具体过程:


7d1548b4e56b62d53f7cb10224e48d34.jpg


首先我们点击了第二个按钮,改变了第二层的 b 和第三层的 c,虽然值发生了改变,但是视图却没有进行更新;


当我们点击了第一个按钮,改变了第一层的 a 时,整个视图进行了更新;


由此可说明,shallowReactive 监听了第一层属性的值,一旦发生改变,则更新视图


(8)shallowRef


这是一个浅层的 ref,与 shallowReactive 一样是拿来做性能优化的


shallowReactive 是监听对象第一层的数据变化用于驱动视图更新,那么 shallowRef 则是监听 .value 的值的变化来更新视图的


我们来看一下具体代码


<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change1">改变1</button>
 <button @click="change2">改变2</button>
</template>
<script>
import {shallowRef} from 'vue'
export default {
    setup() {
        const obj = {
          a: 1,
          first: {
            b: 2,
            second: {
              c: 3
            }
          }
        }
        const state = shallowRef(obj)
        console.log(state);
        function change1() {
          // 直接将state.value重新赋值
          state.value = {
            a: 7,
            first: {
              b: 8,
              second: {
                c: 9
              }
            }
          }
        }
        function change2() {
          state.value.first.b = 8
          state.value.first.second.c = 9
          console.log(state);
        }
        return {state, change1, change2}
    }
}
</script>


首先看一下被 shallowRef 包装过后是怎样的结构


df8b8c48db2318dcbfedd2109a124166.png


然后再来看看改变其值会有什么变化


2acc6ebaa2e28b5b6e9fe1a653f70cbc.jpg


我们先点击了第二个按钮,发现数据确实被改变了,但是视图并没随之更新;


于是点击了第一个按钮,即将整个 .value 重新赋值了,视图就立马更新了


这么一看,未免也太过麻烦了,改个数据还要重新赋值,不要担心,此时我们可以用到另一个API,叫做 triggerRef ,调用它就可以立马更新视图,其接收一个参数 state ,即需要更新的 ref 对象


我们来使用一下


<template>
 <p>{{ state.a }}</p>
 <p>{{ state.first.b }}</p>
 <p>{{ state.first.second.c }}</p>
 <button @click="change">改变</button>
</template>
<script>
import {shallowRef, triggerRef} from 'vue'
export default {
    setup() {
        const obj = {
          a: 1,
          first: {
            b: 2,
            second: {
              c: 3
            }
          }
        }
        const state = shallowRef(obj)
        console.log(state);
        function change() {
          state.value.first.b = 8
          state.value.first.second.c = 9
          // 修改值后立即驱动视图更新
          triggerRef(state)
          console.log(state);
        }
        return {state, change}
    }
}
</script>


我们来看一下具体过程


cc5e160d9d8a953fcf632dafa55816c4.jpg


可以看到,我们没有给 .value 重新赋值,只是在修改值后,调用了 triggerRef 就实现了视图的更新


(9)toRaw


toRaw 方法是用于获取 refreactive 对象的原始数据的


先来看一段代码


<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改变</button>
</template>
<script>
import {reactive} from 'vue'
export default {
    setup() {
        const obj = {
          name: '前端印象',
          age: 22
        }
        const state = reactive(obj) 
        function change() {
          state.age = 90
          console.log(obj); // 打印原始数据obj
          console.log(state);  // 打印 reactive对象
        }
        return {state, change}
    }
}
</script>


来看看具体过程


f5ce37393f0c3a71afe95b7422d0f9f4.jpg


我们改变了 reactive 对象中的数据,于是看到原始数据 obj 和被 reactive 包装过的对象的值都发生了变化,由此我们可以看出,这两者是一个引用关系


那么此时我们就想了,那如果直接改变原始数据 obj 的值,会怎么样呢?答案是:reactive 的值也会跟着改变,但是视图不会更新


由此可见,当我们想修改数据,但不想让视图更新时,可以选择直接修改原始数据上的值,因此需要先获取到原始数据,我们可以使用 Vue3 提供的 toRaw 方法


toRaw 接收一个参数,即 ref 对象或 reactive 对象


<script>
import {reactive, toRaw} from 'vue'
export default {
    setup() {
        const obj = {
          name: '前端印象',
          age: 22
        }
        const state = reactive(obj) 
        const raw = toRaw(state)
        console.log(obj === raw)   // true
    }
}
</script>


上述代码就证明了 toRaw 方法从 reactive 对象中获取到的是原始数据,因此我们就可以很方便的通过修改原始数据的值而不更新视图来做一些性能优化了


注意: 补充一句,当 toRaw 方法接收的参数是 ref 对象时,需要加上 .value 才能获取到原始数据对象


(10)markRaw


markRaw 方法可以将原始数据标记为非响应式的,即使用 refreactive 将其包装,仍无法实现数据响应式,其接收一个参数,即原始数据,并返回被标记后的数据


我们来看一下代码


<template>
 <p>{{ state.name }}</p>
 <p>{{ state.age }}</p>
 <button @click="change">改变</button>
</template>
<script>
import {reactive, markRaw} from 'vue'
export default {
    setup() {
        const obj = {
          name: '前端印象',
          age: 22
        }
        // 通过markRaw标记原始数据obj, 使其数据更新不再被追踪
        const raw = markRaw(obj)   
        // 试图用reactive包装raw, 使其变成响应式数据
        const state = reactive(raw) 
        function change() {
          state.age = 90
          console.log(state);
        }
        return {state, change}
    }
}
</script>


我们来看一下在被 markRaw 方法处理过后的数据是否还能被 reactive 包装成响应式数据


912282122c3f3d00d91d71635671c0ff.jpg


从图中可以看到,即使我们修改了值也不会更新视图了,即没有实现数据响应式

相关文章
|
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 的设计理念及其在构建现代前端应用中的优势。
41 1
深入理解 Vue 3 的 Composition API 与新特性
|
1月前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
33 2
|
3月前
|
JavaScript 前端开发 API
花了一天的时间,地板式扫盲了vue3中所有API盲点
这篇文章全面介绍了Vue3中的API,包括组合式API、选项式API等内容,旨在帮助开发者深入了解并掌握Vue3的各项功能。
花了一天的时间,地板式扫盲了vue3中所有API盲点
|
2月前
|
缓存 JavaScript API
Vue 3的全新Reactivity API:解锁响应式编程的力量
Vue 3引入了基于Proxy的全新响应式系统,提升了性能并带来了更强大的API。本文通过示例详细介绍了`reactive`、`ref`、`computed`、`watch`等核心API的使用方法,帮助开发者深入理解Vue 3的响应式编程。无论你是初学者还是资深开发者,都能从中受益,构建更高效的应用程序。
28 1
|
2月前
|
缓存 JavaScript API
Vue 3的全新Reactivity API:解锁响应式编程的力量
【10月更文挑战第9天】Vue 3的全新Reactivity API:解锁响应式编程的力量
26 3
|
2月前
|
JavaScript API
|
2月前
|
API
《vue3第四章》Composition API 的优势,包含Options API 存在的问题、Composition API 的优势
《vue3第四章》Composition API 的优势,包含Options API 存在的问题、Composition API 的优势
27 0
|
2月前
|
JavaScript 前端开发 API
《vue3第六章》其他,包含:全局API的转移、其他改变
《vue3第六章》其他,包含:全局API的转移、其他改变
23 0
|
2月前
|
存储 前端开发 JavaScript
深入理解Vue3的组合式API及其实践应用
【10月更文挑战第5天】深入理解Vue3的组合式API及其实践应用
103 0
|
2月前
|
JavaScript 前端开发 安全