91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Vue3中的響應式機制是什么

發布時間:2022-09-20 09:33:17 來源:億速云 閱讀:149 作者:iii 欄目:編程語言

這篇文章主要介紹“Vue3中的響應式機制是什么”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“Vue3中的響應式機制是什么”文章能幫助大家解決問題。

什么是響應式

響應式一直都是 Vue 的特色功能之一;與之相比,JavaScript 里面的變量,是沒有響應式這個概念的;你在學習 JavaScript 的時候首先被灌輸的概念,就是代碼是自上而下執行的;

我們看下面的代碼,代碼在執行后,打印輸出的兩次 double 的結果也都是 2;即使 我們修改了代碼中 count 的值后,double 的值也不會有任何改變

let count = 1
let double = count * 2
count = 2

double 的值是根據 count 的值乘以二計算而得到的,如果現在我們想讓 doube 能夠跟著 count 的變化而變化,那么我們就需要在每次 count 的值修改后,重新計算 double

比如,在下面的代碼,我們先把計算 doube 的邏輯封裝成函數,然后在修改完 count 之 后,再執行一遍,你就會得到最新的 double 值

let count = 1
// 計算過程封裝成函數
let getDouble = n=>n*2 //箭頭函數
let double = getDouble(count)
count = 2
// 重新計算double ,這里我們不能自動執行對double的計算
double = getDouble(count)

實際開發中的計算邏輯會比計算 doube 復雜的多,但是都可以封裝成一個函數去執行;下 一步,我們要考慮的是,如何讓 double 的值得到自動計算

如果我們能讓 getDouble 函數自動執行,也就是如下圖所示,我們使用 JavaScript 的某種機制,把 count 包裹一層,每當對 count 進行修改時,就去同步更新 double 的值,那 么就有一種 double 自動跟著 count 的變化而變化的感覺,這就算是響應式的雛形了

Vue3中的響應式機制是什么


響應式原理

響應式原理是什么呢?Vue 中用過三種響應式解決方案,分別是 defineProperty、Proxy 和 value setter我們首先來看 Vue 2 的 defineProperty API

這里我結合一個例子來說明,在下面的代碼中,我們定義個一個對象 obj,使用 defineProperty 代理了 count 屬性;這樣我們就對 obj 對象的 value 屬性實現了攔截,讀取 count 屬性的時候執行 get 函數,修改 count 屬性的時候執行 set 函數,并在 set  函數內部重新計算了 double

let getDouble = n=>n*2
let obj = {}
let count = 1
let double = getDouble(count)
Object.defineProperty(obj,'count',{
    get(){
        return count
    },
    set(val){
        count = val
        double = getDouble(val)
    }
})
console.log(double) // 打印2
obj.count = 2
console.log(double) // 打印4 有種自動變化的感覺

這樣我們就實現了簡易的響應式功能,在課程的第四部分,我還會帶著你寫一個更完善的響應式系統

但 defineProperty API 作為 Vue 2 實現響應式的原理,它的語法中也有一些缺陷;比如在下面代碼中,我們刪除 obj.count 屬性,set 函數就不會執行,double 還是之前的數值;這也是為什么在 Vue 2 中,我們需要 $delete 一個專門的函數去刪除數據

delete obj.count
console.log(double) // doube還是4

Vue 3 的響應式機制是基于 Proxy 實現的;就 Proxy 這個名字來說,你也能看出來這是代理的意思,Proxy 的重要意義在于它解決了 Vue 2 響應式的缺陷

我們看下面的代碼,在其中我們通過 new Proxy 代理了 obj 這個對象,然后通過 get、set 和 deleteProperty 函數代理了對象的讀取、修改和刪除操作,從而實現了響應式的功能

let proxy = new Proxy(obj,{
    get : function (target,prop) {
        return target[prop]
    },
    set : function (target,prop,value) {
        target[prop] = value;
        if(prop==='count'){
            double = getDouble(value)
    }
},
deleteProperty(target,prop){
    delete target[prop]
    if(prop==='count'){
        double = NaN
    }
   }
})
console.log(obj.count,double)
proxy.count = 2
console.log(obj.count,double)
delete proxy.count
// 刪除屬性后,我們打印log時,輸出的結果就會是 undefined NaN
console.log(obj.count,double)

我們從這里可以看出 Proxy 實現的功能和 Vue 2 的 definePropery 類似,它們都能夠在用戶修改數據的時候觸發 set 函數,從而實現自動更新 double 的功能。而且 Proxy 還完善了幾個 definePropery 的缺陷,比如說可以監聽到屬性的刪除

Proxy 是針對對象來監聽,而不是針對某個具體屬性,所以不僅可以代理那些定義時不存在的屬性,還可以代理更豐富的數據結構,比如 Map、Set 等,并且我們也能通過 deleteProperty 實現對刪除操作的代理

當然,為了幫助你理解 Proxy,我們還可以把 double 相關的代碼都寫在 set 和 deleteProperty 函數里進行實現,在課程的后半程我會帶你做好更完善的封裝;比如下面代碼中,Vue 3 的 reactive 函數可以把一個對象變成響應式數據,而 reactive 就是基于 Proxy 實現的;我們還可以通過 watchEffect,在 obj.count 修改之后,執行數據的打印

import {reactive,computed,watchEffect} from 'vue'
let obj = reactive({
    count:1
})
let double = computed(()=>obj.count*2)
obj.count = 2
watchEffect(()=>{
    console.log('數據被修改了',obj.count,double.value)
})

有了 Proxy 后,響應式機制就比較完備了;但是在 Vue 3 中還有另一個響應式實現的邏輯,就是利用對象的 get 和 set 函數來進行監聽,這種響應式的實現方式,只能攔截某一個屬性的修改,這也是 Vue 3 中 ref 這個 API 的實現

在下面的代碼中,我們攔截了 count 的 value 屬性,并且攔截了 set 操作,也能實現類似的功能

let getDouble = n => n * 2
let _value = 1

double = getDouble(_value)
let count = {
    get value() {
        return _value
    },
    set value(val) {
        _value = val
        double = getDouble(_value)
    }
}

console.log(count.value,double)
count.value = 2
console.log(count.value,double)

三種實現原理的對比表格如下,幫助你理解三種響應式的區別

實現原理definePropertyProxyvalue setter
實際場景Vue 2 響應式Vue 3 reactiveVue 3 ref
優勢兼容性基于proxy實現真正的攔截實現簡單
劣勢數組和屬性刪除等攔截不了兼容不了 IE11只攔截了 value 屬性
實際應用Vue 2Vue 3 復雜數據結構Vue 3 簡單數據結構

定制響應式數據

簡單入門響應式的原理后,接下來我們學習一下響應式數據在使用的時候的進階方式;我們看下使用 <script setup> 重構之后的 todolist 的代碼;這段代碼使用 watchEffect,數據變化之后會把數據同步到 localStorage 之上,這樣我們就實現了 todolist 和本地存儲的同步

import { ref, watchEffect, computed } from "vue";
let title = ref("");
let todos = ref(JSON.parse(localStorage.getItem('todos')||'[]'));
watchEffect(()=>{
    localStorage.setItem('todos',JSON.stringify(todos.value))
})
function addTodo() {
    todos.value.push({
        title: title.value,
        done: false,
    });
    title.value = "";
}

更進一步,我們可以直接抽離一個 useStorage 函數,在響應式的基礎之上,把任意數據響應式的變化同步到本地存儲;我們先看下面的這段代碼,ref 從本地存儲中獲取數據,封裝成響應式并且返回,watchEffect 中做本地存儲的同步,useStorage 這個函數可以抽離成一個文件,放在工具函數文件夾中

function useStorage(name, value=[]){
    let data = ref(JSON.parse(localStorage.getItem(name)||'[]'))
    watchEffect(()=>{
        localStorage.setItem(name,JSON.stringify(data.value))
    })
    return data
}

在項目中我們使用下面代碼的寫法,把 ref 變成 useStorage,這也是 Composition API 最大的優點,也就是可以任意拆分出獨立的功能

let todos = useStorage('todos',[])
function addTodo() {
    ...code
}

現在,你應該已經學會了在 Vue 內部進階地使用響應式機制,去封裝獨立的函數;在后續的實戰應用中,我們也會經常對通用功能進行封裝;如下圖所示,我們可以把日常開發中用到的數據,無論是瀏覽器的本地存儲,還是網絡數據,都封裝成響應式數據,統一使用響應式數據開發的模式;這樣,我們開發項目的時候,只需要修改對應的數據就可以了

Vue3中的響應式機制是什么

基于響應式的開發模式,我們還可以按照類似的原理,把我們需要修改的數據,都變成響應式;比如,我們可以在 loading 狀態下,去修改瀏覽器的小圖標 favicon;和本地存儲類似,修改 favicon 時,我們需要找到 head 中有 icon 屬性的標簽

在下面的代碼中,我們把對圖標的對應修改的操作封裝成了 useFavicon 函數,并且通過 ref 和 watch 的包裹,我們還把小圖標變成了響應式數據

import {ref,watch} from 'vue'
export default function useFavicon( newIcon ) {
    const favicon = ref(newIcon)
    const updateIcon = (icon) => {
        document.head
        .querySelectorAll(`link[rel*="icon"]`)
        .forEach(el => el.href = `${icon}`)
    }
watch( favicon,
    (i) => {
        updateIcon(i)
    }
)
    return {favicon,reset}
}

這樣在組件中,我們就可以通過響應式的方式去修改和使用小圖標,通過對 faivcon.value 的修改就可以隨時更換網站小圖標;下面的代碼,就實現了在點擊按鈕之后,修改了網頁的圖標為 geek.png 的操作

<script setup>
    import useFavicon from './utils/favicon'
    let {favicon} = useFavicon()
    function loading(){
        favicon.value = '/geek.png'
    }
</script>
<template>
    <button @click="loading">123</button>
</template>

Vueuse 工具包

我們自己封裝的 useStorage,算是把 localStorage 簡單地變成了響應式對象,實現數據的更新和localStorage 的同步;同理,我們還可以封裝更多的類似 useStorage 函數的其他 use 類型的函數,把實際開發中你用到的任何數據或者瀏覽器屬性,都封裝成響應式數據,這樣就可以極大地提高我們的開發效率

Vue 社區中其實已經有一個類似的工具集合,也就是 VueUse,它把開發中常見的屬性都封裝成為響應式函數

VueUse 趁著這一波 Vue 3 的更新,跟上了響應式 API 的潮流;VueUse 的官方的介紹說這是一個 Composition API 的工具集合,適用于 Vue 2.x 或者 Vue 3.x,用起來和 React Hooks 還挺像的

在項目目錄下打開命令行里,我們輸入如下命令,來進行 VueUse 插件的安裝:

npm install @vueuse/core

然后,我們就先來使用一下 VueUse;在下面這段代碼中,我們使用 useFullscreen 來返回全屏的狀態和切換全屏的函數;這樣,我們就不需要考慮瀏覽器全屏的 API,而是直接使用 VueUse 響應式數據和函數就可以很輕松地在項目中實現全屏功能

<template>
    <h2 @click="toggle">click</h2>
</template>
<script setup>
import { useFullscreen } from '@vueuse/core'
const { isFullscreen, enter, exit, toggle } = useFullscreen()
</script>

useFullscreen 的封裝邏輯和 useStorage 類似,都是屏蔽了瀏覽器的操作,把所有我們需要用到的狀態和數據都用響應式的方式統一管理,VueUse 中包含了很多我們常用的工具函數,我們可以把網絡狀態、異步請求的數據、動畫和事件等功能,都看成是響應式的數據去管理。

關于“Vue3中的響應式機制是什么”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长治县| 白水县| 金湖县| 汶上县| 新干县| 博白县| 买车| 梨树县| 屏南县| 丰县| 和顺县| 琼中| 清涧县| 垫江县| 勃利县| 高平市| 道孚县| 光山县| 漳平市| 白河县| 奉贤区| 平度市| 黄龙县| 香河县| 长汀县| 溧水县| 封丘县| 谷城县| 临沭县| 开化县| 江源县| 尚义县| 布尔津县| 柯坪县| 南部县| 营山县| 增城市| 沂水县| 奎屯市| 凤山县| 德安县|