Vue3的Composition组合式API(readonly与shallowReadonly函数、toRaw与markRaw函数、customRef函数)

1. readonly与shallowReadonly函数

  • readonly: 让一个响应式数据变为只读的(深只读)
  • shallowReadonly:让一个响应式数据变为只读的(浅只读),可以修改第二层及更深的层数据
  • 应用场景: 不希望数据被修改时。如别人提供的数据,我们只想使用,不想修改

使用示例

<template>
  <h2>当前x的值是:{{x}}</h2>
  <button @click="x++">点我x++</button>

  <h2>姓名:{{person.name}}</h2>
  <h2>薪资:{{person.job.salary}}K</h2>
  <button @click="person.name+='~'">修改姓名</button>
  <button @click="person.job.salary++">涨薪</button>
</template>

<script>
import {ref,reactive,readonly,shallowReadonly} from 'vue'
export default {
  name: 'Student',
  setup(){
    let x = ref(0)

    let person = reactive({
      name:'张三',
      job:{
        salary:20
      }
    })

    x = readonly(x)
    person = shallowReadonly(person)

    return {
      x,
      person
    }
  }
}
</script>

效果如下:

  1. 点我x++,页面没反应
  2. 点击修改姓名,页面没反应
  3. 点击涨薪,页面上的薪资能正常变化
    readonly与shallowReadonly函数

3. toRaw与markRaw函数

toRaw:

  • 作用:将一个由reactive生成的响应式对象转为普通对象
  • 注意:对这个普通对象的所有操作,会引起响应式对象的数据发生变化,但不会引起页面更新。等下一次页面被重新渲染时,发生改变的数据会更新到页面

markRaw:

  • 作用:给一个响应式对象,添加一个对象类型的属性A。标记属性A,使其永远不会再成为响应式对象
  • 注意:对属性A的所有操作,会引起属性A的数据发生变化,但不会引起页面更新。等下一次页面被重新渲染时,属性A发生改变的数据会更新到页面
  • 应用场景:
    1. 有些值不应被设置为响应式的,例如引用的复杂的第三方类库等
    2. 当渲染具有不可变数据源的大列表时,跳过响应式转换可以提高性能

使用示例
Student.vue

<template>
  <h2>人员全部信息: {{person}}</h2>
  <h2>姓名:{{person.name}}</h2>
  <button @click="person.name+='~'">修改姓名</button>

  <br>
  <button @click="getAndChangeRawPerson">先获取再改变最原始的person信息</button>
  <br>
  <button @click="addRawCar">给人添加一台最原始的车</button>
  <br>
  <button v-show="person.car" @click="changeCarPrice">改变车的价格</button>
</template>

<script>
import {reactive,toRaw,markRaw} from 'vue'
export default {
  name: 'Student',
  setup(){

    let person = reactive({
      name:'张三'
    })

    function getAndChangeRawPerson(){
      const rawPerson = toRaw(person)
      // 会引起person的数据变化,但页面不会刷新。页面会在下次渲染时更新改变的数据
      rawPerson.name+='$'
    }

    function addRawCar(){
      let car = {name:'大众',price:10}
      // 如果没有markRaw。person.car = car添加的是一个响应式数据。因为person是响应式的
      person.car = markRaw(car)
    }

    function changeCarPrice() {
      // 会引起person的数据变化,但页面不会刷新。页面会在下次渲染时更新改变的数据
      person.car.price = 99
    }

    return {
      person,
      getAndChangeRawPerson,
      addRawCar,
      changeCarPrice
    }
  }
}
</script>

效果如下:

  1. 点击先获取再改变最原始的person信息,页面没有发生变化,但其实person的数据已经改变了

  2. 再点击修改姓名,页面重新渲染,会将之前对toRaw数据的改变也更新到页面
    toRaw函数效果

  3. 点击给人添加一台最原始的车,页面能正常更新person。同时也会出现改变车的价格按钮
    给人添加一台车的效果

  4. 点击改变车的价格,页面没有发生变化,但其实person.car的数据已经改变了

  5. 再点击修改姓名,页面重新渲染,会将之前对markRaw的person.car的数据的改变也更新到页面
    markRow函数的效果

4. customRef函数

  • 作用:创建一个自定义的ref,并对其读取track跟踪更新trigger触发进行显式控制。
  • 案例:实现防抖效果。如下所示:

App.vue

  • 自定义一个ref。value就是ref管理的数据;delay是其它参数
  • 读取value的值,会自动调用get。需要使用track(),通知Vue追踪value的变化,这样才会加载value更新后的数据
  • 当修改value的值,会自动调用set,变传入需要修改的值。需要使用trigger(),通知Vue去重新解析模板
  • set中创建了一个定时器。延迟一段时间,再去修改数据
  • 使用let keyWord = myRef('hello',500)定义了一个响应式的数据keyWord,初始的数据是hello,每次修改keyword都会延迟500ms
<template>
  <input type="text" v-model="keyWord">
  <h3>{{keyWord}}</h3>
</template>

<script>
import {customRef} from 'vue'
export default {
  name: 'App',
  setup() {
    // 自定义一个ref。value就是ref管理的数据;delay是其它参数
    function myRef(value, delay){
      let timer
      return customRef((track,trigger)=>{
        return {
          // 读取value的值,会自动调用get
          get(){
            console.log(`有人从myRef这个容器中读取数据了,我把${value}给他了`)
            track() // 通知Vue追踪value的变化,这样才会加载value更新后的数据
            return value
          },
          // 当修改value的值,会自动调用set,变传入需要修改的值
          set(newValue){
            console.log(`有人把myRef这个容器中数据改为了:${newValue}`)
            clearTimeout(timer)   // 如果有定时器未执行,则先清除旧的定时器,防止抖动
            timer = setTimeout(()=>{    // 延迟一段时间,再去修改数据
              value = newValue
              trigger() // 通知Vue去重新解析模板
            },delay)
          }
        }
      })
    }

    // 使用程自定义的ref
    let keyWord = myRef('hello',500)

    return {keyWord}
  }
}
</script>

效果如下:在输入框的hello后面,快速的输入123,过一段时间,下面的hello也更新为hello123
customRef函数

源码直接下载地址: https://pan.quark.cn/s/d280357b18e5 在网页构建领域中,HTML5被视为当代网页工程的基础规范,其问世显著增强了页面的视觉表现力用户互动性。本工程致力于运用HTML5技术开发一个电视剧信息展示页面,目的是呈现诸如剧名、演员构成、故事梗概等电视剧关键资料。接下来将深入阐释如何借助HTML5的结构化组件和样式管理功能达成此项目目标。 我们必须掌握HTML5的核心框架。一个规范的HTML5文档一般包含`<!DOCTYPE html>`声明、`<html>`根标记、`<head>`头部标记和`<body>`主体标记。在头部区域,可以配置网页的基本元数据,例如字符集设定、页面标题等。在主体部分,将具体构建电视剧信息列表的内容。 电视剧展示页面通常包含多个条目,每个条目对应一部电视剧。HTML5中的`<section>`标记用于内容模块化,适合表示单个电视剧的详细信息区域。每个`<section>`内部,可使用`<h2>`标题标记显示剧名,`<img>`图像标记插入宣传剧照,`<p>`段落标记呈现剧情介绍,而`<ul>`无序列表`<li>`列表项标记则用于罗列演员阵容。 为了优化页面布局,需要借助CSS(层叠样式表)进行样式管理。HTML5引入了创新的CSS选择器布局模型,例如Flexbox和Grid,使页面布局更加灵活多变。在此场景下,可以利用Flexbox为电视剧信息列表实现自适应布局,保障在不同设备尺寸下均能呈现理想视觉效果。具体操作时,可将`<section>`标记设定为Flex容器,通过`display: flex;`属性,并运用`justify-content`和`align-items`属性调整子元素的对...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值