Vue3響應(yīng)式原理分析(Proxy(obj,{get(){},set(){}}))
Vue3原理:首先是get方法分析,再者set方法分析,最后雙向數(shù)據(jù)綁定,層層漸進(jìn)到掌握,以及與Vue2的區(qū)別,話不多說(shuō),直接上代碼分析。
1、Proxy響應(yīng)式的get方法
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
let obj = {
name:"Vue",
age:8
}
// Proxy 代理 new Proxy()創(chuàng)建一個(gè)代理對(duì)象
// new Proxy(要代理的這個(gè)對(duì)象,{get(),set()})
let obj2 = new Proxy(obj,{
get(target,property){
// 什么時(shí)候執(zhí)行? 當(dāng)我們?cè)L問(wèn) obj2 的某個(gè)屬性的時(shí)候
// target和 property 表示什么?
// target 是這個(gè)obj對(duì)象 ,property就是我們?cè)L問(wèn)的這個(gè)屬性
console.log("執(zhí)行了get",target,property);
return target[property]
}
})
console.log(obj2.age);
console.log(obj2.name);
// obj2 是一個(gè)代理對(duì)象,屬性和值的obj一樣
</script>
</head>
<body>
</body>
</html>執(zhí)行效果

2、Proxy響應(yīng)式的set方法
<script>
let obj = {
name:"Vue",
age:8
}
// Proxy 代理 new Proxy()創(chuàng)建一個(gè)代理對(duì)象
// new Proxy(要代理的這個(gè)對(duì)象,{get(),set()})
let obj2 = new Proxy(obj,{
get(target,property){
// 什么時(shí)候執(zhí)行? 當(dāng)我們?cè)L問(wèn) obj2 的某個(gè)屬性的時(shí)候
// target和 property 表示什么?
// target 是這個(gè)obj對(duì)象 ,property就是我們?cè)L問(wèn)的這個(gè)屬性
console.log("執(zhí)行了get",target,property);
return target[property]
},
set(target,property,newVal){
// 數(shù)據(jù)劫持的時(shí)候 執(zhí)行這里的代碼 newVal就是 boj2.age = 9 =號(hào) 后面的這個(gè)值
console.log("執(zhí)行了set",target,property,newVal);
// 在這里進(jìn)行修改這個(gè)屬性成為新的值,下次訪問(wèn),才能拿到新值
target[property] = newVal
}
})
obj2.age = 9; //修改值 觸發(fā)執(zhí)行了set
console.log(obj2.age)
/*
自己總結(jié):
1:obj2.age = 9; //修改值 觸發(fā)執(zhí)行了set 就會(huì)執(zhí)行set里面的console.log newVal=9 但是實(shí)際return是8沒(méi)有改到
2:在set里面修改值 才會(huì)變 才真正改了
*/
</script>效果圖:

3、雙向數(shù)據(jù)綁定
<body>
<input type="text" id="ipt">
<p id="op"></p>
<script>
let obj = {
txtVal : "初始值"
}
function myReactive(obj){
return new Proxy(obj,{
get(target,property){
return target[property]
},
set(target,property,newVal){
// 對(duì)象劫持 數(shù)據(jù)劫持
ipt.value = newVal
op.innerHTML = newVal
target[property] = newVal
}
})
}
let objRet = myReactive(obj);
// 綁定初始值
ipt.value = objRet.txtVal;
op.innerHTML = objRet.txtVal
ipt.addEventListener("input",e=>{
objRet.txtVal = e.target.value //觸發(fā)了set
})
</script>
</body>效果圖:

4、Vue2和Vue3set的區(qū)別
Vue3的set修改值
<script>
let obj = [10,20,30]
let obj2 = new Proxy(obj,{
get(target,property){
console.log("執(zhí)行了get",target,property);
return target[property]
},
set(target,property,newVal){
console.log("執(zhí)行了set",target,property,newVal);
}
})
obj2[0] = 1000
/*
對(duì)比:
Vue2 將初始值改為數(shù)組,在下面就修改不了了 而且觸發(fā)不了set
Vue3 就可以
*/
</script>如圖:

Vue2的set修改值(修改不了)
<body>
<input type="text" id="oipt">
<p id="op"></p>
<script>
let obj = {};
// let val = "默認(rèn)值";
let = [10,20,30]
Object.defineProperty(obj,"iptVal",{
get(){
return val;
},
set(newVal){
oipt.value =newVal
op.innerHTML = newVal
// val = newVal
}
})
// 設(shè)置初始值
oipt.value = obj.iptVal;
op.innerHTML = obj.iptVal;
oipt.addEventListener("keyup",function(e){
// 發(fā)布者,影響訂閱者的
obj.iptVal[0] = e.target.value //觸發(fā)了set
})
</script>
</body>效果圖:set 就修改不到

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue3組合式api實(shí)現(xiàn)v-lazy圖片懶加載的方法實(shí)例
vue作為前端主流的3大框架之一,目前在國(guó)內(nèi)有著非常廣泛的應(yīng)用,下面這篇文章主要給大家介紹了關(guān)于vue3組合式api實(shí)現(xiàn)v-lazy圖片懶加載的相關(guān)資料,需要的朋友可以參考下2022-09-09
Vue實(shí)現(xiàn)首頁(yè)banner自動(dòng)輪播效果
這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)首頁(yè)banner自動(dòng)輪播效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
vue項(xiàng)目使用electron-builder庫(kù)打包成桌面程序的過(guò)程
這篇文章主要介紹了vue項(xiàng)目使用electron-builder庫(kù)打包成桌面程序的過(guò)程,本文給大家介紹如何使用electron-builder這個(gè)庫(kù)結(jié)合實(shí)例代碼給大家講解的非常詳細(xì),感興趣的朋友一起看看吧2024-02-02
vue3實(shí)現(xiàn)鼠標(biāo)右鍵顯示菜單,點(diǎn)擊其他地方消失問(wèn)題
這篇文章主要介紹了vue3實(shí)現(xiàn)鼠標(biāo)右鍵顯示菜單,點(diǎn)擊其他地方消失問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
利用vue+turn.js實(shí)現(xiàn)翻書(shū)效果完整實(shí)例
這篇文章主要給大家介紹了關(guān)于利用vue+turn.js實(shí)現(xiàn)翻書(shū)效果的相關(guān)資料,turn.js是使用了jquery書(shū)寫的,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
解決vue-router進(jìn)行build無(wú)法正常顯示路由頁(yè)面的問(wèn)題
下面小編就為大家分享一篇解決vue-router進(jìn)行build無(wú)法正常顯示路由頁(yè)面的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-03-03
Vue項(xiàng)目pdf(base64)轉(zhuǎn)圖片遇到的問(wèn)題及解決方法
這篇文章主要介紹了Vue項(xiàng)目pdf(base64)轉(zhuǎn)圖片遇到的問(wèn)題及解決方法,需要的朋友可以參考下2018-10-10
Vue通過(guò)WebSocket建立長(zhǎng)連接的實(shí)現(xiàn)代碼
這篇文章主要介紹了Vue通過(guò)WebSocket建立長(zhǎng)連接的實(shí)現(xiàn)代碼,文中給出了問(wèn)題及解決方案,需要的朋友可以參考下2019-11-11
vue 中directive功能的簡(jiǎn)單實(shí)現(xiàn)
本篇介紹directive的簡(jiǎn)單實(shí)現(xiàn),主要學(xué)習(xí)其實(shí)現(xiàn)的思路及代碼的設(shè)計(jì),需要的朋友參考下吧2018-01-01

