主頁 > 企業開發 > 為了實踐微前端,重構了自己的導航網站

為了實踐微前端,重構了自己的導航網站

2022-01-24 06:27:54 企業開發

筆者早期開發了一個導航網站,一直想要重構,因為懶拖了好幾年,終于,在了解到微前端大法后下了決心,因為作業上一直沒有機會實踐,沒辦法,只能用自己的網站試試,思來想去,訪問量最高的也就是這個破導航網站了,于是用最快的時間完成了基本功能的重構,然后準備通過微前端來擴展網站的功能,比如天氣、待辦、筆記、秒表計時等等,這些功能屬于附加的功能,可能會越來越多,所以不能和導航本身強耦合在一起,需要做到能獨立開發,獨立上線,所以使用微前端再合適不過了,

另外,因為有些功能可能非常簡單,比如秒表計時,單獨創建一個專案顯得沒有必要,但是又不想直接寫在導航的代碼里,最好是能直接通過Vue單檔案來開發,然后頁面上動態的進行加載渲染,所以會在微前端方式之外再嘗試一下動態組件,

本文內的專案都使用Vue CLI創建,Vue使用的是3.x版本,路由使用的都是hash模式

小程式注冊

為了顯得高大上一點,擴展功能我把它稱為小程式,首先要實作的是一個小程式的注冊功能,詳細來說就是:

1.提供一個表單,輸入小程式名稱、描述、圖示、url、型別(微前端方式還需要配置激活規則,組件方式需要配置樣式檔案的url),如下:

【粘貼圖片】

2.導航頁面上顯示注冊的小程式串列,點擊后渲染對應的小程式:

【粘貼圖片】

微前端方式

先來看看微前端的實作方式,筆者選擇的是qiankun框架,

主應用

主應用也就是導航網站,首先安裝qiankun

npm i qiankun -S

主應用需要做的很簡單,注冊微應用并啟動,然后提供一個容器給微應用掛載,最后打開指定的url即可,

因為微應用串列都存盤在資料庫里,所以需要先獲取然后進行注冊,創建qiankun.js檔案:

// qiankun.js
import { registerMicroApps, start } from 'qiankun'
import api from '@/api';

// 注冊及啟動
const registerAndStart = (appList) => {
  // 注冊微應用
  registerMicroApps(appList)

  // 啟動 qiankun
  start()
}

// 判斷是否激活微應用
const getActiveRule = (hash) => (location) => location.hash.startsWith(hash);

// 初始化小程式
export const initMicroApp = async () => {
  try {
    // 請求小程式串列資料
    let { data } = await api.getAppletList()
    // 過濾出微應用
    let appList = data.data.filter((item) => {
      return item.type === 'microApp';
    }).map((item) => {
      return {
        container: '#appletContainer',
        name: item.name,
        entry: item.url,
        activeRule: getActiveRule(item.activeRule)
      };
    })
    // 注冊并啟動微應用
    registerAndStart(appList)
  } catch (e) {
    console.log(e);
  }
}

一個微應用的資料示例如下:

{
  container: '#appletContainer',
  name: '后閣樓',
  entry: 'http://lxqnsys.com/applets/hougelou/',
  activeRule: getActiveRule('#/index/applet/hougelou')
}

可以看到提供給微應用掛載的容器為#appletContainer,微應用的訪問urlhttp://lxqnsys.com/applets/hougelou/,注意最后面的/不可省略,否則微應用的資源路徑可能會出現錯誤,

另外解釋一下激活規則activeRule,導航網站的url為:http://lxqnsys.com/d/#/index,微應用的路由規則為:applet/:appletId,所以一個微應用的激活規則為頁面urlhash部分,但是這里activeRule沒有直接使用字串的方式:#/index/applet/hougelou,這是因為筆者的導航網站并沒有部署在根路徑,而是在/d目錄下,所以#/index/applet/hougelou這個規則是匹配不到http://lxqnsys.com/d/#/index/applet/hougelou這個url的,需要這樣才行:/d/#/index/applet/hougelou,但是部署的路徑有可能會變,不方便直接寫到微應用的activeRule里,所以這里使用函式的方式,自行判斷是否匹配,也就是根據頁面的location.hash是否是以activeRule開頭的來判斷,是的話代表匹配到了,

微應用

微應用也就是我們的小程式專案,根據官方檔案的介紹Vue 微應用,首先需要在src目錄新增一個public-path.js

// public-path.js
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

然后修改main.js,增加qiankun的生命周期函式:

// main.js
import './public-path';
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

let app = null
const render = (props = {}) => {
    // 微應用使用方式時掛載的元素需要在容器的范圍下查找
    const { container } = props;
    app = createApp(App)
    app.use(router)
    app.mount(container ? container.querySelector('#app') : '#app')
}

// 獨立運行時直接初始化
if (!window.__POWERED_BY_QIANKUN__) {
    render();
}

// 三個生命周期函式
export async function bootstrap() {
    console.log('[后閣樓] 啟動');
}
export async function mount(props) {
    console.log('[后閣樓] 掛載');
    render(props);
}
export async function unmount() {
    console.log('[后閣樓] 卸載');
    app.unmount();
    app = null;
}

接下來修改打包配置vue.config.js

module.exports = {
    // ...
    configureWebpack: {
        devServer: {
            // 主應用需要請求微應用的資源,所以需要允許跨域訪問
            headers: {
                'Access-Control-Allow-Origin': '*'
            }
        },
        output: {
            // 打包為umd格式
            library: `hougelou`,
            libraryTarget: 'umd'
        }
    }
}

最后,還需要修改一下路由配置,有兩種方式:

1.設定base

import { createRouter, createWebHashHistory } from 'vue-router';

let routes = routes = [
    { path: '/', name: 'List', component: List },
    { path: '/detail/:id', name: 'Detail', component: Detail },
]

const router = createRouter({
    history: createWebHashHistory(window.__POWERED_BY_QIANKUN__ ? '/d/#/index/applet/hougelou/' : '/'),
    routes
})

export default router

這種方式的缺點也是把主應用的部署路徑寫死在base里,不是很優雅,

2.使用子路由

import { createRouter, createWebHashHistory } from 'vue-router';
import List from '@/pages/List';
import Detail from '@/pages/Detail';
import Home from '@/pages/Home';

let routes = []

if (window.__POWERED_BY_QIANKUN__) {
    routes = [{
        path: '/index/applet/hougelou/',
        name: 'Home',
        component: Home,
        children: [
            { path: '', name: 'List', component: List },
            { path: 'detail/:id', name: 'Detail', component: Detail },
        ],
    }]
} else {
    routes = [
        { path: '/', name: 'List', component: List },
        { path: '/detail/:id', name: 'Detail', component: Detail },
    ]
}

const router = createRouter({
    history: createWebHashHistory(),
    routes
})

export default router

在微前端環境下把路由都作為/index/applet/hougelou/的子路由,

效果如下:

圖片名稱

優化

1.回傳按鈕

如上面的效果所示,微應用內部頁面跳轉后,如果要回到上一個頁面只能通過瀏覽器的回傳按鈕,顯然不是很方便,可以在標題欄上添加一個回傳按鈕:

<div  v-if="isMicroApp" @click="back">
  <span ></span>
</div>
const back = () => {
  router.go(-1);
};

這樣當小程式為微應用時會顯示一個回傳按鈕,但是有一個問題,當在微應用的首頁時顯然是不需要這個回傳按鈕的,我們可以通過判斷當前的路由和微應用的activeRule是否一致,一樣的話就代表是在微應用首頁,那么就不顯示回傳按鈕:

<div  v-if="isMicroApp && isInHome" @click="back">
  <span ></span>
</div>
router.afterEach(() => {
  if (!isMicroApp.value) {
    return;
  }
  let reg = new RegExp("^#" + route.fullPath + "?$");
  isInHome.value = https://www.cnblogs.com/wanglinmantan/archive/2022/01/23/reg.test(payload.value.activeRule);
});

圖片名稱

2.微應用頁面切換時滾動位置恢復

如上面的動圖所示,當從串列頁進入到詳情頁再回傳串列時,串列回到了頂部,這樣的體驗是很糟糕的,我們需要記住滾動的位置并恢復,

可以通過把url和滾動位置關聯并記錄起來,在router.beforeEach時獲取當前的滾動位置,然后和當前的url關聯起來并存盤,當router.afterEach時根據當前url獲取存盤的資料并恢復滾動位置:

const scrollTopCache = {};
let scrollTop = 0;

// 監聽容器滾動位置
appletContainer.value.addEventListener("scroll", () => {
  scrollTop = appletContainer.value.scrollTop;
});

router.beforeEach(() => {
  // 快取滾動位置
  scrollTopCache[route.fullPath] = scrollTop;
});

router.afterEach(() => {
  if (!isMicroApp.value) {
    return;
  }
  // ...
  // 恢復滾動位置
  appletContainer.value.scrollTop = scrollTopCache[route.fullPath];
});

圖片名稱

3.初始url為小程式url的問題

正常在關閉小程式時會把頁面的路由恢復至頁面原本的路由,但是比如我在打開小程式的情況下直接重繪頁面,那么因為url滿足小程式的激活規則,所以qiankun會去加載對應的微應用,然而可能這時頁面上連微應用的容器都沒有,所以會報錯,解決這個問題可以在頁面加載后判斷初始路由是否是小程式的路由,是的話就恢復一下,然后再去注冊微應用:

if (/\/index\/applet\//.test(route.fullPath)) {
  router.replace("/index");
}
initMicroApp();

Vue組件方式

接下來看看使用Vue組件的方式,筆者的想法是直接使用Vue單檔案來開發,開發完成后打包成一個js檔案,然后在導航網站上請求該js檔案,并把它作為動態組件渲染出來,

簡單起見我們直接在導航專案下新建一個檔案夾作為小程式的目錄,這樣可以直接使用專案的打包工具,新增一個stopwatch測驗組件,目前目錄結構如下:

【粘貼圖片】

組件App.vue內容如下:

<template>
  <div >
    <div >{{ count }}</div>
    <button @click="start">開始</button>
  </div>
</template>

<script setup>
import { ref } from "vue";

const count = ref(0);
const start = () => {
  setInterval(() => {
    count.value++;
  }, 1000);
};
</script>

<style lang="less" scoped>
.countContainer {
  text-align: center;

  .count {
    color: red;
  }
}
</style>

index.js用來匯出組件:

import App from './App.vue';

export default App

// 配置資料
const config = {
    width: 450
}

export {
    config
}

為了個性化,還支持匯出它的配置資料,

接下來需要對組件進行打包,我們直接使用vue-clivue-cli支持指定不同的構建目標,默認為應用模式,我們平常專案打包運行的npm run build,其實運行的就是vue-cli-service build命令,可以通過選項來修改打包行為:

vue-cli-service build --target lib --dest dist_applets/stopwatch --name stopwatch --entry src/applets/stopwatch/index.js

上面這個配置就可以打包我們的stopwatch組件,選項含義如下:

--target      app | lib | wc | wc-async (默認為app應用模式,我們使用lib作為庫打包模式)
--dest        指定輸出目錄 (默認輸出到dist目錄,我們改成dist_applets目錄下)
--name        庫或 Web Components 模式下的名字 (默認值:package.json 中的 "name" 欄位或入口檔案名,我們改成組件名稱)
--entry       指定打包的入口,可以是.js或.vue檔案(也就是組件的index.js路徑)

更詳細的資訊可以移步官方檔案:構建目標、CLI 服務,

但是我們的組件是不定的,數量可能會越來越多,所以直接在命令列輸入命令打包會非常的麻煩,我們可以通過腳本來完成,在/applets/目錄下新增build.js

// build.js
const { exec } = require('child_process');
const path = require('path')
const fs = require('fs')

// 獲取組件串列
const getComps = () => {
    let res = []
    let files = fs.readdirSync(__dirname)
    files.forEach((filename) => {
        // 是否是目錄
        let dir = path.join(__dirname, filename)
        let isDir = fs.statSync(dir).isDirectory
        // 入口檔案是否存在
        let entryFile = path.join(dir, 'index.js')
        let entryExist = fs.existsSync(entryFile)
        if (isDir && entryExist) {
            res.push(filename)
        }
    })
    return res
}
let compList = getComps()
// 創建打包任務
let taskList = compList.map((comp) => {
    return new Promise((resolve, reject) => {
        exec(`vue-cli-service build --target lib --dest dist_applets/${comp} --name ${comp} --entry src/applets/${comp}/index.js`, (error, stdout, stderr) => {
            if (error) {
                reject(error)
            } else {
                resolve()
            }
        })
    });
})
Promise.all(taskList)
    .then(() => {
        console.log('打包成功');
    })
    .catch((e) => {
        console.error('打包失敗');
        console.error(e);
    })

然后去package.json新增如下命令:

{
  "scripts": {
    "buildApplets": "node ./src/applets/build.js"
  }
}

運行命令npm run buildApplets,可以看到打包結果如下:

【粘貼圖片】

我們使用其中css檔案和umd型別的js檔案,打開.umd.js檔案看看:

【粘貼圖片】

factory函式執行回傳的結果就是組件index.js里面匯出的資料,另外可以看到引入vue的代碼,這表明Vue是沒有包含在打包后的檔案里的,這是vue-cli刻意為之的,這在通過構建工具使用打包后的庫來說是很方便的,但是我們是需要直接在頁面運行的時候動態的引入組件,不經過打包工具的處理,所以exportsmoduledefinerequire等物件或方法都是沒有的,沒有沒關系,我們可以手動注入,我們使用第二個else if,也就是我們需要手動來提供exports物件和require函式,

當我們點擊Vue組件型別的小程式時我們使用axios來請求組件的js檔案,獲取到的是js字串,然后使用new Function來執行js,注入我們提供的exports物件和require函式,然后就可以通過exports物件獲取到組件匯出的資料,最后再使用動態組件渲染出組件即可,同時如果存在樣式檔案的話也要動態加載樣式檔案,

<template>
  <component v-if="comp" :is="comp"></component>
</template>
import * as Vue from 'vue';

const comp = ref(null);
const load = async () => {
    try {
      // 加載樣式檔案
      if (payload.value.styleUrl) {
        loadStyle(payload.value.styleUrl)
      }
      // 請求組件js資源
      let { data } = await axios.get(payload.value.url);
      // 執行組件js
      let run = new Function('exports', 'require', `return ${data}`)
      // 手動提供exports物件和require函式
      const exports = {}
      const require = () => {
        return Vue;
      }
      // 執行函式
      run(exports, require)
      // 獲取組件選項物件,扔給動態組件進行渲染
      comp.value = https://www.cnblogs.com/wanglinmantan/archive/2022/01/23/exports.stopwatch.default
    } catch (error) {
      console.error(error);
    }
};

執行完組件的js后我們注入的exports物件如下:

【粘貼圖片】

所以通過exports.stopwatch.default就能獲取到組件的選項物件傳遞給動態組件進行渲染,效果如下:

圖片名稱

大功告成,最后我們再稍微修改一下,因為通過exports.stopwatch.default獲取組件匯出內容我們還需要知道組件的打包名稱stopwatch,這顯然有點麻煩,我們可以改成一個固定的名稱,比如就叫comp,修改打包命令:

// build.js

// ...
exec(`vue-cli-service build --target lib --dest dist_applets/${comp} --name comp --entry src/applets/${comp}/index.js`, (error, stdout, stderr) => {
  if (error) {
    reject(error)
  } else {
    resolve()
  }
})
// ...

--name引數由之前的${name}改成寫死comp即可,打包結果如下:

【粘貼圖片】

exports物件結構變成如下:

【粘貼圖片】

然后我們就可以通過comp名稱來應對任何組件了comp.value = https://www.cnblogs.com/wanglinmantan/archive/2022/01/23/exports.comp.default

當然,小程式關閉的時候不要忘記洗掉添加的樣式節點,

總結

本文簡單了嘗試兩種網站功能的擴展方式,各位如果有更好的方式的話可以評論留言分享,線上效果演示地址http://lxqnsys.com/d/,

轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/419940.html

標籤:其他

上一篇:為了實踐微前端,重構了自己的導航網站

下一篇:如何在linux中批量重命名檔案并洗掉擴展后的附加字符

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • IEEE1588PTP在數字化變電站時鐘同步方面的應用

    IEEE1588ptp在數字化變電站時鐘同步方面的應用 京準電子科技官微——ahjzsz 一、電力系統時間同步基本概況 隨著對IEC 61850標準研究的不斷深入,國內外學者提出基于IEC61850通信標準體系建設數字化變電站的發展思路。數字化變電站與常規變電站的顯著區別在于程序層傳統的電流/電壓互 ......

    uj5u.com 2020-09-10 03:51:52 more
  • HTTP request smuggling CL.TE

    CL.TE 簡介 前端通過Content-Length處理請求,通過反向代理或者負載均衡將請求轉發到后端,后端Transfer-Encoding優先級較高,以TE處理請求造成安全問題。 檢測 發送如下資料包 POST / HTTP/1.1 Host: ac391f7e1e9af821806e890 ......

    uj5u.com 2020-09-10 03:52:11 more
  • 網路滲透資料大全單——漏洞庫篇

    網路滲透資料大全單——漏洞庫篇漏洞庫 NVD ——美國國家漏洞庫 →http://nvd.nist.gov/。 CERT ——美國國家應急回應中心 →https://www.us-cert.gov/ OSVDB ——開源漏洞庫 →http://osvdb.org Bugtraq ——賽門鐵克 →ht ......

    uj5u.com 2020-09-10 03:52:15 more
  • 京準講述NTP時鐘服務器應用及原理

    京準講述NTP時鐘服務器應用及原理京準講述NTP時鐘服務器應用及原理 安徽京準電子科技官微——ahjzsz 北斗授時原理 授時是指接識訓通過某種方式獲得本地時間與北斗標準時間的鐘差,然后調整本地時鐘使時差控制在一定的精度范圍內。 衛星導航系統通常由三部分組成:導航授時衛星、地面檢測校正維護系統和用戶 ......

    uj5u.com 2020-09-10 03:52:25 more
  • 利用北斗衛星系統設計NTP網路時間服務器

    利用北斗衛星系統設計NTP網路時間服務器 利用北斗衛星系統設計NTP網路時間服務器 安徽京準電子科技官微——ahjzsz 概述 NTP網路時間服務器是一款支持NTP和SNTP網路時間同步協議,高精度、大容量、高品質的高科技時鐘產品。 NTP網路時間服務器設備采用冗余架構設計,高精度時鐘直接來源于北斗 ......

    uj5u.com 2020-09-10 03:52:35 more
  • 詳細解讀電力系統各種對時方式

    詳細解讀電力系統各種對時方式 詳細解讀電力系統各種對時方式 安徽京準電子科技官微——ahjzsz,更多資料請添加VX 衛星同步時鐘是我京準公司開發研制的應用衛星授時時技術的標準時間顯示和發送的裝置,該裝置以M國全球定位系統(GLOBAL POSITIONING SYSTEM,縮寫為GPS)或者我國北 ......

    uj5u.com 2020-09-10 03:52:45 more
  • 如何保證外包團隊接入企業內網安全

    不管企業規模的大小,只要企業想省錢,那么企業的某些服務就一定會采用外包的形式,然而看似美好又經濟的策略,其實也有不好的一面。下面我通過安全的角度來聊聊使用外包團的安全隱患問題。 先看看什么服務會使用外包的,最常見的就是話務/客服這種需要大量重復性、無技術性的服務,或者是一些銷售外包、特殊的職能外包等 ......

    uj5u.com 2020-09-10 03:52:57 more
  • PHP漏洞之【整型數字型SQL注入】

    0x01 什么是SQL注入 SQL是一種注入攻擊,通過前端帶入后端資料庫進行惡意的SQL陳述句查詢。 0x02 SQL整型注入原理 SQL注入一般發生在動態網站URL地址里,當然也會發生在其它地發,如登錄框等等也會存在注入,只要是和資料庫打交道的地方都有可能存在。 如這里http://192.168. ......

    uj5u.com 2020-09-10 03:55:40 more
  • [GXYCTF2019]禁止套娃

    git泄露獲取原始碼 使用GET傳參,引數為exp 經過三層過濾執行 第一層過濾偽協議,第二層過濾帶引數的函式,第三層過濾一些函式 preg_replace('/[a-z,_]+\((?R)?\)/', NULL, $_GET['exp'] (?R)參考當前正則運算式,相當于匹配函式里的引數 因此傳遞 ......

    uj5u.com 2020-09-10 03:56:07 more
  • 等保2.0實施流程

    流程 結論 ......

    uj5u.com 2020-09-10 03:56:16 more
最新发布
  • 使用Django Rest framework搭建Blog

    在前面的Blog例子中我們使用的是GraphQL, 雖然GraphQL的使用處于上升趨勢,但是Rest API還是使用的更廣泛一些. 所以還是決定回到傳統的rest api framework上來, Django rest framework的官網上給了一個很好用的QuickStart, 我參考Qu ......

    uj5u.com 2023-04-20 08:17:54 more
  • 記錄-new Date() 我忍你很久了!

    這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 大家平時在開發的時候有沒被new Date()折磨過?就是它的諸多怪異的設定讓你每每用的時候,都可能不小心踩坑。造成程式意外出錯,卻一下子找不到問題出處,那叫一個煩透了…… 下面,我就列舉它的“四宗罪”及應用思考 可惡的四宗罪 1. Sa ......

    uj5u.com 2023-04-20 08:17:47 more
  • 使用Vue.js實作文字跑馬燈效果

    實作文字跑馬燈效果,首先用到 substring()截取 和 setInterval計時器 clearInterval()清除計時器 效果如下: 實作代碼如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta ......

    uj5u.com 2023-04-20 08:12:31 more
  • JavaScript 運算子

    JavaScript 運算子/運算子 在 JavaScript 中,有一些運算子可以使代碼更簡潔、易讀和高效。以下是一些常見的運算子: 1、可選鏈運算子(optional chaining operator) ?.是可選鏈運算子(optional chaining operator)。?. 可選鏈操 ......

    uj5u.com 2023-04-20 08:02:25 more
  • CSS—相對單位rem

    一、概述 rem是一個相對長度單位,它的單位長度取決于根標簽html的字體尺寸。rem即root em的意思,中文翻譯為根em。瀏覽器的文本尺寸一般默認為16px,即默認情況下: 1rem = 16px rem布局原理:根據CSS媒體查詢功能,更改根標簽的字體尺寸,實作rem單位隨螢屏尺寸的變化,如 ......

    uj5u.com 2023-04-20 08:02:21 more
  • 我的第一個NPM包:panghu-planebattle-esm(胖虎飛機大戰)使用說明

    好家伙,我的包終于開發完啦 歡迎使用胖虎的飛機大戰包!! 為你的主頁添加色彩 這是一個有趣的網頁小游戲包,使用canvas和js開發 使用ES6模塊化開發 效果圖如下: (覺得圖片太sb的可以自己改) 代碼已開源!! Git: https://gitee.com/tang-and-han-dynas ......

    uj5u.com 2023-04-20 08:01:50 more
  • 如何在 vue3 中使用 jsx/tsx?

    我們都知道,通常情況下我們使用 vue 大多都是用的 SFC(Signle File Component)單檔案組件模式,即一個組件就是一個檔案,但其實 Vue 也是支持使用 JSX 來撰寫組件的。這里不討論 SFC 和 JSX 的好壞,這個仁者見仁智者見智。本篇文章旨在帶領大家快速了解和使用 Vu ......

    uj5u.com 2023-04-20 08:01:37 more
  • 【Vue2.x原始碼系列06】計算屬性computed原理

    本章目標:計算屬性是如何實作的?計算屬性快取原理以及洋蔥模型的應用?在初始化Vue實體時,我們會給每個計算屬性都創建一個對應watcher,我們稱之為計算屬性watcher ......

    uj5u.com 2023-04-20 08:01:31 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:01:10 more
  • http1.1與http2.0

    一、http是什么 通俗來講,http就是計算機通過網路進行通信的規則,是一個基于請求與回應,無狀態的,應用層協議。常用于TCP/IP協議傳輸資料。目前任何終端之間任何一種通信方式都必須按Http協議進行,否則無法連接。tcp(三次握手,四次揮手)。 請求與回應:客戶端請求、服務端回應資料。 無狀態 ......

    uj5u.com 2023-04-20 08:00:32 more