AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當前位置:首頁 > 科技  > 軟件

最近很火的Vue Vine是如何實現(xiàn)一個文件中寫多個組件

來源: 責編: 時間:2024-07-10 17:58:18 119觀看
導讀前言在今年的Vue Conf 2024大會上,沈青川大佬(維護Vue/Vite 中文文檔)在會上介紹了他的新項目Vue Vine。Vue Vine提供了全新Vue組件書寫方式,主要的賣點是可以在一個文件里面寫多個vue組件。相信你最近應該看到了不少介紹

前言

在今年的Vue Conf 2024大會上,沈青川大佬(維護Vue/Vite 中文文檔)在會上介紹了他的新項目Vue Vine。Vue Vine提供了全新Vue組件書寫方式,主要的賣點是可以在一個文件里面寫多個vue組件。相信你最近應該看到了不少介紹Vue Vine的文章,這篇文章我們另辟蹊徑來講講Vue Vine是如何實現(xiàn)在一個文件里面寫多個vue組件。KhR28資訊網(wǎng)——每日最新資訊28at.com

看個demo

我們先來看普通的vue組件,about.vue代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

<template>  <h3>i am about page</h3></template><script lang="ts" setup></script>

我們在瀏覽器中來看看編譯后的js代碼,代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

const _sfc_main = {};function _sfc_render(_ctx, _cache) {  return _openBlock(), _createElementBlock("h3", null, "i am about page");}_sfc_main.render = _sfc_render;export default _sfc_main;

從上面的代碼可以看到普通的vue組件編譯后生成的js文件會export default導出一個_sfc_main組件對象,并且這個組件對象上面有個大名鼎鼎的render函數(shù)。父組件只需要import導入子組件里面export default導出的_sfc_main組件對象就可以啦。KhR28資訊網(wǎng)——每日最新資訊28at.com

搞清楚普通的vue組件編譯后是什么樣的,我們接著來看一個Vue Vine的demo,Vue Vine的組件必須以.vine.ts 結尾,home.vine.ts代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

async function ChildComp() {  return vine`    <h3>我是子組件</h3>  `;}export async function Home() {  return vine`  <h3>我是父組件</h3>    <ChildComp  />  `;}

如果你熟悉react,你會發(fā)現(xiàn)Vine 組件函數(shù)和react比較相似,不同的是return的時候需要在其返回值上顯式使用 vine 標記的模板字符串。KhR28資訊網(wǎng)——每日最新資訊28at.com

在瀏覽器中來看看home.vine.ts編譯后的代碼,代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

export const ChildComp = (() => {  const __vine = _defineComponent({    name: "ChildComp",    setup(__props, { expose: __expose }) {      // ...省略    },  });  function __sfc_render(_ctx, _cache, $props, $setup, $data, $options) {    return _openBlock(), _createElementBlock("h3", null, "我是子組件");  }  __vine.render = __sfc_render;  return __vine;})();export const Home = (() => {  const __vine = _defineComponent({    name: "Home",    setup(__props, { expose: __expose }) {      // ...省略    },  });  function __sfc_render(_ctx, _cache, $props, $setup, $data, $options) {    return (      _openBlock(),      _createElementBlock(        _Fragment,        null,        [_hoisted_1, _createVNode($setup["ChildComp"])],        64,      )    );  }  __vine.render = __sfc_render;  return __vine;})();

從上面的代碼可以看到組件ChildComp和Home編譯后是一個立即調用函數(shù),在函數(shù)中return了__vine組件對象,并且這個組件對象上面也有render函數(shù)。想必細心的你已經(jīng)發(fā)現(xiàn)了在同一個文件里面定義的多個組件經(jīng)過編譯后,從常規(guī)的export default導出一個默認的vue組件對象變成了export導出多個具名的vue組件對象。KhR28資訊網(wǎng)——每日最新資訊28at.com

接下來我們將通過debug的方式帶你搞清楚Vue Vine是如何實現(xiàn)一個文件內導出多個vue組件對象。KhR28資訊網(wǎng)——每日最新資訊28at.com

createVinePlugin函數(shù)

我們遇見的第一個問題是需要找到從哪里開始著手debug?KhR28資訊網(wǎng)——每日最新資訊28at.com

來看一下官方文檔是接入vue vine的,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到vine是一個vite插件,以插件的形式起作用的。KhR28資訊網(wǎng)——每日最新資訊28at.com

現(xiàn)在我們找到了一切起源就是這個VineVitePlugin函數(shù),所以我們需要給vite.config.ts文件中的VineVitePlugin函數(shù)打個斷點。如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

接下來我們需要啟動一個debug終端。這里以vscode舉例,打開終端然后點擊終端中的+號旁邊的下拉箭頭,在下拉中點擊Javascript Debug Terminal就可以啟動一個debug終端。KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

在debug終端執(zhí)行yarn dev,在瀏覽器中打開對應的頁面,比如:http://localhost:3333/ 。此時代碼將會停留在我們打的斷點VineVitePlugin函數(shù)調用處,讓代碼走進VineVitePlugin函數(shù),發(fā)現(xiàn)這個函數(shù)實際定義的名字叫createVinePlugin,在我們這個場景中簡化后的createVinePlugin函數(shù)代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

function createVinePlugin() {  return {    name: "vue-vine-plugin",    async resolveId(id) {      // ...省略    },    async load(id) {      // ...省略    },    async transform(code, id) {      const { fileId, query } = parseQuery(id);      if (!fileId.endsWith(".vine.ts") || query.type === QUERY_TYPE_STYLE) {        return;      }      return runCompileScript(code, id);    },    async handleHotUpdate(ctx) {      // ...省略    }  };}

從上面的代碼可以看到插件中有不少鉤子函數(shù),vite會在對應的時候調用這些插件的鉤子函數(shù),比如當vite解析每個模塊時就會調用transform等函數(shù)。KhR28資訊網(wǎng)——每日最新資訊28at.com

transform鉤子函數(shù)的接收的第一個參數(shù)為code,是當前文件的code代碼字符串。第二個參數(shù)為id,是當前文件路徑,這個路徑可能帶有query。KhR28資訊網(wǎng)——每日最新資訊28at.com

在transform鉤子函數(shù)中先調用parseQuery函數(shù)根據(jù)當前文件路徑拿到去除query的文件路徑,以及query對象。KhR28資訊網(wǎng)——每日最新資訊28at.com

!fileId.endsWith(".vine.ts") 的意思是判斷當前文件是不是.vine.ts結尾的文件,如果不是則不進行任何處理,這也就是為什么文檔中會寫Vue Vine只支持.vine.ts結尾的文件。KhR28資訊網(wǎng)——每日最新資訊28at.com

query.type === QUERY_TYPE_STYLE的意思是判斷當前文件是不是css文件,因為同一個vue文件會被處理兩次,第一次處理時只會處理template和script這兩個模塊,第二次再去單獨處理style模塊。KhR28資訊網(wǎng)——每日最新資訊28at.com

在transform鉤子函數(shù)的最后就是調用runCompileScript(code, id)函數(shù),并且將其執(zhí)行結果進行返回。KhR28資訊網(wǎng)——每日最新資訊28at.com

runCompileScript函數(shù)

接著將斷點走進runCompileScript函數(shù),在我們這個場景中簡化后的runCompileScript函數(shù)代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

const runCompileScript = (code, fileId) => {  const vineFileCtx = compileVineTypeScriptFile(    code,    fileId,    compilerHooks,    fileCtxMap,  );  return {    code: vineFileCtx.fileMagicCode.toString(),  };};

從上面的代碼可以看到首先會以code(當前文件的code代碼字符串)為參數(shù)去執(zhí)行compileVineTypeScriptFile函數(shù),這個函數(shù)會返回一個vineFileCtx上下文對象。這個上下文對象的fileMagicCode.toString(),就是前面我們在瀏覽器中看到的最終編譯好的js代碼。KhR28資訊網(wǎng)——每日最新資訊28at.com

compileVineTypeScriptFile函數(shù)

接著將斷點走進compileVineTypeScriptFile函數(shù),在我們這個場景中簡化后的compileVineTypeScriptFile函數(shù)代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

function compileVineTypeScriptFile(  code: string,  fileId: string,  compilerHooks: VineCompilerHooks,  fileCtxCache?: VineFileCtx,) {  const vineFileCtx: VineFileCtx = createVineFileCtx(    code,    fileId,    fileCtxCache,  );  const vineCompFnDecls = findVineCompFnDecls(vineFileCtx.root);  doAnalyzeVine(compilerHooks, vineFileCtx, vineCompFnDecls);  transformFile(    vineFileCtx,    compilerHooks,    compilerOptions?.inlineTemplate ?? true,  );  return vineFileCtx;}

在執(zhí)行compileVineTypeScriptFile函數(shù)之前,我們在debug終端來看看接收的第一個參數(shù)code,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到第一個參數(shù)code就是我們寫的home.vine.ts文件中的源代碼。KhR28資訊網(wǎng)——每日最新資訊28at.com

createVineFileCtx函數(shù)

接下來看第一個函數(shù)調用createVineFileCtx,這個函數(shù)返回一個vineFileCtx上下文對象。將斷點走進createVineFileCtx函數(shù),在我們這個場景中簡化后的createVineFileCtx函數(shù)代碼如下:KhR28資訊網(wǎng)——每日最新資訊28at.com

import MagicString from 'magic-string'function createVineFileCtx(code: string, fileId: string) {  const root = babelParse(code);  const vineFileCtx: VineFileCtx = {    root,    fileMagicCode: new MagicString(code),    vineCompFns: [],    // ...省略  };  return vineFileCtx;}

由于Vue Vine中的組件和react相似是組件函數(shù),組件函數(shù)中當然全部都是js代碼。既然是js代碼那么就可以使用babel的parser函數(shù)將組件函數(shù)的js代碼編譯成AST抽象語法樹,所以第一步就是使用code去調用babel的parser函數(shù)生成AST抽象語法樹,然后賦值給root變量。KhR28資訊網(wǎng)——每日最新資訊28at.com

我們在debug終端來看看得到的AST抽象語法樹是什么樣的,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到在body數(shù)組中有兩項,分別對應的就是ChildComp組件函數(shù)和Home組件函數(shù)。KhR28資訊網(wǎng)——每日最新資訊28at.com

接下來就是return返回一個vineFileCtx上下文對象,對象上面的幾個屬性我們需要講一下。KhR28資訊網(wǎng)——每日最新資訊28at.com

  • root:由.vine.ts文件轉換后的AST抽象語法樹。
  • vineCompFns:數(shù)組中存了文件中定義的多個vue組件,初始化時為空數(shù)組。
  • fileMagicCode:是一個由magic-string庫new的一個對象,對象中存了在編譯時生成的js代碼字符串。magic-string是由svelte的作者寫的一個庫,用于處理字符串的JavaScript庫。它可以讓你在字符串中進行插入、刪除、替換等操作,在編譯時就是利用這個庫生成編譯后的js代碼。toString方法返回經(jīng)過處理后的字符串,前面的runCompileScript函數(shù)中就是最終調用vineFileCtx.fileMagicCode.toString()方法返回經(jīng)過編譯階段處理得到的js代碼。

findVineCompFnDecls函數(shù)

我們接著來看compileVineTypeScriptFile函數(shù)中的第二個函數(shù)調用findVineCompFnDecls:KhR28資訊網(wǎng)——每日最新資訊28at.com

function compileVineTypeScriptFile(  code: string,  fileId: string,  compilerHooks: VineCompilerHooks,  fileCtxCache?: VineFileCtx,) {  // ...省略  const vineCompFnDecls = findVineCompFnDecls(vineFileCtx.root);  // ...省略}

通過前一步我們拿到了一個vineFileCtx上下文對象,vineFileCtx.root中存的是編譯后的AST抽象語法樹。KhR28資訊網(wǎng)——每日最新資訊28at.com

所以這一步就是調用findVineCompFnDecls函數(shù)從AST抽象語法樹中提取出在.vine.ts文件中定義的多個vue組件對象對應的Node節(jié)點。我們在debug終端來看看組件對象對應的Node節(jié)點組成的數(shù)組vineCompFnDecls,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到數(shù)組由兩個Node節(jié)點組成,分別對應的是ChildComp組件函數(shù)和Home組件函數(shù)。KhR28資訊網(wǎng)——每日最新資訊28at.com

doAnalyzeVine函數(shù)

我們接著來看compileVineTypeScriptFile函數(shù)中的第三個函數(shù)調用doAnalyzeVine:KhR28資訊網(wǎng)——每日最新資訊28at.com

function compileVineTypeScriptFile(  code: string,  fileId: string,  compilerHooks: VineCompilerHooks,  fileCtxCache?: VineFileCtx,) {  // ...省略  doAnalyzeVine(compilerHooks, vineFileCtx, vineCompFnDecls);  // ...省略}

經(jīng)過上一步的處理我們拿到了兩個組件對象的Node節(jié)點,并且將這兩個Node節(jié)點存到了vineCompFnDecls數(shù)組中。KhR28資訊網(wǎng)——每日最新資訊28at.com

由于組件對象的Node節(jié)點是一個標準的AST抽象語法樹的Node節(jié)點,并不能清晰的描述一個vue組件對象。所以接下來就是調用doAnalyzeVine函數(shù)遍歷組件對象的Node節(jié)點,將其轉換為能夠清晰的描述一個vue組件的對象,將這些vue組件對象組成數(shù)組塞到vineFileCtx上下文對象的vineCompFns屬性上。KhR28資訊網(wǎng)——每日最新資訊28at.com

我們在debug終端來看看經(jīng)過doAnalyzeVine函數(shù)處理后生成的vineFileCtx.vineCompFns屬性是什么樣的,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到vineCompFns屬性中存的組件對象已經(jīng)能夠清晰的描述一個vue組件,上面有一些我們熟悉的屬性props、slots等。KhR28資訊網(wǎng)——每日最新資訊28at.com

transformFile函數(shù)

我們接著來看compileVineTypeScriptFile函數(shù)中的第四個函數(shù)調用transformFile:KhR28資訊網(wǎng)——每日最新資訊28at.com

function compileVineTypeScriptFile(  code: string,  fileId: string,  compilerHooks: VineCompilerHooks,  fileCtxCache?: VineFileCtx,) {  // ...省略  transformFile(    vineFileCtx,    compilerHooks,    compilerOptions?.inlineTemplate ?? true,  );  // ...省略}

經(jīng)過上一步的處理后在vineFileCtx上下文對象的vineCompFns屬性數(shù)組中已經(jīng)存了一系列能夠清晰描述vue組件的對象。KhR28資訊網(wǎng)——每日最新資訊28at.com

在前面我們講過了vineFileCtx.vineCompFns數(shù)組中存的對象能夠清晰的描述一個vue組件,但是對象中并沒有我們期望的render函數(shù)、setup函數(shù)等。KhR28資訊網(wǎng)——每日最新資訊28at.com

所以接下來就需要調用transformFile函數(shù),遍歷上一步拿到的vineFileCtx.vineCompFns數(shù)組,將所有的vue組件轉換成對應的立即調用函數(shù)。在每個立即調用函數(shù)中都會return一個__vine組件對象,并且這個__vine組件對象上都有一個render屬性。KhR28資訊網(wǎng)——每日最新資訊28at.com

之所以包裝成一個立即調用函數(shù),是因為每個組件都會生成一個名為__vine組件對象,所以才需要立即調用函數(shù)將作用域進行隔離。KhR28資訊網(wǎng)——每日最新資訊28at.com

我們在debug終端來看看經(jīng)過transformFile函數(shù)處理后拿到的js code代碼字符串,如下圖:KhR28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片KhR28資訊網(wǎng)——每日最新資訊28at.com

從上圖中可以看到此時的js code代碼字符串已經(jīng)和我們之前在瀏覽器中看到的編譯后的代碼一模一樣了。KhR28資訊網(wǎng)——每日最新資訊28at.com

總結

Vue Vine是一個vite插件,vite解析每個模塊時都會觸發(fā)插件的transform鉤子函數(shù)。在鉤子函數(shù)中會去判斷當前文件是否以.vine.ts結尾的,如果不是則return。KhR28資訊網(wǎng)——每日最新資訊28at.com

在transform鉤子函數(shù)中會去調用runCompileScript函數(shù),runCompileScript函數(shù)并不是實際干活的地方,而是去調用compileVineTypeScriptFile函數(shù)。KhR28資訊網(wǎng)——每日最新資訊28at.com

在compileVineTypeScriptFile函數(shù)中先new一個vineFileCtx上下文對象,對象中的root屬性存了由.vine.ts文件轉換成的AST抽象語法樹。KhR28資訊網(wǎng)——每日最新資訊28at.com

接著就是調用findVineCompFnDecls函數(shù)從AST抽象語法樹中找到組件對象對應的Node節(jié)點。KhR28資訊網(wǎng)——每日最新資訊28at.com

由于Node節(jié)點并不能清晰的描述一個vue組件,所以需要調用doAnalyzeVine函數(shù)將這些Node節(jié)點轉換成能夠清晰描述vue組件的對象。KhR28資訊網(wǎng)——每日最新資訊28at.com

最后就是遍歷這些vue組件對象將其轉換成立即調用函數(shù)。在每個立即調用函數(shù)中都會return一個__vine組件對象,并且這個__vine組件對象上都有一個render屬性。KhR28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-100190-0.html最近很火的Vue Vine是如何實現(xiàn)一個文件中寫多個組件

聲明:本網(wǎng)頁內容旨在傳播知識,若有侵權等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 微服務 | Spring Cloud中如何使用Eureka

下一篇: Stream很好,Map很酷,但答應我別用toMap()

標簽:
  • 熱門焦點
  • 一加Ace2 Pro官宣:普及16G內存 引領24G

    一加官方今天繼續(xù)為本月發(fā)布的新機一加Ace2 Pro帶來預熱,公布了內存方面的信息。“淘汰 8GB ,12GB 起步,16GB 普及,24GB 引領,還有呢?#一加Ace2Pro#,2023 年 8 月,敬請期待。”同時
  • 盧偉冰長文解析K60至尊版 對Redmi有著里程碑式的意義

    在今天的Redmi后性能時代戰(zhàn)略發(fā)布會結束之后,Redmi總經(jīng)理盧偉冰又帶來了一篇長文,詳解了為什么 Redmi 要開啟后性能時代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 一加Ace2 Pro真機揭曉 鈦空灰配色質感拉滿

    終于,在經(jīng)過了幾波預熱之后,一加Ace2 Pro的外觀真機圖在網(wǎng)上出現(xiàn)了。還是博主數(shù)碼閑聊站曝光的,這次的外觀設計還是延續(xù)了一加11的方案,只是細節(jié)上有了調整,例如新加入了鈦空灰
  • 天貓精靈Sound Pro體驗:智能音箱沒有音質?來聽聽我的

    這幾年除了手機作為智能生活終端最主要的核心之外,第二個可以成為中心點的產品是什么?——是智能音箱。 手機在執(zhí)行命令的時候有兩種操作方式,手和智能語音助手,而智能音箱只
  • 2023年,我眼中的字節(jié)跳動

    此時此刻(2023年7月),字節(jié)跳動從未上市,也從未公布過任何官方的上市計劃;但是這并不妨礙它成為中國最受關注的互聯(lián)網(wǎng)公司之一。從2016-17年的抖音強勢崛起,到2018年的&ldquo;頭騰
  • 破圈是B站頭上的緊箍咒

    來源 | 光子星球撰文 | 吳坤諺編輯 | 吳先之每年的暑期檔都少不了瞄準追劇女孩們的古偶劇集,2021年有優(yōu)酷的《山河令》,2022年有愛奇藝的《蒼蘭訣》,今年卻輪到小破站抓住了追
  • 品牌洞察丨服務本地,美團直播成效幾何?

    來源:17PR7月11日,美團App首頁推薦位出現(xiàn)&ldquo;美團直播&rdquo;的固定入口。在直播聚合頁面,外賣&ldquo;神槍手&rdquo;直播間、美團旅行直播間、美團買菜直播間等均已上線,同時
  • 三星顯示已開始為AR設備研發(fā)硅基LED微顯示屏

    7月18日消息,據(jù)外媒報道,隨著蘋果首款頭顯產品Vision Pro在6月份正式推出,AR/VR/MR等頭顯產品也就將成為各大公司下一個重要的競爭領域,對顯示屏這一關
  • 電博會與軟博會實現(xiàn)"線下+云端"的雙線融合

    在本次“電博會”與“軟博會”雙展會利好條件的加持下,既可以發(fā)揮展會拉動人流、信息流、資金流實現(xiàn)快速交互流動的作用,繼而推動區(qū)域經(jīng)濟良性發(fā)展;又可以聚
Top