日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

Vue2的核心原理剖析

發布時間:2023/12/13 vue 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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把數據放到對應的位置上去 如果數據變化之后就用數據最新的值再重新放一次)

方案一:命令式操作

  • document.querySelector(’#app’).innerText = data.name
  • 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}{評論,你的意見是我進步的財富!}

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

    總結

    以上是生活随笔為你收集整理的Vue2的核心原理剖析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。