您好,登錄后才能下訂單哦!
這篇文章主要介紹“Vue的核心原理是什么”,在日常操作中,相信很多人在Vue的核心原理是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Vue的核心原理是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!
<script> // 1. 字面量定義 let data = { name: 'aa' } data.name = 'bb' // 這種情況下我們并不能知道name屬性發(fā)生了變化 // 2. Object.defineProperty let data1 = {} Object.defineProperty(data1, 'name', { // 當(dāng)我們?cè)L問(wèn)data1的name屬性的時(shí)候自動(dòng)調(diào)用的方法 // 并且get函數(shù)的返回值就是你拿到的值 get() { console.log('你訪問(wèn)了data1的name屬性') return 'aa' }, // 當(dāng)我們?cè)O(shè)置修改name屬性的時(shí)候自動(dòng)調(diào)用的函數(shù) // 并且屬性最新的值會(huì)被當(dāng)成實(shí)參傳入進(jìn)來(lái) set(newValue) { console.log('你修改了data1的name屬性最新的值為', newValue) // 這個(gè)位置 只要你修改了name屬性就會(huì)得到執(zhí)行 // 所以如果你想要在name變化的時(shí)候 完成一些自己的事情 // 都可以放到這里來(lái)執(zhí)行 // 1. ajax() // 2. 操作一塊dom區(qū)域 } }) // 以上是js中對(duì)象定義的另外一種方案,可以在訪問(wèn)屬性和設(shè)置屬性的時(shí)候自動(dòng)調(diào)用對(duì)應(yīng)的函數(shù) // 訪問(wèn)屬性:data.name data['name'] // 設(shè)置屬性:data.name = 'bb' data['name'] = 'bb' </script>
響應(yīng)式的核心API
<script> // let data = { // name: 'aa' // } let data = {} let _name = 'aa' Object.defineProperty(data, 'name', { get() { console.log('你訪問(wèn)了data1的name屬性') return _name }, set(newValue) { console.log('你修改了data1的name屬性最新的值為', newValue) _name = newValue } }) // 問(wèn)題產(chǎn)生的原因:get中直接返回了一個(gè)固定的值,并且set函數(shù)中新值拿到了但是沒(méi)有做任何事情 // 解決方案:通過(guò)聲明一個(gè)中間變量,讓get函數(shù)中return出去這個(gè)變量 // 并且在set函數(shù)中把最新的值設(shè)置到這個(gè)中間變量身上,起到一個(gè)set和get操作的一個(gè) // 數(shù)據(jù)的效果 </script>
數(shù)據(jù)的變化可以引起視圖的變化(通過(guò)操作dom把數(shù)據(jù)放到對(duì)應(yīng)的位置上去 如果數(shù)據(jù)變化之后就用數(shù)據(jù)最新的值再重新放一次)
方案一:命令式操作
1.document.querySelector(’#app’).innerText = data.name
2.set函數(shù)中重新執(zhí)行一下document.querySelector(’#app’).innerText = data.name
方案二:聲明式渲染
v-text指令的實(shí)現(xiàn)
<p v-text="name"></p>
核心邏輯:通過(guò)‘模板編譯’找到標(biāo)記了v-text的元素,然后把對(duì)應(yīng)的數(shù)據(jù)通過(guò)操作domapi放上去
<div id="app"> <p v-text="name"></p> <p></p> </app>
1.通過(guò)app根元素找到所有的子節(jié)點(diǎn) (元素節(jié)點(diǎn),文本節(jié)點(diǎn)…) -> dom.nodeChilds
2.通過(guò)節(jié)點(diǎn)類型篩選出元素節(jié)點(diǎn) (p) -> nodeType 1元素節(jié)點(diǎn) 3文本節(jié)點(diǎn)
3.通過(guò)v-text找到需要設(shè)置的具體的節(jié)點(diǎn) <p v-text></p>
4.找到綁定了v-text標(biāo)記的元素 拿到它身上所有的屬性 id class v-text=“name”
5.通過(guò)v-text=“name” 拿到指令類型 ‘v-text’ 拿到需要綁定的數(shù)據(jù)的屬性名 ‘name’
6.判斷當(dāng)前是v-text指令 然后通過(guò)操作domapi 把name屬性對(duì)應(yīng)的值放上去 node.innerText = data[name]
以上整個(gè)過(guò)程可以稱作‘模板編譯’
input元素 v-model雙向綁定 M -> V V -> M
1.通過(guò)app根元素找到所有的子節(jié)點(diǎn) (元素節(jié)點(diǎn),文本節(jié)點(diǎn)…) -> dom.nodeChilds
2.通過(guò)節(jié)點(diǎn)類型篩選出元素節(jié)點(diǎn) (p) -> nodeType 1元素節(jié)點(diǎn) 3文本節(jié)點(diǎn)
3.通過(guò)v-text找到需要設(shè)置的具體的節(jié)點(diǎn) <p v-text></p>
4.找到綁定了v-text標(biāo)記的元素 拿到它身上所有的屬性 id class v-text=“name”
5.通過(guò)v-model=“name” 拿到指令類型 ‘v-model’ 拿到需要綁定的數(shù)據(jù)的屬性名 ‘name’
6.判斷當(dāng)前是v-model指令 然后通過(guò)操作domapi 把name屬性對(duì)應(yīng)的值放上去node.value = data[name]
v-model和v-text除了指令類型不一致,使用的dom api不一致 其它的步驟是完全一致的
本質(zhì):事件監(jiān)聽(tīng)在回調(diào)函數(shù)中拿到input中輸入的最新的值然后賦值給綁定的屬性
node.addEventListener('input',(e)=>{ data[name] = e.target.value })
以上總結(jié):
1.數(shù)據(jù)的響應(yīng)式
2.數(shù)據(jù)變化影響視圖
3.視圖變化影響數(shù)據(jù)
4.指令是如何實(shí)現(xiàn)的(常規(guī)實(shí)現(xiàn)邏輯)
1.通用的數(shù)據(jù)響應(yīng)式處理
data(){ return { name:'cp', age:28 } }
基于現(xiàn)成的數(shù)據(jù),然后都處理成響應(yīng)式
Object.keys(data) // 由所有的對(duì)象的key組成的數(shù)組 Object.keys(data).forEach(key=>{ // key 屬性名 // data[key] 屬性值 // data 原對(duì)象 // 將所有的key都轉(zhuǎn)成get和set的形式 defineReactive(data,key,data[key]) }) function defineReactive(data,key,value){ Oject.defineProperty(data, key, { get(){ return value }, set(newValue){ value = newValue } }) }
2.發(fā)布訂閱模式
問(wèn)題:
<div> <p v-text="name"></p> <p v-text="name"></p> <div v-text="age"></div> </div>
name發(fā)生變化之后 我需要做的事情是更新倆個(gè)p標(biāo)簽,而現(xiàn)在不管你更新了哪個(gè)數(shù)據(jù),所有的標(biāo)簽都會(huì)被重新操作賦值,無(wú)法做到精準(zhǔn)更新
解決問(wèn)題的思路:
1.數(shù)據(jù)發(fā)生變化之后最關(guān)鍵的代碼是什么?
node.innerText = data[name]
2.設(shè)計(jì)一個(gè)存儲(chǔ)結(jié)構(gòu)
每一個(gè)響應(yīng)式數(shù)據(jù)可能被多個(gè)標(biāo)簽綁定 是一個(gè)‘一對(duì)多’的關(guān)系
{ name: [()=>{ node(p1).innerText = data[name]},()=>{ node(p2).innerText = data[name]}...] }
發(fā)布訂閱(自定義事件) 解決的問(wèn)題就是 ‘1對(duì)多’的問(wèn)題
實(shí)現(xiàn)簡(jiǎn)單的發(fā)布訂閱模式:
瀏覽器的事件模型
dom.addEventLister(‘click’,()=>{})
只要調(diào)用click事件,所有綁定的回調(diào)函數(shù)都會(huì)執(zhí)行 顯然是一個(gè)1對(duì)多的關(guān)系
const Dep = { map:{}, collect(eventName,fn){ // 如果從來(lái)沒(méi)有收集過(guò)當(dāng)前事件就先初始化成數(shù)組 if(!this.map[eventName]){ this.map[eventName] = [] } // 已經(jīng)初始化好了就直接往里面push添加 this.map[eventName].push(fn) }, trigger(eventName){ this.map[eventName].forEach(fn=>fn()) } }
使用發(fā)布訂閱模式優(yōu)化現(xiàn)存問(wèn)題
先前的寫(xiě)法 不管是哪個(gè)數(shù)據(jù)發(fā)生變化我們都是粗暴的執(zhí)行一下compile函數(shù)即可
現(xiàn)在的寫(xiě)法 我們?cè)赾ompile函數(shù)初次執(zhí)行的時(shí)候 完成更新函數(shù)的收集 然后在數(shù)據(jù)變化的時(shí)候
通過(guò)數(shù)據(jù)的key找到相對(duì)應(yīng)的更新函數(shù) 依次執(zhí)行 達(dá)到精準(zhǔn)更新的效果
到此,關(guān)于“Vue的核心原理是什么”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。