溫馨提示×

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

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

vue3與vue2的區(qū)別以及vue3的API用法介紹

發(fā)布時(shí)間:2021-09-07 14:09:33 來(lái)源:億速云 閱讀:197 作者:chen 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容主要講解“vue3與vue2的區(qū)別以及vue3的API用法介紹”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“vue3與vue2的區(qū)別以及vue3的API用法介紹”吧!

目錄
  • 前言

  • ?準(zhǔn)備工作

  • ?vue3用法

  • ?實(shí)現(xiàn)


前言

最近,由于我的第一個(gè)vue3 + ts的正式項(xiàng)目,已經(jīng)進(jìn)入驗(yàn)收階段。聽(tīng)你們老說(shuō)vue3、vue3的,我就想著去看看vue3到底和vue2有啥區(qū)別。

文章主要闡述vue3的API用法,以及簡(jiǎn)單地實(shí)現(xiàn)一個(gè)vue3。帶大家感受一下vue3與之前vue2的區(qū)別。以及簡(jiǎn)單帶大家揭秘源碼中vue3初始化的一個(gè)流程。

?準(zhǔn)備工作

要想看看vue3內(nèi)部的源碼是咋搞得,首先跟vue2源碼剖析一樣,先從github上下一份源碼到本地。

接著就是安裝依賴:

yarn --ignore-scripts

在你執(zhí)行命令的時(shí)候可能會(huì)遇到node版本過(guò)低的錯(cuò)誤:

vue3與vue2的區(qū)別以及vue3的API用法介紹

解決此問(wèn)題可以升級(jí)自己的node版本,或者忽略該engine。

如果選擇忽略的話可以設(shè)置

yarn config set --ignore-engines true

然后執(zhí)行依賴安裝。

依賴安裝完成后,編譯打包生成vuejs文件:

yarn dev

需要調(diào)試的話,可以在packages\vue\examples文件下建立測(cè)試文件。引用打包后的vue文件,可以應(yīng)用packages\vue\dist\vue.global.js。

?vue3用法

vue3的特性我就不多闡述了,就vue3的用法而言,更傾向于函數(shù)式編程,通過(guò)對(duì)外暴露Vue中的createApp()API,以工廠函數(shù)的方式創(chuàng)建了一個(gè)應(yīng)用程序?qū)嵗O啾容^vue2的new Vue實(shí)例,更加貼切。

在源碼文件中,我們新建一個(gè)init.html文件。

<script src="../dist/vue.global.js"></script>
 <body>
  <div id="app">{{name}}</div>
  <script>
    const { createApp } = Vue
    const app1 = createApp({
      data() {
        return {
          name: 'clying'
        }
      },
      setup() {
        return {
          name: 'deng'
        }
      }
    }).mount('#app')
  </script>
</body>

根據(jù)上例,我們可以看出vue3是即支持Composition API,也支持Options API,兩者可以同時(shí)使用。

但是,我們可以看到在data和setup中,我同時(shí)使用了一個(gè)name變量進(jìn)行賦值。那么頁(yè)面中會(huì)展示哪一個(gè)呢?

3!2!1!上答案:

vue3與vue2的區(qū)別以及vue3的API用法介紹

可以明顯看出composition-api中setup優(yōu)先級(jí)更高。

vue3與vue2的區(qū)別以及vue3的API用法介紹

當(dāng)然也可以在源碼中的packages\runtime-core\src\componentPublicInstance.ts看到,通過(guò)switch先判斷setup中的變量是否存在,然后再去判斷data中的變量。所以setup中變量的優(yōu)先級(jí)會(huì)高于data中的變量。

?實(shí)現(xiàn)

通過(guò)上面的用法,我們可以知道vue3中會(huì)對(duì)外暴露一個(gè)Vue變量,內(nèi)部存在createApp、reactive等方法。

在此,我們先實(shí)現(xiàn)vue3的初始化框架。就createApp而言,它會(huì)接收用戶傳入的參數(shù):data()、setup()等,最后進(jìn)行實(shí)例掛載mount。所以在createApp中會(huì)接收一些參數(shù)options、內(nèi)部還會(huì)存在mount方法。

const Vue = {
    createApp(options) {
      return {
        mount(selector) { //解析、獲取render、掛載
        }
      }
    }
}

在mount中通過(guò)selector獲取到宿主元素。

接下來(lái)就是對(duì)模板的編譯,由于將template編譯AST后,依舊要轉(zhuǎn)成render函數(shù)。在此我們簡(jiǎn)化操作,在編譯時(shí)直接返回一個(gè)render。

mount(selector) { //解析、獲取render、掛載
  const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // 編譯返回render
    options.render = this.compileToFunction(parent.innerHTML)
  }
},
compileToFunction(template) {
  return function render() {
    const h = document.createElement('div')
    h.textContent = this.name
    return h
  }
}

拿到render之后,執(zhí)行它,將其添加到宿主元素中,將老的節(jié)點(diǎn)刪除。

在執(zhí)行render的時(shí)候,我們需要注意它的this指向。如果給它綁定data,那么它展示的就會(huì)使data中的name。

mount(selector) { //解析、獲取render、掛載
  const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // 編譯返回render
    options.render = this.compileToFunction(parent.innerHTML)
  }
  // 執(zhí)行render 
  const el = options.render.call(options.data())
  parent.innerHTML = ''
  parent.appendChild(el)
},

vue3與vue2的區(qū)別以及vue3的API用法介紹

可以看到頁(yè)面上展示的是clying。反之,如果綁定的是options.setup(),那么頁(yè)面上出現(xiàn)的就是deng。

對(duì)于vue3的用法,我們知道setup的優(yōu)先級(jí)是高于data的。那我們可以使用代理啊,將兩者的屬性變量,通過(guò)代理的方式,糅合到一起,優(yōu)先考慮setup。當(dāng)訪問(wèn)相同name時(shí),實(shí)際訪問(wèn)的就是setup中的name。

mount(selector) { //解析、獲取render、掛載
  const parent = document.querySelector(selector)
  console.log(parent);
  if (!options.render) {
    // 編譯返回render
    options.render = this.compileToFunction(parent.innerHTML)
  }
  if (options.setup) {
    this.setupState = options.setup()
  }
  if (options.data) {
    this.data = options.data()
  }
  this.proxy = new Proxy(this, {
    get(target, key) {
      if (key in target.setupState) {
        return target.setupState[key]
      } else if (key in target.data) {
        return target.data[key]
      }// 還可能存在props、watch等其他同名變量
    }, 
    set(target, key, value, newVal) {
      console.log(target, key, value, newVal);
    }
  })
  // 執(zhí)行render  this.proxy就是整合setup和data的上下文
  const el = options.render.call(this.proxy)
  console.log(el, options.render);
  parent.innerHTML = ''
  parent.appendChild(el)
},

在proxy的get中,先看setup中是否存在目標(biāo)屬性,如果存在的話返回的就是setup中的屬性變量,否則就是data中的。在渲染的時(shí)候,直接將整合的變量集傳入即可。當(dāng)然proxy中也會(huì)存在set方法,需要先代理,然后在外部獲取變量做值得修改才能觸發(fā),在此有興趣的同學(xué)可以自行研究哦!

到此,相信大家對(duì)“vue3與vue2的區(qū)別以及vue3的API用法介紹”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向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)容。

AI