Vue(Vue2+Vue3)——84.其他Composition API

简介: Vue(Vue2+Vue3)——84.其他Composition API

84  其他Composition API


1 shallowReavtive和shallowRef


shallow中文译为浅层次的,


引入shallowReavtive和shallowRef


想要使用shallowReavtive和shallowRef,也是需要先引入的

import {shallowReactive,shallowRef} from "vue";


shallowReavtive和reavtive


shallowReavtive定义对象类型数据,只考虑第一层响应式,里面的不考虑

如果使用shallowReavtive定义对象,由于shallowReavtive是浅层次的,只能处理第一层属性,嵌套对象属性是不处理的

一级属性name和age都能修改,但是嵌套属性sal是不能修改的

所以shallowReavtive和reavtive区别就是:shallowReavtive只能处理浅层气的数据,但是reavite可以处理多层次的数据


shallowRef和ref


如果定义普通数据类型,nameshallowRef和ref是没有区别的

但是如果定义的是对象类型,那么shallowRef就无效了

下面把ref换成shallowRef

发现没用了

由此可见,ref可以处理普通类型数据和对象类型数据,但是shallowRef只能处理普通类型的数据。


总结


  • shallowReactive:只处理对象最外层属性的响应式(浅响应式)。
  • shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理。
  • 什么时候使用?
  • 如果有一个对象数据,结构比较深, 但变化时只是外层属性变化 ===> shallowReactive。
  • 如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换 ===> shallowRef。


2 readonly 与 shallowReadonly


readonly估计大家都知道,在开发中遇到这个词汇比较多,译为只读,shallowReadonly译为浅层次只读


引入read only 与 shallowReadonly


想要实现必先引入:

import {readonly,shallowReadonly} from "vue";


readonly限制reavtive类型


如果响应式对象里面的属性不想被修改,想要进行保护,那么这个时候就可以使用readonly了:

这个时候再修改,就不会修改成功,并且控制台还会有警告

除了readonly,还有一个类似的属性叫shallowReadonly


shallowReadonly限制reavtive类型


shallowReadonly只考虑第一层数据,不会考虑多层数据

这样只能修改多层次的sal属性,单层次的name和age还是无法修改的

上面说的例子都是reavtive修饰的数据,接下来换成ref修饰的数据,是否还能剩下呢


readonly限制ref类型


把sum使用readonly修饰

也是只能只读的




总结


  • readonly: 让一个响应式数据变为只读的(深只读)。
  • shallowReadonly:让一个响应式数据变为只读的(浅只读)。
  • 应用场景: 不希望数据被修改时。


3 toRaw 与 markRaw


raw中文译为原始的意思,那么toRaw就是把xx变成原始,markRaw就是把xx标记为原始

下面简单介绍下这两个API的作用


引入toRaw 与 markRaw


先要使用就得先引入:

import {toRaw,markRaw} from "vue";


toRaw处理reactive属性


可以使用toRaw使得reactive响应式数据变成原始数据:

发现person对象已经变成了原始数据了


toRaw处理ref属性


既然toRwa可以处理reactive属性,那么是否可以处理ref属性呢,我们也可以验证下。

也是可以的,但是不同的版本处理不同,可能有的低点的vue3版本在这里就不是一个引用对象,而是一个undefined


markRaw禁止属性改变


标记一个对象,使其永远不会再成为响应式对象。

markRaw可以让对象变成最原始的,它不同于readonly,readonly是改都改不了,markRaw可以让数据改变,但是vue不再监视

现在是可以正常修改属性的

使用markRaw修改属性,再次修改已经修改不了了


总结


  • toRaw:
  • 作用:将一个由reactive生成的响应式对象转为普通对象
  • 使用场景:用于读取响应式对象对应的普通对象,对这个普通对象的所有操作,不会引起页面更新。
  • markRaw:
  • 作用:标记一个对象,使其永远不会再成为响应式对象。
  • 应用场景:
  • 有些值不应被设置为响应式的,例如复杂的第三方类库等。
  • 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能。


4 customRef


custom译为自定义,创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。

虽然是自定义,但是也不是完全都是自己写的,可以借助customRef。

下面通过案例演示一下customRef的使用,这个案例也是vue官网提供的防抖效果案例

自定义ref函数

ref其实也是一个函数,我们可以自己创建

这样一个最基本的自定义ref函数就完成了,接下来就可以引入customRef编写逻辑了


引入customRef


想要使用,就得引入customRef

import {customRef } from 'vue'


使用customRef


customRef其实也是一个函数,且必须要返回出来这个customRef函数

但是这么写确报错了:

这是一个底层的错误,因为少了参数,它的参数是一个函数

customRef的参数和返回值


想要解决上面的错误,需要给customRef进行传参,vue设置的customRef参数是一个函数,这个函数里面就是自定义的逻辑

但是又报错了,这次的错误是没有get,其实是因为自定义函数没有返回值,vue要求为自定义函数的返回值必须是一个对象

但是又双叒叕报错了!

我们需要写两个特殊的属性:一个是get,它是一个函数,一个是set,它的值也是一个函数!

先不说逻辑怎么样,现在至少不报错了


初始化自定义ref页面数据


get

虽然不报错了,但是没有定义的数据,这是因为因为get没有返回值

有人读取数据,get函数就会被执行

我们给get返回数据即可

页面正常了,但是修改不了h3标签的数据,这是因为set没有返回值

set

和get是相反的,有人修改数据,set函数就会被执行,它有一个参数,就是修改后的最新数据

但是这样页面h4的数据还是不会变,这时候就要用到customRef的两个参数了:track,trigger

trigger

trigger有触发器的意思,它可以通知去调用get

track

track有追踪的意思,追踪属性的改变。如果不追踪,那么就永远返回属性最新的值

track要在return之前调用

这样整个自定义的customReff的流程就写完了,数据也可以正常修改了

这时候离官方案例就差一步了,就是延迟加载值,可以使用定时器实现


自定义逻辑:延迟加载(防抖效果)


但是这样不够完美,如果输入的频率大于定时器,那么会造成页面的抖动

可以定义一个变量,每次开启定时器的时候,都把id交给这个变量,然后每次进入set的时候,就清除对应的定时器id,重新开启新的定时器

当然可以再次优化,就是把定时器的事件换成变量,由ref传参:

全部代码如下:

<template>
  <input type="text" v-model="keyWord">
  <h3>{{keyWord}}</h3>
</template> 
<script>
  import { ref,customRef } from 'vue'
  export default {
    name: 'App',
    setup() {
        // 定义一个自定义Ref函数,名称为myRef
        function myRef(value,timerNum){
          let timer
          // 这个return返回的是自定义的ref
           return customRef((track,trigger)=>{
              // 这个return返回的是自定义ref里面的逻辑
              return{
                  get(){
                      // 通知Vue追踪数据的变化
                      track()
                      return value
                  },
                  set(newValue){
                     clearTimeout(timer)
                     timer= setTimeout(() => {
                        value=newValue
                        // 通知vue去重新解析模板
                        trigger() 
                      }, timerNum);
                  }
              }
           })
        }
       //  let keyWord=ref('hello') // 使用vue提供的ref
       let keyWord=myRef('hello',500) // 使用程序员自定义的ref
      return {keyWord}
    }
 }
</script>








总结


  • 作用:创建一个自定义的 ref,并对其依赖项跟踪和更新触发进行显式控制。
  • 实现防抖效果:
<template>
    <input type="text" v-model="keyword">
    <h3>{{keyword}}</h3>
</template>
<script>   import {ref,customRef} from 'vue'
    export default {
        name:'Demo',
        setup(){
            // let keyword = ref('hello') //使用Vue准备好的内置ref
            //自定义一个myRef
            function myRef(value,delay){
                let timer
                //通过customRef去实现自定义
                return customRef((track,trigger)=>{
                    return{
                        get(){
                            track() //告诉Vue这个value值是需要被“追踪”的
                            return value
                        },
                        set(newValue){
                            clearTimeout(timer)
                            timer = setTimeout(()=>{
                                value = newValue
                                trigger() //告诉Vue去更新界面
                            },delay)
                        }
                    }
                })
            }
            let keyword = myRef('hello',500) //使用程序员自定义的ref
            return {
                keyword
            }
        }
    }
</script>





5 provide 与 inject


provide与inject是一种组件中的通信方式。适应于祖孙间通信,祖孙组件也叫跨级组件,因为祖孙组件之间隔了一个父组件

provide译为提供,一般是提供数据

inject译为注入,注入数据

通过provide把数据给祖组件了,然后通过inject可以得到数据,他俩都是函数,可以直接调用,使用起来特别简单

provide 与 inject主要是实现祖与后代组件间通信,如果父子之间通信,可以使用props

下面就通过代码演示一下祖孙间的provide与inject数据交互


创建祖孙组件


首先遇到做点准备工作,创建一个祖孙组件

这里我以App作为祖组件,Child作为子组件,Son作为孙组件,并且都给了点样式

接下来就是一个套娃的效果,其实就是App中引入Child组件并使用,Child组件引入Son组件并使用:

然后一个简单的套娃就出现了

现在我想要把App祖组件传给Son孙组件,可以先给APP准备点数据:

这样数据就造好了,接下来就可以传递给Son孙组件了


引入provide


import {provide} from 'vue'


使用provide


provide都是函数,直接调用即可,需要传递两个参数:

参数1:数据变量

参数2:真正要传递的数据

到这里数据以及提供过去了,provide的代码也就编写完了,接下来是引入inject并使用


引入inject


import {inject} from 'vue'


使用inject


inject只有一个参数,就是provide传递数据的参数名称

数据可以正常接收,并且是响应式的

这样就完成了使用provide和inject祖孙组件的数据交互


总结


  • 作用:实现祖与后代组件间通信
  • 套路:父组件有一个 provide 选项来提供数据,后代组件有一个 inject 选项来开始使用这些数据
  • 具体写法:
  •  1 祖组件中:
setup(){
        ......
    let car = reactive({name:'奔驰',price:'40万'})
    provide('car',car)
    ......
}

   2 后代组件中:

setup(props,context){
        ......
    const car = inject('car')
    return {car}
        ......
}


6 响应式数据的判断


有的时候我们的数据背重重加工,变得比较复杂混乱,这时候如果想要判断它是否是响应式数据,可以借助以下几个API

  • isRef: 检查一个值是否为一个 ref 对象
  • isReactive: 检查一个对象是否是由 reactive 创建的响应式代理
  • isReadonly: 检查一个对象是否是由 readonly 创建的只读代理
  • isProxy: 检查一个对象是否是由 reactive 或者 readonly 方法创建的代理


引入API


还是一样的想要用就得引入:

import {isRef,isReactive,isReadonly,isProxy } from 'vue'


代码实现


简单写点数据判断是不是响应式的

当然都是响应式的

相关文章
|
16天前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
13天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
31 7
|
14天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
36 3
|
13天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
34 1
|
13天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
34 1
|
16天前
|
JavaScript 前端开发 API
Vue 3新特性详解:Composition API的威力
【10月更文挑战第25天】Vue 3 引入的 Composition API 是一组用于组织和复用组件逻辑的新 API。相比 Options API,它提供了更灵活的结构,便于逻辑复用和代码组织,特别适合复杂组件。本文将探讨 Composition API 的优势,并通过示例代码展示其基本用法,帮助开发者更好地理解和应用这一强大工具。
18 1
|
16天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
16天前
Vue3 项目的 setup 函数
【10月更文挑战第23天】setup` 函数是 Vue3 中非常重要的一个概念,掌握它的使用方法对于开发高效、灵活的 Vue3 组件至关重要。通过不断的实践和探索,你将能够更好地利用 `setup` 函数来构建优秀的 Vue3 项目。
|
19天前
|
JavaScript API
vue3知识点:ref函数
vue3知识点:ref函数
29 2
|
19天前
|
JavaScript 前端开发 API
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
vue3知识点:Vue3.0中的响应式原理和 vue2.x的响应式
23 0