vue3与react、 react hooks

一、Vue3新特性:setup、ref、reactive、computed、watch、watchEffect函数、生命周期钩子、自定义hooks函数、toRef和toRefs、shallowReactive 与 shallowRef、readonly 与 shallowReadonly、toRaw 与 markRaw、customRef、provide 与 inject、Fragment、Teleport、Suspense、data选项应始终被声明为一个函数

2、setup是所有composition  API(组合式api)展示的舞台, 返回一个对象,则对象中的属性、方法, 在模板中均可以直接使用,setUp(props, contex)接受两个参数,props:值为对象,包含:组件外部传递过来,且组件内部声明接收了的属性(其实就是vue2.0的props功能),context:上下文对象(其中可以获取到1、attrs组件外部传递过来,但没有在props配置中声明的属性。2、slots:插槽内容3、emit:分发自定义事件的函数,并且以后在setup中不能写this.$emit,要写context.emit)

3、ref一般用来定义一个基本类型的响应式数据, reactive定义一个响应式源对象,接收一个普通对象然后返回该普通对象的响应式代理器对象,响应式转换是“深层的”:会影响对象内部所有嵌套的属性,内部基于 ES6 的 Proxy 实现,通过代理对象操作源对象内部数据都是响应式的;watch默认是惰性的,watchEffect默认立即执行;watch可以获取到当前值和之前值,watchEffect只能获取当前值;watch可以传递多个函数作为参数,watchEffect只需要传递一个回调函数

4、

(1)、vue2响应式原理:

核心:

对象: 通过defineProperty对对象的已有属性值的读取和修改进行劫持(监视/拦截)

数组: 通过重写数组更新数组一系列更新元素的方法来实现元素修改的劫持

(2)、Vue3的响应式原理:

核心:

通过Proxy(代理):拦截对data任意属性的任意(13种)操作, 包括属性值的读写, 属性的添加, 属性的删除等…

通过 Reflect(反射): 动态对被代理对象的相应属性进行特定的操作

5、生命周期:

为什么要在生命周期前加"on"?

因为setup是围绕beforeCreate和created生命周期来运行的,所以不需要显式地定义它们,这些生命周期函数接受一个回调函数,当钩子被组件调用时将会被执行。

beforeCreate -> 使用 setup()

created -> 使用 setup()

beforeMount -> onBeforeMount

mounted -> onMounted

beforeUpdate -> onBeforeUpdate

updated -> onUpdated

beforeDestroy -> onBeforeUnmount

destroyed -> onUnmounted

errorCaptured -> onErrorCaptured

1.vue3中已经没有destroyed 和beforeDestroy 了

2.vue3也可以用vue2的生命周期,vue3生命周期比vue2快

6、自定义hook函数

什么是hook? ----本质是一个函数,把setup函数中使用的composition API进行了封装

类似于vue2中的mixin

自定义hook的优势:复用代码,让setup中的逻辑更清晰易懂

(1)、基础封装hooks

//定义的hooks

import {reactive,onMounted,onBeforeUnmount} from 'vue'

export default function(){

    let point=reactive(

        {

            x:0,

            y:0

        }

    )

    function sponk(event){

        console.log(point);

        point.x=event.pageX;

        point.y=event.pageY;

        console.log(event);

    }

    onMounted(()=>{

        console.log('onMounted');

        document.getElementById('HelloWorld').addEventListener('click',sponk)

    })

    onBeforeUnmount(()=>{

        console.log('onBeforeUnmount');

        document.getElementById('HelloWorld').removeEventListener('click',sponk)

    })

    return point;

}

//使用hooks的组件

<template>

  <div class="hello" id="HelloWorld">

    x轴位置:{{valz.x}}<br/>

    y轴位置:{{valz.y}}<br/>

  </div>

</template>

<script>

  //引入定义的hooks

  import point from './../hook/commonFirst'

  export default {

    name: 'HelloWorld',

    props: {

      msg: String

    },

    setup(){

      console.log('---setup---');

      //触发执行此方法即可

      let valz=point()

      return{

        valz

      }

    },

}

</script>

(2)、 封装发 axios 请求的 hook 函数

hooks/useRequest.ts

import { ref } from 'vue'

import axios from 'axios'

/*

使用axios发送异步ajax请求

*/

export default function useUrlLoader<T>(url: string) {

  const result = ref<T | null>(null)

  const loading = ref(true)

  const errorMsg = ref(null)

  axios

    .get(url)

    .then(response => {

      loading.value = false

      result.value = response.data

    })

    .catch(e => {

      loading.value = false

      errorMsg.value = e.message || '未知错误'

    })

  return {

    loading,

    result,

    errorMsg

  }

}

<template>

  <div class="about">

    <h2 v-if="loading">LOADING...</h2>

    <h2 v-else-if="errorMsg">{{ errorMsg }}</h2>

    <!-- <ul v-else>

    <li>id: {{result.id}}</li>

    <li>name: {{result.name}}</li>

    <li>distance: {{result.distance}}</li>

  </ul> -->

    <ul v-for="p in result" :key="p.id">

      <li>id: {{ p.id }}</li>

      <li>title: {{ p.title }}</li>

      <li>price: {{ p.price }}</li>

    </ul>

    <!-- <img v-if="result" :src="result[0].url" alt=""> -->

  </div>

</template>

<script lang="ts">

import { watch } from 'vue'

import useRequest from './hooks/useRequest'

// 地址数据接口

interface AddressResult {

  id: number

  name: string

  distance: string

}

// 产品数据接口

interface ProductResult {

  id: string

  title: string

  price: number

}

export default {

  setup() {

    // const {loading, result, errorMsg} = useRequest<AddressResult>('/data/address.json')

    const { loading, result, errorMsg } = useRequest<ProductResult[]>('/data/products.json')

    watch(result, () => {

      if (result.value) {

        console.log(result.value.length) // 有提示

      }

    })

    return {

      loading,

      result,

      errorMsg

    }

  }

}

</script>

其他可以查看从0到1学vue3_山竹回家了的博客-CSDN博客_vue3


下面写一下vue3、react hooks原理及其区别

vue3 带来的六大新特性

Performance:性能比vue2.x块1.2~2倍

Tree shaking support:支持按需编译,体积更小

Composition API:组合API,类似React Hooks

Custom Renderer API:暴露了自定义渲染API

Fragment,Teleport(Protal),Suspense:新增三个组件

Better TypeScript support:更好的支持TS

Performance

Vue3.0在性能方面比Vue2.x快了1.2~2倍。

重写虚拟DOM的实现

运行时编译

静态提升与事件侦听器缓存

SSR 速度提高

Three-shaking support

Vue3.x中的核心API都支持tree-shaking,这些API都是通过包引入的方式而不是直接在实例化时就注入,只会对使用到的功能或特性进行打包(按需打包),这意味着更多的功能和更小的体积。

Composition API

Vue2.x中,我们通常采用mixin来复用逻辑代码,使用起来虽然方便,但也存在一些问题:代码来源不清晰、方法属性可能出现冲突。因此,Vue3.x引入了Composition API(组合API),使用纯函数分割复用代码。和React Hooks的概念相似。

更好的逻辑复用和代码组织

更好的类型推导

Fragment、Teleport、Suspense

新增三个组件。

Fragment

在书写Vue2.x时,由于组件必须是一个根结点,很多时候会添加一些没有意义的节点用于包裹。Fragment组件就是用于解决这个问题的(这和React 中的Fragment组件是一样的)。

Teleport

Teleport其实就是React中的Portal。Portal 提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀的方案。

一个 portal 的典型用例是当父组件有 overflow: hidden 或 z-index 样式时,但你需要子组件能够在视觉上“跳出”其容器。例如,对话框、悬浮卡以及提示框。

Suspense

同样的,这和React中的Supense是一样的。

Suspense 让你的组件在渲染之前进行“等待”,并在等待时显示 fallback 的内容。

Vue3.0 是如何变快的

diff 算法优化

Vue2 中的虚拟dom 是进行全量对比

Vue3 新增静态标记,这和react的fiber类似,都是打tag

hoistStatic 静态提升

Vue2 中无论元素是否参与更新,每次都会重新创建,然后在渲染

Vue3 中对于不参与更新的元素,会做静态提升,只被创建一次,在渲染时直接复用即可

cacheHandlers 事件侦听器缓存

默认情况下默认情况下onClick会被视为动态绑定,所以每次都会去追踪它的变化,但是因为是同一个函数,所以没有追踪变化,直接缓存起来复用即可

ssr 渲染

当有大量静态的内容的时候,这些内容会被当作纯字符串推进一个buffer里面,即使存在动态的绑定,会通过模版插值嵌入进去,这样会比通过虚拟dom来渲染的快上很多很多

当静态内容大到一定量级的时候,会用_createStaticVNode方法在客户端去生成一个static node。这些静态node,会被直接innerHtml,就不需要创建对象,然后根据对象渲染。

vue3底层设计思想:

1.浏览器性能提升

  首先,随着ES6的发展已及广泛使用,浏览器对这些新的特性逐渐增加,性能不断优化,这就给vue3优化提供了一个机会,通过重写来优化提升vue的性能。

2、底层实现方法

在框架设计上,vue2.0 是采用Object.defineProperty来实现双向绑定原理,这个属性本身就存在一些不足的地方,比如:

1.Object.defineProperty无法监控到数组下标的变化,导致直接通过数组的下标给数组设置值,不能实时响应。 为了解决这个问题,经过vue内部处理后可以使用以下几种方法来监听数组,push(),pop(),shift(),unshift(),splice(),sort(),reverse();由于只针对了以上八种方法进行了hack处理,所以其他数组的属性也是检测不到的,还是具有一定的局限性。

  2.Object.defineProperty只能劫持对象的属性,因此我们需要对每个对象的每个属性进行遍历。Vue 2.x里,是通过 递归 + 遍历 data 对象来实现对数据的监控的,如果属性值也是对象那么需要深度遍历,显然如果能劫持一个完整的对象是才是更好的选择,新增的属性还行通过set方法来添加监听,有一定的局限性。

  vue3主要采用的Proxy特性,有以下优点:

  1.可以劫持整个对象,并返回一个新的对象

  2.有13种劫持操作,但同时Proxy作为ES6的新特性,有一定的兼容问题,最主要的是这个属性无法用polyfill来兼容,这个需要在vue3中需要解决的问题。

React原理分析:

实现和更新原理

React将每个节点转化为fiber对象,最终形成一个fiber树结构,来依次渲染。通过两个fiber的对比来实现更新。这里要说到几个diff算法,分别是tree diff,component diff和element diff。同时更新过程可能会被打断,让优先级更高的任务优先执行(例如浏览器渲染)

Tree diff

新旧两个DOM树,逐层对比的过程;当整个DOM树逐层对比完毕,则所有需要被更新的元素必然能被找到;

Component diff

在进行Tree Diff的时候,每一层中,组件级别的对比。如果对比前后,组件的类型相同,则暂时认为此组件不需要被更新;如果对比前后,组件类型不同,则需要移除旧组件,创建新组件,并追加到页面上;

Element diff

在进行组件对比的时候,如果两个组件类型相同,则需要进行元素级别的对比,叫做element diff;

React 原理分析(一) —— React 设计思想 - 掘金 (juejin.cn)

React 源码分析(二)—— Fiber 的 render 阶段 - 掘金 (juejin.cn)

React 原理分析(三)—— Fiber 的commit 阶段 - 掘金 (juejin.cn)

vue与react的区别:

1、Vue和React存在着很多的共同点:

数据驱动视图

组件化

都使用Virtual DOM

2、核心思想不同

vue的主要特点:灵活易用的渐进式框架,进行数据拦截/代理,它对侦测数据的变化更敏感、更精确。

Reactt推崇函数式编程(纯组件),数据不可变以及单向数据流,当然需要双向的地方也可以手动实现, 比如借助onChange和setState来实现。

由于两者核心思想的不同,所以导致Vue和React在后续设计产生了许多的差异。

3、组件写法差异

Vue 推荐的做法是 template 的单文件组件格式(简单易懂,从传统前端转过来易于理解),即 html,css,JS 写在同一个文件(vue也支持JSX写法)

React推荐的做法是JSX + inline style, 也就是把 HTML 和 CSS 全都写进 JavaScript 中,即 all in js

这个差异一定程度上也是由于二者核心思想不同而导致的。

4.、响应式原理不同

Vue依赖收集,自动优化,数据可变。Vue递归监听data的所有属性,直接修改。当数据改变时,自动找到引用组件重新渲染。

React基于状态机,手动优化,数据不可变,需要setState驱动新的state替换老的state。当数据改变时,以组件为根目录,默认全部重新渲染, 所以 React 中会需要 shouldComponentUpdate 这个生命周期函数方法来进行控制




vue3.2中的defineProps、defineEmits、defineExpose,方便使用

vue3.2中的defineProps、defineEmits、defineExpose - 简书 (jianshu.com)

最后编辑于:2025-02-24 21:39:25


喜欢的朋友记得点赞、收藏、关注哦!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/897048.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《基于WebGPU的下一代科学可视化——告别WebGL性能桎梏》

引言&#xff1a;科学可视化的算力革命 当WebGL在2011年首次亮相时&#xff0c;它开启了浏览器端3D渲染的新纪元。然而面对当今十亿级粒子模拟、实时物理仿真和深度学习可视化需求&#xff0c;WebGL的架构瓶颈日益凸显。WebGPU作为下一代Web图形标准&#xff0c;通过显存直存、…

宠物医疗对接DeepSeek详细方案

基于DeepSeek本地化部署技术与医疗场景优化实践 一、核心架构设计 1. 本地化部署与数据安全 私有化服务器部署:将DeepSeek模型部署在宠物医院本地服务器,所有诊疗数据(如宠物病历、影像报告)均存储于院内,避免云端传输风险数据加密机制:采用AES-256加密算法对医疗数据加…

K8s 1.27.1 实战系列(一)准备工作

一、主机规划与硬件要求 1、节点数量 至少需要 3 台服务器(1 台 Master 节点,2 台 Worker 节点)。本地测试可缩容:若仅用于测试,可缩减为 1 个 Master 和 1 个 Worker,但需注意稳定性风险。2、硬件配置 ​Master 节点:建议 2 核 CPU、8GB 内存、80GB 硬盘。​Worker 节…

2.PSCAD是什么软件?

PSCAD&#xff08;Power Systems Computer Aided Design&#xff09;是一款功能强大的电力系统仿真软件&#xff0c;广泛应用于电力系统的建模、仿真和分析。它结合了电磁暂态仿真引擎EMTDC&#xff08;Electromagnetic Transients including DC&#xff09;&#xff0c;能够精…

Stable Diffusion模型Pony系列模型深度解析

Stable Diffusion模型Pony系列模型深度解析 一、技术架构与核心特性 基于SDXL的深度优化 Pony系列模型以SDXL为基础框架&#xff0c;通过针对二次元/动漫风格的微调&#xff0c;强化了在该领域的生成能力&#xff0c;同时保留了对写实场景的兼容性‌。其训练数据特别侧重于人…

FastGPT 引申:混合检索完整实例

文章目录 FastGPT 引申&#xff1a;混合检索完整实例1. 各检索方式的初始结果2. RRF合并过程3. 合并后的结果4. Rerank重排序后5. 最终RRF合并6. 内容总结 FastGPT 引申&#xff1a;混合检索完整实例 下边通过一个简单的例子说明不同检索方式的分值变化过程&#xff0c;假设我…

在MATLAB环境中,对矩阵拼接(Matrix Concatenation)的测试

在MATLAB环境中&#xff0c;对矩阵拼接&#xff08;Matrix Concatenation&#xff09;的正确性与鲁棒性开展测试时&#xff0c;需要依据不同的拼接场景精心设计测试用例&#xff0c;全面验证矩阵维度、数据顺序、边界条件以及异常处理等关键方面。以下是详尽的测试方法与具体示…

OpenFeign 学习笔记

OpenFeign 学习笔记 一、基础入门 1.1 简介 OpenFeign 是基于声明式的 REST 客户端&#xff0c;用于简化服务间远程调用。&#xff08;编程式 REST 客户端&#xff08;RestTemplate&#xff09;&#xff09; 通过接口注解方式定义 HTTP 请求&#xff0c;自动实现服务调用。 …

“沂路畅通”便利服务平台:赋能同城物流,构建高效畅通的货运生态

“沂路畅通”便利服务平台&#xff1a;赋能同城物流&#xff0c;构建高效畅通的货运生态 随着城市化进程的加速&#xff0c;同城物流需求迅速增长&#xff0c;然而货运过程中仍然存在信息不对称、资源浪费、司机服务体验差等痛点。临沂呆马区块链网络科技有限公司&#xff08;…

去除HTML有序列表(ol)编号的多种解决方案

以下是去除HTML有序列表(ol)编号的多种解决方案&#xff1a; <!DOCTYPE html> <html> <head> <style> /* 基础方案&#xff1a;完全移除编号 */ ol.no-number {list-style-type: none; /* 移除默认编号 */padding-left: 0; /* 移除默认缩进 */…

es如何进行refresh?

在 Elasticsearch 中,refresh 操作的作用是让最近写入的数据可以被搜索到。以下为你介绍几种常见的执行 refresh 操作的方式: 1. 使用 RESTful API 手动刷新 你可以通过向 Elasticsearch 发送 HTTP 请求来手动触发 refresh 操作。可以针对单个索引、多个索引或者所有索引进…

Leetcode 57: 插入区间

Leetcode 57: 插入区间 问题描述&#xff1a; 给定一个非重叠的区间集合 intervals&#xff08;按开始时间升序排列&#xff09;和一个新的区间 newInterval&#xff0c;将新的区间插入到区间集合中并合并重叠的部分&#xff0c;最后返回结果区间集合。 适合面试的解法&#x…

爬虫面试:关于爬虫破解验证码的13个经典面试题

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 1. ​什么是验证码(CAPTCHA)?它的作用是什么?2. ​常见的验证码类型有哪些?3. ​在爬虫开发中,遇到验证码时通常有哪些解决方案?4. ​如何使用第三方验证码识别服务?请举例说明。5. ​训练自己的验证码识别模型…

Kylin麒麟操作系统服务部署 | NFS服务部署

以下所使用的环境为&#xff1a; 虚拟化软件&#xff1a;VMware Workstation 17 Pro 麒麟系统版本&#xff1a;Kylin-Server-V10-SP3-2403-Release-20240426-x86_64 一、 NFS服务概述 NFS&#xff08;Network File System&#xff09;&#xff0c;即网络文件系统。是一种使用于…

三参数水质在线分析仪:从源头保障饮用水安全

【TH-ZS03】饮用水安全是人类健康的重要保障&#xff0c;其质量直接关系到人们的生命健康。随着工业化、城市化的快速发展&#xff0c;水体污染问题日益严峻&#xff0c;饮用水安全面临着前所未有的挑战。为了从源头保障饮用水安全&#xff0c;科学、高效的水质监测手段必不可少…

PGlite:浏览器中运行的PostgreSQL

PGlite 是一款基于 WebAssembly&#xff08;WASM&#xff09;构建的轻量级 PostgreSQL 数据库引擎&#xff0c;旨在简化开发者在浏览器、Node.js、Bun 或 Deno 环境中运行 PostgreSQL。PGlite 无需复杂的安装或配置&#xff0c;特别适合开发测试、本地化应用及快速原型设计。 一…

【Spring AOP】_使用注解编写AOP程序

目录 1. 以增加方法执行时间为例使用AOP 1.1 引入AOP依赖 1.2 编写AOP程序 2. AOP的重要概念 3. AOP通知类型与通知方法标注 3.1 在通知方法前使用对应注解 3.2 使用Pointcut注解提取公共切点表达式 3.3 跨类使用切点 3.4 切面类排序 1. 以增加方法执行时间为例使用AO…

C# iText 抽取PDF页特定区域文本内容

开发中需要提取PDF文件某页某区域内的特定文本内容&#xff0c;对于文字转换而成的PDF文件&#xff0c;可以使用iText库&#xff0c;通过Rectangle划定PDF页中特定区域提取文字&#xff0c;思路是将这个Rectangle框定区域放到TextRegionEventFilter过滤器中&#xff0c;代码如下…

Java 关键字 volatile

volatile 是 Java 中的一个关键字&#xff0c;用于修饰变量&#xff0c;确保多线程环境下的可见性和有序性。它主要用于解决以下两个问题&#xff1a; 可见性问题&#xff1a;一个线程对 volatile 变量的修改对其他线程立即可见。有序性问题&#xff1a;禁止指令重排序&#x…

python网络爬虫开发实战之基本库使用

目录 第二章 基本库的使用 2.1 urllib的使用 1 发送请求 2 处理异常 3 解析链接 4 分析Robots协议 2.2 requests的使用 1 准备工作 2 实例引入 3 GET请求 4 POST请求 5 响应 6 高级用法 2.3 正则表达式 1 实例引入 2 match 3 search 4 findall 5 sub 6 com…