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.pswp.cn/news/897048.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/897048.shtml
英文地址,請注明出處:http://en.pswp.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…