<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
<script> // 1. 字面量定義 let data = { name: 'aa' } data.name = 'bb' // 這種情況下我們並不能知道name屬性發生了變化 // 2. Object.defineProperty let data1 = {} Object.defineProperty(data1, 'name', { // 當我們存取data1的name屬性的時候自動呼叫的方法 // 並且get函數的返回值就是你拿到的值 get() { console.log('你存取了data1的name屬性') return 'aa' }, // 當我們設定修改name屬性的時候自動呼叫的函數 // 並且屬性最新的值會被當成實參傳入進來 set(newValue) { console.log('你修改了data1的name屬性最新的值為', newValue) // 這個位置 只要你修改了name屬性就會得到執行 // 所以如果你想要在name變化的時候 完成一些自己的事情 // 都可以放到這裡來執行 // 1. ajax() // 2. 操作一塊dom區域 } }) // 以上是js中物件定義的另外一種方案,可以在存取屬性和設定屬性的時候自動呼叫對應的函數 // 存取屬性:data.name data['name'] // 設定屬性:data.name = 'bb' data['name'] = 'bb' </script>
響應式的核心API
<script> // let data = { // name: 'aa' // } let data = {} let _name = 'aa' Object.defineProperty(data, 'name', { get() { console.log('你存取了data1的name屬性') return _name }, set(newValue) { console.log('你修改了data1的name屬性最新的值為', newValue) _name = newValue } }) // 問題產生的原因:get中直接返回了一個固定的值,並且set函數中新值拿到了但是沒有做任何事情 // 解決方案:通過宣告一箇中間變數,讓get函數中return出去這個變數 // 並且在set函數中把最新的值設定到這個中間變數身上,起到一個set和get操作的一個 // 資料的效果 </script>
資料的變化可以引起檢視的變化(通過操作dom把資料放到對應的位置上去 如果資料變化之後就用資料最新的值再重新放一次)
方案一:命令式操作
1.document.querySelector(’#app’).innerText = data.name
2.set函數中重新執行一下document.querySelector(’#app’).innerText = data.name
方案二:宣告式渲染
v-text指令的實現
<p v-text="name"></p>
核心邏輯:通過‘模板編譯’找到標記了v-text的元素,然後把對應的資料通過操作domapi放上去
<div id="app"> <p v-text="name"></p> <p></p> </app>
1.通過app根元素找到所有的子節點 (元素節點,文位元組點…) -> dom.nodeChilds
2.通過節點型別篩選出元素節點 (p) -> nodeType 1元素節點 3文位元組點
3.通過v-text找到需要設定的具體的節點 <p v-text></p>
4.找到繫結了v-text標記的元素 拿到它身上所有的屬性 id class v-text=“name”
5.通過v-text=“name” 拿到指令型別 ‘v-text’ 拿到需要繫結的資料的屬性名 ‘name’
6.判斷當前是v-text指令 然後通過操作domapi 把name屬性對應的值放上去 node.innerText = data[name]
以上整個過程可以稱作‘模板編譯’
input元素 v-model雙向繫結 M -> V V -> M
1.通過app根元素找到所有的子節點 (元素節點,文位元組點…) -> dom.nodeChilds
2.通過節點型別篩選出元素節點 (p) -> nodeType 1元素節點 3文位元組點
3.通過v-text找到需要設定的具體的節點 <p v-text></p>
4.找到繫結了v-text標記的元素 拿到它身上所有的屬性 id class v-text=“name”
5.通過v-model=“name” 拿到指令型別 ‘v-model’ 拿到需要繫結的資料的屬性名 ‘name’
6.判斷當前是v-model指令 然後通過操作domapi 把name屬性對應的值放上去node.value = data[name]
v-model和v-text除了指令型別不一致,使用的dom api不一致 其它的步驟是完全一致的
本質:事件監聽在回撥函數中拿到input中輸入的最新的值然後賦值給繫結的屬性
node.addEventListener('input',(e)=>{ data[name] = e.target.value })
以上總結:
1.資料的響應式
2.資料變化影響檢視
3.檢視變化影響資料
4.指令是如何實現的(常規實現邏輯)
1.通用的資料響應式處理
data(){ return { name:'cp', age:28 } }
基於現成的資料,然後都處理成響應式
Object.keys(data) // 由所有的物件的key組成的陣列 Object.keys(data).forEach(key=>{ // key 屬性名 // data[key] 屬性值 // data 原物件 // 將所有的key都轉成get和set的形式 defineReactive(data,key,data[key]) }) function defineReactive(data,key,value){ Oject.defineProperty(data, key, { get(){ return value }, set(newValue){ value = newValue } }) }
2.釋出訂閱模式
問題:
<div> <p v-text="name"></p> <p v-text="name"></p> <div v-text="age"></div> </div>
name發生變化之後 我需要做的事情是更新倆個p標籤,而現在不管你更新了哪個資料,所有的標籤都會被重新操作賦值,無法做到精準更新
解決問題的思路:
1.資料發生變化之後最關鍵的程式碼是什麼?
node.innerText = data[name]
2.設計一個儲存結構
每一個響應式資料可能被多個標籤繫結 是一個‘一對多’的關係
{ name: [()=>{ node(p1).innerText = data[name]},()=>{ node(p2).innerText = data[name]}...] }
釋出訂閱(自定義事件) 解決的問題就是 ‘1對多’的問題
實現簡單的釋出訂閱模式:
瀏覽器的事件模型
dom.addEventLister(‘click’,()=>{})
只要呼叫click事件,所有繫結的回撥函數都會執行 顯然是一個1對多的關係
const Dep = { map:{}, collect(eventName,fn){ // 如果從來沒有收集過當前事件就先初始化成陣列 if(!this.map[eventName]){ this.map[eventName] = [] } // 已經初始化好了就直接往裡面push新增 this.map[eventName].push(fn) }, trigger(eventName){ this.map[eventName].forEach(fn=>fn()) } }
使用釋出訂閱模式優化現存問題
先前的寫法 不管是哪個資料發生變化我們都是粗暴的執行一下compile函數即可
現在的寫法 我們在compile函數初次執行的時候 完成更新函數的收集 然後在資料變化的時候
通過資料的key找到相對應的更新函數 依次執行 達到精準更新的效果
本篇文章就到這裡了,希望能夠給你帶來幫助,也希望您能夠多多關注it145.com的更多內容!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45