Vue2的核心原理剖析

? 用了這么久的Vue2了你真的 知其然,知其所以然么?

?今天博主就為大家帶來一篇對Vue核心功能的部分剖析\textcolor{pink}{今天博主就為大家帶來一篇對Vue核心功能的部分剖析}Vue

?后續文章會用更多小案例來幫助大家理解Vue的原理\textcolor{green}{后續文章會用更多小案例來幫助大家理解Vue的原理}Vue

前言:

  • 相信大家閱讀過很多關于Vue2的文章,我也閱讀過很多,但是大部分文章介紹的都是如何在項目中進行應用,技術點如果使用,功能如何實現;
  • 今天小編為大家帶來這篇Vue2的核心原理剖析就是為大家介紹我們常用的Vue2他是如何實現的核心內容,我們簡單代碼的背后究竟他做了哪些,讓大家能夠 知其然,知其所以然

學習目標:

  • 了解Object.defineProperty原理
  • 了解set、get關聯使用
  • 了解數據反應到識圖的過程
  • 了解視圖更換如何影響數據
  • 掌握MVVM

Object.defineProperty

 <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   

get、set

 <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

M -> V

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不一致 其它的步驟是完全一致的

V -> M

本質:事件監聽在回調函數中拿到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找到相對應的更新函數 依次執行 達到精準更新的效果

寫在最后

?原創不易,還希望各位大佬支持一下\textcolor{blue}{原創不易,還希望各位大佬支持一下}

👍 點贊,你的認可是我創作的動力!\textcolor{green}{點贊,你的認可是我創作的動力!}

?? 收藏,你的青睞是我努力的方向!\textcolor{green}{收藏,你的青睞是我努力的方向!}

?? 評論,你的意見是我進步的財富!\textcolor{green}{評論,你的意見是我進步的財富!}

看完文章啦 驗證大家對這篇文章的掌握 大家參與下方的投票呦!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248511.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248511.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248511.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Scrum之成敗——從自身案例說起,僅供參考

從07年中初次接觸Scrum的概念到其中幾年項目中逐漸實踐CI、TDD&#xff0c;到親自掌握項目實踐Scrum近一年&#xff0c;最終我們放棄了Scrum這個框架和所謂的“自組織”。原因為何&#xff1f; 1.成員放棄了Scrum所“賦予”的“權利” 比如領用任務、評估工作量、自組織協作、決…

sanic官方文檔解析之下載和Configuration

1,sanic框架是做什么的? sanic的官方網址:https://sanic.readthedocs.io/en/latest/sanic框架是一個類似于flask框架的在Python3.5以上版本的文本服務器,他能夠快速的編寫,它是通過驚人的開發效率完成開發,希望通過這篇文章得到激勵sanic框架的理念是:簡單,高效 sanic的應用如…

首秀 Express 框架

文章目錄框架特性express的使用初始化項目&#xff1a;下載框架模塊&#xff1a;測試代碼&#xff1a;總結以上代碼&#xff1a;請求處理的中間件概念&#xff1a;中間件——app.use基本用法&#xff1a;next的用法app.use中間件的應用路由的保護網站維護公告自定義404&#xf…

云原生技能樹測評

前言 利用午休后的10多分鐘時間&#xff0c;看了看APP的技能樹板塊&#xff0c;簡單的提出幾個看法&#xff01; 答題過程 可以設置為闖關類型&#xff0c;答對一道后可以進入下一關&#xff0c;或者是一個章節為一關&#xff0c;讓大家一直有一種期待 回答錯誤數量 可以…

原型和閉包

原型和閉包 一切皆對象 一切皆對象&#xff08;類型值除外&#xff09; undefined, number, string, boolean屬于簡單的值類型 函數、數組、對象、new Number(10)都是對象。他們都是引用類型 Null是基本數據類型&#xff0c;不是引用數據類型 基本數據類型的值就是它本身的值&a…

python 排序算法

冒泡排序&#xff1a; 1 #coding:utf-82 3 比較相鄰的元素&#xff0c;每一趟交換后&#xff0c;最后的元素是最大的。4 第一次比較n-1次&#xff0c;第二次比較n-2次。。。第n-1次比較1次5 進行n-1次冒泡次數6 最優時間復雜度O(n),最壞時間復雜度O(n^2)7 8 9 def bubble_sort…

獎勵 CSDN 社區的領軍人物

設計動機 領軍人物榜單在這里&#xff1a;https://blog.csdn.net/rank/list/role CSDN 是中國 IT 人士學習、成長、成功的平臺&#xff0c; 這個平臺有很多博主&#xff0c; 博主寫的很多優秀文章獲得了粉絲。 那么&#xff0c; 博主獲得粉絲之后&#xff0c; 博主以粉絲為榮…

一文教會你何為重繪、回流?

文章目錄css圖層圖層創建的條件重繪(Repaint)回流觸發重繪的屬性觸發回流的屬性常見的觸發回流的操作優化方案requestAnimationFrame----請求動畫幀寫在最后學習目標&#xff1a; 了解前端Dom代碼、css樣式、js邏輯代碼到瀏覽器展現過程了解什么是圖層了解重繪與回流了解前端層…

mockjs中的方法(三)

1&#xff09;Mock.mock()&#xff1b; Mock.mock( url, type, template, function(options) ); 其中 url 是定義我們要請求的 url 地址&#xff0c;以便于我們請求的時候 mock 去進行攔截&#xff0c;知道我們要去請求那個值&#xff1b;但是它也是可選的&#xff0c;而且格式…

js函數、js對象的這些點你真的懂嗎?

本篇學習目標 ?了解函數&#xff08;高級&#xff09;原型原型鏈概念\textcolor{green}{了解函數&#xff08;高級&#xff09;原型原型鏈概念}了解函數&#xff08;高級&#xff09;原型原型鏈概念 ?掌握函數作用域\textcolor{green}{掌握函數作用域}掌握函數作用域 ?掌握…

前端處理跨域的幾種方式

什么是跨域&#xff1f; 跨域是指一個域下的文檔或腳本試圖去請求另一個域下的資源&#xff0c;這里跨域是廣義的。 廣義的跨域&#xff1a; 1、資源跳轉&#xff1a;A鏈接、重定向、表單提交 2、資源嵌入&#xff1a; <link>、<script>、<img>、<frame&g…

程序員必知的緩存套圖

文章目錄1. 線程與進程1.1 進程:1.2. 線程:1.3. 關系2. 瀏覽器內核模塊組成4. 事件循環機制5. 緩存5.1. 緩存理解5.2. 緩存分類5.3. 緩存使用示意圖5.4. 緩存中的header參數1. 線程與進程 1.1 進程: 進程是計算機中的程序關于某數據集合上的一次運行活動&#xff0c;是系統進…

安裝webpack及使用

前言 你是否也是只會運用框架中集成好的Webpack配置呢&#xff1f;你明白每一項的意義么&#xff1f;你懂多少Webpack的個性化配置項呢&#xff1f;本篇文章為你講解Webpack中的各種配置項參數及作用&#xff01; 文章目錄了解Webpack相關開啟項目編譯打包應用使用webpack配置…

Python基礎-os模塊 sys模塊

sys模塊 與操作系統交互的一個接口 文件夾相關 os.makedirs(dirname1/dirname2) 可生成多層遞歸目錄os.removedirs(dirname1) 若目錄為空&#xff0c;則刪除&#xff0c;并遞歸到上一級目錄&#xff0c;如若也為空&#xff0c;則刪除&#xff0c;依此類推os.mkdir(dirnam…

php單例型(singleton pattern)

搞定&#xff0c;吃飯 <?php /* The purpose of singleton pattern is to restrict instantiation of class to a single object. It is implemented by creating a method within the class that creates a new instance of that class if one does not exist. If an obje…

開啟關閉各種服務

開啟&關閉 Mac版 查找被占用的8080端口&#xff0c;根據pid殺掉進程 查找8080端口 losf -i:8080 根據pid殺掉進程 kill -9 pid iMac:~ acui$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 62948 ting 93u IPv6 0x6697d6…

助你提高效率的幾個Vue指令

前言 很多使用Vue的同學往往最容易忽略的指令&#xff0c;由于在這里考慮到很多初學甚至還沒有開始接觸Vue的同學呢&#xff0c;在介紹v-clos之前呢就先以大家都熟知的v-model編寫小demo v-model 相信大家對v-model并不陌生&#xff0c;簡單來講他就是用于在表單控件以及組建…

掌握Mock擺脫后端同學的束縛

文章目錄前言Mock概述mock.js安裝Mock規范Mock的使用總結前言 當下采用前后端分離模式開發Web應用已經成為氣候&#xff0c;在開發階段有一個不成文的規定則是 項目開發后端先行 但是作為前端開發工程師的我們&#xff0c;難道在搭建完頁面后只能等待后端的接口么&#xff1f;…

戶外鞋簡介

. 單論品牌&#xff08;主要以登山鞋及徙步鞋為主&#xff09;&#xff1a; 高級品牌&#xff1a;SCARPA、ASOLO、MONTRAIL、ZAMBERLAN、vasque、Lowa、La Sportiva 價格都較高&#xff0c;單價都在千元以上&#xff0c;品質一流&#xff0c;做工精細。 中檔品牌&#xff1a;Tr…

Vue技能樹上線啦

前言 前端現在越來越多樣化&#xff0c;語言眾多&#xff0c;大家使用的框架也比較雜&#xff0c;在廣泛的前端技術棧面前我唯愛Vue&#xff08;僅代表個人觀點勿噴小伙伴們&#xff09;可能很多人覺得我是因為簡單&#xff0c;其實并不然&#xff0c;我嘗試過很多框架&#x…