首页 > 其他分享 >浅析vue3中如何使用动态组件、如何快速理解Vue3的 toRaw和markRaw、ref与shallowRef、shallowReactive 区别

浅析vue3中如何使用动态组件、如何快速理解Vue3的 toRaw和markRaw、ref与shallowRef、shallowReactive 区别

时间:2023-07-17 22:13:27浏览次数:32  
标签:对象 视图 响应 Vue3 markRaw shallowRef data 浅析

一、Vue3中使用 component :is 加载动态组件

1、不使用setup语法糖,这种方式和vue2差不多,is可以是个字符串

2、使用setup语法糖,这时候的is如果使用字符串就会加载不出来,得使用组件实例

<component class="task-box" :is="componentObj[route.params.type]" :info="taskInfo"></component>

import DeliverDetailTeach from './components/DeliverDetailTeach.vue'
// ...
const componentObj = {
    1: markRaw(DeliverDetailTeach),
    2: markRaw(DeliverDetailLive),
}

3、问题:为什么 vue3 需要对引入的组件使用 markRow?

  vue2中 is 是通过组件名称切换的,vue3中setup是通过组件实例切换的。直接把组件实例放到 reactive 中代理,vue会发出警告。告知我们可以通过 shallowRef 或者 markRaw 跳过proxy 代理。对组件实例进行响应式代理毫无意义,且浪费性能。

markRow:标记一个对象,使其不能成为一个响应式对象。
toRaw:将响应式对象(由 reactive 定义的响应式)转换为普通对象
shallowRef:只处理基本数据类型的响应式, 不进行对象的响应式处理
shallowReactive:只处理对象最外层属性的响应式(浅响应式)

二、toRaw和markRaw

1、raw 的意思

  • raw就是原始的意思
  • toRaw 就是把一个响应式对象转化为普通对象
  • markRaw 就是把某个数据,标记为普通对象,当我们把它放到响应式对象中,也依然是非响应式的

2、toRaw 的作用是什么

  • 将一个用reactive生成的响应式对象,变成非响应式的普通对象
  • 然后赋值给新的变量
  • 注意:不影响原来的对象

3、toRaw 的使用场景是什么

  • 用于读取响应式对象中的普通对象
  • 对这个对象的所有操作,都不会引起页面更新

4、为什么需要用到 markRaw

(1)有些值不应被设置为响应式的,例如复杂的第三方库

  • 比如一个响应式对象中,要放入axios,或者别的随机数字的第三方库
  • 如果不让他变成非响应式的,那么Vue就会去找到每一个层级,让其都能响应式处理
  • 这样的情况下,性能就会受到严重影响
  • 所以我们需要让其变成永远都不会成功响应式的数据,提高性能

(2)当渲染具有不可变数据源的大列表时,跳过响应式可以提高性能

5、对谁使用markRaw?

  这个数据原本不能是响应式的;然后把这个数据放到响应式对象当中,这个属性依然不是响应式的

三、ref与shallowRef区别

1、ref 很容易理解,使用ref创建的对象,里面任意深度的属性与视图都是响应性的

2、shallowRef

  先说说shallowRef的特点:与ref不同,shallowRef修改深层属性时,并不会更新视图

<template>
    <div>
        <p>{{data.foo}}</p>
        <button @click="update">update</button>
        <button @click="log">log</button>
    </div>
</template>

setup() {
    const data = shallowRef({
        foo: '1'
    })
    function update() {
        data.value.foo = '2'
    }
    function log() {
        console.log(data.value.foo)
    }
    return {
        data,
    }
}

  上例点击update时,视图并不会更新,但是点击log按钮时,打印出foo的值为2。想要更新视图,必须给value赋值,直接替换整个对象。修改update方法

function update() {
    data.value = { foo: 200 }
}

  再次点击update按钮,视图更新。

  shalow即浅的意思,shallowRef 只有整个数据变更时才刷新视图,或者在修改了数据之后,调用triggerRef方法,主动触发视图刷新

function update() {
    data.value.foo = '300';
    triggerRef(data);    // 触发视图刷新
}

3、为什么要使用shallowRef

  因为ref方法会递归遍历对象的所有属性,使所有属性都具备响应性,所以,当对象很复杂且庞大时,过多的监听会导致性能上的损耗。如假设有一个文章列表数组:

list = [
    { title: '', auto: '', time: '' },
    { title: '', auto: '', time: '' },
    { title: '', auto: '', time: '' },
    //...
]

  像这种做展示用的数据,并不需要每个属性都做响应性,此时使用shallowRef就很合适。

4、shallowReactive 与 shallowRef

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

  shallowRef:只处理基本数据类型的响应式,不进行对象的响应式处理

5、什么时候使用?

(1)如果有一个对象数据,结构比较深,但变化时只是外层属性变化  >  使用shallowReactive

  我们修改数据只有定义在对象第一层的属性才是响应式的,深层次的数据将不再具有响应式的功能,因为深层次的数据将不再是一个响应式对象,而是一给普通对象(数据变了,但是vue监测不到,是无法触发页面更新的)

(2)如果有一个对象数据,后续功能不会修改该对象中的属性,而是生新的对象来替换  >  shallowRef

  我们调用了shallowRef方法传递了基本数据类型,我们可以看到,当前属性是有响应式的。当我们点击修改数据,在页面中可以看到是有响应式功能的

  但是当传递的是一个对象的时候,我们可以看到,传递的对象将变成一个普通对象,不再具有响应式功能了。修改对象的属性数据后将不在触发页面的更新,因为vue监测不到了。只有全量替换对象的值才能触发响应式更新。

标签:对象,视图,响应,Vue3,markRaw,shallowRef,data,浅析
From: https://www.cnblogs.com/goloving/p/17561344.html

相关文章

  • 保姆级教程:手把手教你搭建vue3+vite+pinia项目,直接上手开发
    虽然代码很机械的就写出来了,但是搭建项目却总是很生疏会忘记呢(毕竟一个项目做n年。。)第一步:npmcreateviteprojectName(你的项目名)第二步,:选择Vue第三步:选择想要用的语言,这里我选了javascript第四步:切换到对应项目目录,npminstall下载当前所需依赖 经过上面四步,一个最简......
  • Vue3 遍历显示Json数组
    在Vue项目中遍历显示Json数组以列表的形式显示的页面上 main.js全局json对象//全局jsonconstglobalData=reactive({extTelTalkData:[{userExten:"1000",userName:"刘亦菲",callStatus:"通话"},......
  • vue3 provide/inject使用
    provide/inject可解决深层组件传值问题父组件import{provide}from"vue";constcurValue=ref(props.modelValue);provide('curTabName',curValue);子组件import{inject}from"vue";constcurTabName=inject("curTabName&quo......
  • vue3axios怎么用
    Vue3中使用axios在Vue3中,可以使用axios来进行网络请求。axios是一个基于Promise的HTTP客户端,可以用于浏览器和Node.js,非常便捷和强大。安装axios在开始之前,首先需要安装axios。可以通过npm或者yarn来安装:npminstallaxios引入axios在Vue3中,可以使用import来引入axios:impor......
  • vue3axiosjwt拦截器
    实现Vue3axiosjwt拦截器介绍在Vue3项目中使用axios进行网络请求时,我们经常需要在每次请求中添加JWT令牌(JSONWebToken)以进行身份验证。为了简化这个过程,我们可以使用axios的拦截器来实现自动添加JWT令牌的功能。本文将指导你如何使用Vue3、axios和JWT来实现拦截器。整体流程......
  • 浅析建造者模式
    0.前言建造者模式是创建型设计模式的一种。本篇文章将介绍什么是建造者模式,以及什么时候用建造者模式,同时给出Kubernetes:kubectl中类似建造者模式的示例以加深理解。1.建造者模式1.1从工厂函数说起试想构建房子类,其属性如下:typehousestruct{ windowint door......
  • vue3 封装api接口
    新建axiosj.tsimportaxiosfrom'axios';import{showMessage}from"./status";//引入状态码文件import{ElMessage}from'element-plus'//引入el提示框,这个项目里用什么组件库这里引什么//设置接口超时时间axios.defaults.timeout=60000;//请求地址,......
  • vue3 为什么使用 hooks?
    目的为了解决在组件中共享逻辑和状态的问题。 hooks提供了一种更简洁和直观的方式来共享逻辑和状态。vue3中的hooks是基于函数的组件模型,通过在函数组件内部使用特定的hook函数来实现。每个hook函数都有特定的用途,例如:useState用于创建和管理状态,useEffect用于......
  • SpringBoot+Vue3+MySQL集群 开发健康体检双系统
    第1章课程介绍试看4节|38分钟观看项目演示,熟悉大健康体检项目主要功能。掌握学习本课程的最佳方法,以及如何利用在线手册学习和答疑。第2章大健康体检项目全栈环境搭建16节|218分钟利用虚拟机或者云主机安装Linux系统和Docker环境,部署MongoDB、Redis、Minio和RabbitMQ等中......
  • Vue2或Vue3中实现页面锚点滚动(结合AntDesign a-steps
    核心代码 onStepChange(current){ this.current=current; document.querySelector(`[id='${current}']`).scrollIntoView({ behavior:"smooth",//定义过渡动画instant立刻跳过去smooth平滑过渡过去 block:"start",//定义垂直滚动方向的对齐start顶部(......