溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Vue的核心原理是什么

發(fā)布時(shí)間:2022-03-24 09:12:34 來(lái)源:億速云 閱讀:217 作者:iii 欄目:開(kāi)發(fā)技術(shù)

這篇文章主要介紹“Vue的核心原理是什么”,在日常操作中,相信很多人在Vue的核心原理是什么問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”Vue的核心原理是什么”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

Object.defineProperty

 <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   

get、set

 <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ù)反應(yīng)到視圖

數(shù)據(jù)的變化可以引起視圖的變化(通過(guò)操作dom把數(shù)據(jù)放到對(duì)應(yīng)的位置上去 如果數(shù)據(jù)變化之后就用數(shù)據(jù)最新的值再重新放一次)

方案一:命令式操作

1.document.querySelector(&rsquo;#app&rsquo;).innerText = data.name

2.set函數(shù)中重新執(zhí)行一下document.querySelector(&rsquo;#app&rsquo;).innerText = data.name

方案二:聲明式渲染

v-text指令的實(shí)現(xiàn)

 <p v-text="name"></p>

核心邏輯:通過(guò)&lsquo;模板編譯&rsquo;找到標(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)&hellip;) -> 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” 拿到指令類型 &lsquo;v-text&rsquo; 拿到需要綁定的數(shù)據(jù)的屬性名 &lsquo;name&rsquo;

6.判斷當(dāng)前是v-text指令 然后通過(guò)操作domapi 把name屬性對(duì)應(yīng)的值放上去 node.innerText = data[name]

以上整個(gè)過(guò)程可以稱作&lsquo;模板編譯&rsquo;

視圖的變化反映到數(shù)據(jù)

input元素 v-model雙向綁定
M -> V
V -> M

M -> V

1.通過(guò)app根元素找到所有的子節(jié)點(diǎn) (元素節(jié)點(diǎn),文本節(jié)點(diǎn)&hellip;) -> 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” 拿到指令類型 &lsquo;v-model&rsquo; 拿到需要綁定的數(shù)據(jù)的屬性名 &lsquo;name&rsquo;

6.判斷當(dāng)前是v-model指令 然后通過(guò)操作domapi 把name屬性對(duì)應(yīng)的值放上去node.value = data[name]

v-model和v-text除了指令類型不一致,使用的dom api不一致 其它的步驟是完全一致的

V -> M

本質(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)邏輯)

優(yōu)化工作:

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è)&lsquo;一對(duì)多&rsquo;的關(guān)系

 {
        name: [()=>{ node(p1).innerText = data[name]},()=>{ node(p2).innerText = data[name]}...]
      }

發(fā)布訂閱(自定義事件) 解決的問(wèn)題就是 &lsquo;1對(duì)多&rsquo;的問(wèn)題

實(shí)現(xiàn)簡(jiǎn)單的發(fā)布訂閱模式:

瀏覽器的事件模型

dom.addEventLister(&lsquo;click&rsquo;,()=>{})

只要調(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í)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(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)容。

vue
AI