主頁 > 企業開發 > Vue.js 3.x 優化概覽

Vue.js 3.x 優化概覽

2022-04-22 08:43:21 企業開發

本文整理自拉勾網Vue.js 3.x 原始碼課程,講師是來自Zoom的大牛黃軼,非常感謝! 本人僅補充一些參考資料,

1. Vue.js框架的演程序序

Vue.js 從 1.x 到 2.0 版本,最大的升級就是引入了虛擬 DOM 的概念,

image-20220412212335522

Vue.js 2.x 的版本痛點問題:

  • 原始碼自身的維護性;
  • 資料量大后帶來的渲染和更新的性能問題;
  • 雞肋 API;
  • TypeScript 支持不佳;
  • ...

Vue.js 3.x 帶來的優化

  • 原始碼優化

  • 性能優化

  • 語法Api優化

    image-20220412212300757

2. Vue.js 3.0 優化概覽

那么接下來,我們就一起來看一下 Vue.js 3.0 具體做了哪些優化,

2.1 原始碼優化

首先是原始碼優化,也就是祖師爺對于 Vue.js 框架本身開發的優化,它的目的是讓代碼更易于開發和維護,

原始碼的優化主要體現在使用 monorepoTypeScript 管理和開發原始碼,這樣做的目標是提升自身代碼可維護性,接下來我們就來看一下這兩個方面的具體變化,

2.1.1 更好的代碼管理方式:monorepo

  1. 什么是monorepo?

就是把多個專案放在一個倉庫里面,相對立的是傳統的 MultiRepo 模式,即每個專案對應一個單獨的倉庫來分散管理,

img

  1. monorepo 解決什么問題?
    • 多個repo難以管理,編輯器需要打開多個專案;

    • 某個模塊升級,依賴改模塊的其他模塊需要手動升級,容易疏漏;

    • 公用的npm包重復安裝,占據大量硬碟容量,比如打包工具webpack會在每個專案中安裝一次;

    • 對新人友好,一句命令即可完成所有模塊的依賴安裝,且整個專案模塊不用到各個倉庫去找;

  2. monorepo 在vue.js 3.x 中的應用

原始碼的優化體現在代碼管理方式上,

Vue.js 2.x 的原始碼托管在 src 目錄,然后依據功能拆分出了

  • compiler(模板編譯的相關代碼)
  • core(與平臺無關的通用運行時代碼)
  • platforms(平臺專有代碼)
  • server(服務端渲染的相關代碼)
  • sfc(.vue 單檔案決議相關代碼)
  • shared(共享工具代碼)

等目錄:

Drawing 0.png

而到了 Vue.js 3.0 ,整個原始碼是通過 monorepo 的方式維護的,根據功能將不同的模塊拆分到 packages 目錄下面不同的子目錄中:

Drawing 1.png

可以看出相對于 Vue.js 2.x 的原始碼組織方式,monorepo 把這些模塊拆分到不同的 package 中,每個 package 有各自的 API、型別定義和測驗,

這樣做的優勢在于:

  • 使得模塊拆分更細化,職責劃分更明確,模塊之間的依賴關系也更加明確
  • 開發人員也更容易閱讀、理解和更改所有模塊原始碼,提高代碼的可維護性,
  • 一些 package(比如 reactivity 回應式庫)是可以獨立于 Vue.js 使用的,這樣用戶如果只想使用 Vue.js 3.0 的回應式能力,可以單獨依賴這個回應式庫而不用去依賴整個 Vue.js,減小了參考包的體積大小,而 Vue.js 2 .x 是做不到這一點的,

參考資料:

  • 什么是monorepo?
  • Vue3.0 中的 monorepo 管理模式
  • 現代前端工程為什么越來越離不開 Monorepo?

2.1.2 有型別的 JavaScript:TypeScript

原始碼的優化還體現在 Vue.js 3.0 自身采用了 TypeScript 開發,

Vue.js 1.x 版本的原始碼是沒有用型別語言的,祖師爺用 JavaScript 開發了整個框架,但對于復雜的框架專案開發,使用型別語言非常有利于代碼的維護,因為它可以在編碼期間幫你做型別檢查,避免一些因型別問題導致的錯誤;也可以利于它去定義介面的型別,利于 IDE 對變數型別的推導,

因此在重構 2.0 的時候,祖師爺選型了 Flow(Flow是JavaScript代碼的靜態型別檢查器,),

參考資料:

  • Flowjs官方檔案
  • Flow和TypeScript之間的區別和優劣

但是在 Vue.js 3.0 的時候拋棄 Flow 轉而采用 TypeScript 重構了整個專案,這里有兩方面原因:

首先,Flow 是 Facebook 出品的 JavaScript 靜態型別檢查工具,它可以以非常小的成本對已有的 JavaScript 代碼遷入,非常靈活,這也是 Vue.js 2.0 當初選型它時一方面的考量,但是 Flow 對于一些復雜場景型別的檢查,支持得并不好

其次,Vue.js 3.0 拋棄 Flow 后,使用 TypeScript 重構了整個專案, TypeScript提供了更好的型別檢查,能支持復雜的型別推導;由于原始碼就使用 TypeScript 撰寫,也省去了單獨維護 d.ts 檔案的麻煩;就整個 TypeScript 的生態來看,TypeScript 團隊也是越做越好,TypeScript 本身保持著一定頻率的迭代和更新,支持的 feature 也越來越多,

2.2 性能優化

2.2.1 原始碼體積優化

首先是原始碼體積優化,我們在平時作業中也經常會嘗試優化靜態資源的體積,因為 JavaScript 包體積越小,意味著網路傳輸時間越短,JavaScript 引擎決議包的速度也越快,

那么,Vue.js 3.0 在原始碼體積的減少方面做了哪些作業呢?

  1. 移除一些冷門的 feature

    比如 filter、inline-template 等

  2. 引入 tree-shaking 的技術,減少打包體積

    Tree shaking 是一個通常用于描述移除 JavaScript 背景關系中的未參考代碼(dead-code) 行為的術語,

    它依賴于ES2015中的 import 和 export 陳述句,用來檢測代碼模塊是否被匯出、匯入,且被 JavaScript 檔案使用,

    在現代 JavaScript 應用程式中,我們使用模塊打包(如webpack或Rollup)將多個 JavaScript 檔案打包為單個檔案時自動洗掉未參考的代碼,這對于準備預備發布代碼的作業非常重要,這樣可以使最終檔案具有簡潔的結構和最小化大小,

    參考資料:

    • 從過去到現在,聊聊 Tree-shaking 是什么?

第一點很好理解,所以這里我們來看看 tree-shaking,它的原理很簡單,tree-shaking 依賴 ES2015 模塊語法的靜態結構(即 import 和 export),通過編譯階段的靜態分析,找到沒有引入的模塊并打上標記,

舉個例子,一個 math 模塊定義了 2 個方法 square(x) 和 cube(x) :

export function square(x) {
  return x * x
}

export function cube(x) {
  return x * x * x
}

我們在這個模塊外面只引入了 cube 方法:

import { cube } from './math.js'
// do something with cube

最終 math 模塊會被 webpack 打包生成如下代碼:

/* 1 */

/***/ (function(module, __webpack_exports__, __webpack_require__) {
  'use strict';
  /* unused harmony export square */
  /* harmony export (immutable) */ __webpack_exports__['a'] = cube;
  function square(x) {
    return x * x;
  }
  function cube(x) {
    return x * x * x;
  }
});

可以看到,未被引入的 square 模塊被標記了, 然后壓縮階段會利用例如 uglify-js、terser 等壓縮工具真正地洗掉這些沒有用到的代碼,

也就是說,利用 tree-shaking 技術,如果你在專案中沒有引入 Transition、KeepAlive 等組件,那么它們對應的代碼就不會打包,這樣也就間接達到了減少專案引入的 Vue.js 包體積的目的,

2.2.2 資料劫持優化

2.2.2.1 資料回應式

Vue.js 區別于 React 的一大特色是它的資料是回應式的,這個特性從 Vue.js 1.x 版本就一直伴隨著,這也是 Vue.js 粉喜歡 Vue.js 的原因之一,

DOM 是資料的一種映射,資料發生變化后可以自動更新 DOM,用戶只需要專注于資料的修改,沒有其余的心智負擔,

在 Vue.js 內部,想實作這個功能是要付出一定代價的,那就是必須劫持資料的訪問和更新

其實這點很好理解,當資料改變后,為了自動更新 DOM,那么就必須劫持資料的更新,也就是說當資料發生改變后能自動執行一些代碼去更新 DOM,

那么問題來了,Vue.js 怎么知道更新哪一片 DOM 呢?

因為在渲染 DOM 的時候訪問了資料,我們可以對它進行訪問劫持,這樣就在內部建立了依賴關系,也就知道資料對應的 DOM 是什么了,

以上只是大體的思路,具體實作要比這更復雜,內部還依賴了一個 watcher 的資料結構做依賴管理,參考下圖:

1.png

2.2.2.2 回應式實作方案
  1. Vue.js 1.x 和 Vue.js 2.x 版本

Vue.js 1.x 和 Vue.js 2.x 內部都是通過 Object.defineProperty 這個 API 去劫持資料的 getter 和 setter,具體是這樣的:

Object.defineProperty(data, 'a',{
  get(){
    // track
  },
  set(){
    // trigger
  }
})

但這個 API 有一些缺陷

  • 它必須預先知道要攔截的 key 是什么,所以它并不能檢測物件屬性的添加和洗掉

    var vm = new Vue({
      data: {
        a: 1
      }
    })
    // `vm.a` 現在是回應式的
    vm.b = 2
    // `vm.b` 不是回應式的
    

? 盡管 Vue.js 為了解決這個問題提供了 $set 和 $delete 實體方法,但是對于用戶來說,還是增加了一定的心智負擔,

Vue 2 中更改檢測的注意事項——$set

  • 另外 Object.defineProperty 的方式還有一個問題,舉個例子,比如這個嵌套層級比較深的物件:
export default {
  data: {
    a: {
      b: {
        c: {
          d: 1
        }
      }
    }
  }
}

由于 Vue.js 無法判斷你在運行時到底會訪問到哪個屬性,所以對于這樣一個嵌套層級較深的物件,如果要劫持它內部深層次的物件變化,就需要遞回遍歷這個物件,執行 Object.defineProperty 把每一層物件資料都變成回應式的,毫無疑問,如果我們定義的回應式資料過于復雜,這就會有相當大的性能負擔

  1. Vue.js 3.x 版本

為了解決上述 2 個問題,Vue.js 3.0 使用了 Proxy API 做資料劫持,它的內部是這樣的:

observed = new Proxy(data, {
  get() {
    // track
  },
  set() {
    // trigger
  }
})

由于它劫持的是整個物件,那么自然對于物件的屬性的增加和洗掉都能檢測到,

但要注意的是,Proxy API 并不能監聽到內部深層次的物件變化,因此 Vue.js 3.x 的處理方式是在 getter 中去遞回回應式,這樣的好處是真正訪問到的內部物件才會變成回應式,而不是無腦遞回,這樣無疑也在很大程度上提升了性能,Vue.js 3.x 中回應式的實作程序比較復雜,在此不展開講解,

2.2.3 編譯優化

最后是編譯優化,為了便于理解,我們先來看一張圖:

2.png

這是 Vue.js 2.x 從 new Vue 開始渲染成 DOM 的流程,上面說過的回應式程序就發生在圖中的 init 階段,另外 template compile to render function 的流程是可以借助 vue-loader 在 webpack 編譯階段離線完成,并非一定要在運行時完成,

所以想優化整個 Vue.js 的運行時,除了資料劫持部分的優化,我們可以在耗時相對較多的 patch 階段想辦法,Vue.js 3.0 也是這么做的,并且它通過在編譯階段優化編譯的結果,來實作運行時 patch 程序的優化,

通過資料劫持和依賴收集,Vue.js 2.x 的資料更新并觸發重新渲染的粒度是組件級的:

3.png

雖然 Vue 能保證觸發更新的組件最小化,但在單個組件內部依然需要遍歷該組件的整個 vnode 樹,舉個例子,比如我們要更新這個組件:

<template>
  <div id="content">
    <p >static text</p>
    <p >static text</p>
    <p >{{message}}</p>
    <p >static text</p>
    <p >static text</p>
  </div>
</template>

整個 diff 程序如圖所示:

圖片1.png

可以看到,因為這段代碼中只有一個動態節點,所以這里有很多 diff 和遍歷其實都是不需要的,這就會導致 vnode 的性能跟模版大小正相關,跟動態節點的數量無關,當一些組件的整個模版內只有少量動態節點時,這些遍歷都是性能的浪費,

而對于上述例子,理想狀態只需要 diff 這個系結 message 動態節點的 p 標簽即可,

Vue.js 3.0 做到了,它通過編譯階段對靜態模板的分析,編譯生成了 Block tree,Block tree 是一個將模版基于動態節點指令切割的嵌套區塊,每個區塊內部的節點結構是固定的,而且每個區塊只需要以一個 Array 來追蹤自身包含的動態節點,借助 Block tree,Vue.js 將 vnode 更新性能由與模版整體大小相關提升為與動態內容的數量相關,這是一個非常大的性能突破,此程序比較復雜,

除此之外,Vue.js 3.0 在編譯階段還包含了對 Slot 的編譯優化、事件偵聽函式的快取優化,并且在運行時重寫了 diff 演算法等,

2.3 語法 API 優化:Composition API

除了原始碼和性能方面,Vue.js 3.0 還在語法方面進行了優化,主要是提供了 Composition API,

2.3.1 優化邏輯組織

首先,是優化邏輯組織,

在 Vue.js 1.x 和 2.x 版本中,撰寫組件本質就是在撰寫一個“包含了描述組件選項的物件”,我們把它稱為 Options API,它的好處是在于寫法非常符合直覺思維,對于新手來說這樣很容易理解,這也是很多人喜歡 Vue.js 的原因之一,

Options API 的設計是按照 methodscomputeddataprops 這些不同的選項分類,當組件小的時候,這種分類方式一目了然;但是在大型組件中,一個組件可能有多個邏輯關注點,當使用 Options API 的時候,每一個關注點都有自己的 Options,如果需要修改一個邏輯點關注點,就需要在單個檔案中不斷上下切換和尋找,

舉一個官方例子 Vue CLI UI file explorer,它是 vue-cli GUI 應用程式中的一個復雜的檔案瀏覽器組件,這個組件需要處理許多不同的邏輯關注點:

  • 跟蹤當前檔案夾狀態并顯示其內容
  • 處理檔案夾導航(比如打開、關閉、重繪等)
  • 處理新檔案夾的創建
  • 切換顯示收藏夾
  • 切換顯示隱藏檔案夾
  • 處理當前作業目錄的更改

如果我們按照邏輯關注點做顏色編碼,就可以看到當使用 Options API 去撰寫組件時,這些邏輯關注點是非常分散的:

Drawing 6.png

Vue.js 3.0 提供了一種新的 API:Composition API,它有一個很好的機制去解決這樣的問題,就是將某個邏輯關注點相關的代碼全都放在一個函式里,這樣當需要修改一個功能時,就不再需要在檔案中跳來跳去,

通過下圖,我們可以很直觀地感受到 Composition API 在邏輯組織方面的優勢:

Drawing 7.png

2.3.2 優化邏輯復用

其次,是優化邏輯復用,

當我們開發專案變得復雜的時候,免不了需要抽象出一些復用的邏輯,在 Vue.js 2.x 中,我們通常會用 mixins 去復用邏輯,舉一個滑鼠位置偵聽的例子,我們會撰寫如下函式 mousePositionMixin:

const mousePositionMixin = {
  data() {
    return {
      x: 0,
      y: 0
    }
  },
  mounted() {
    window.addEventListener('mousemove', this.update)
  },

  destroyed() {
    window.removeEventListener('mousemove', this.update)
  },
  methods: {
    update(e) {
      this.x = e.pageX
      this.y = e.pageY
    }
  }
}
export default mousePositionMixin

然后在組件中使用:

<template>
  <div>
    Mouse position: x {{ x }} / y {{ y }}
  </div>
</template>
<script>
import mousePositionMixin from './mouse'
export default {
  mixins: [mousePositionMixin]
}
</script>

使用單個 mixin 似乎問題不大,但是當我們一個組件混入大量不同的 mixins 的時候,會存在兩個非常明顯的問題:

  • 命名沖突
  • 資料來源不清晰

首先每個 mixin 都可以定義自己的 props、data,它們之間是無感的,所以很容易定義相同的變數,導致命名沖突,

另外對組件而言,如果模板中使用不在當前組件中定義的變數,那么就會不太容易知道這些變數在哪里定義的,這就是資料來源不清晰,

但是Vue.js 3.0 設計的 Composition API,就很好地幫助我們解決了 mixins 的這兩個問題,

我們來看一下在 Vue.js 3.0 中如何書寫這個示例:

import { ref, onMounted, onUnmounted } from 'vue'
export default function useMousePosition() {
  const x = ref(0)
  const y = ref(0)
  const update = e => {
    x.value = https://www.cnblogs.com/CherishTheYouth/archive/2022/04/21/e.pageX
    y.value = e.pageY
  }
  onMounted(() => {
    window.addEventListener('mousemove', update)
  })
  onUnmounted(() => {
    window.removeEventListener('mousemove', update)
  })
  return { x, y }
}

這里我們約定 useMousePosition 這個函式為 hook 函式,然后在組件中使用:

<template>
  <div>
    Mouse position: x {{ x }} / y {{ y }}
  </div>
</template>
<script>
  import useMousePosition from './mouse'
  export default {
    setup() {
      const { x, y } = useMousePosition()
      return { x, y }
    }
  }
</script>

可以看到,整個資料來源清晰了,即使去撰寫更多的 hook 函式,也不會出現命名沖突的問題,

Composition API 除了在邏輯復用方面有優勢,也會有更好的型別支持,因為它們都是一些函式,在呼叫函式時,自然所有的型別就被推匯出來了,不像 Options API 所有的東西使用 this,

另外,Composition API 對 tree-shaking 友好,代碼也更容易壓縮,

3.總結

以上就是Vue.js 3.x 大版本所做的優化,在實際專案開發中,Vue.js 3.x 相對于 Vue.js 2.x 來說,確實能帶來更好的開發體驗和較大的性能提升,

作者:CherishTheYouth 出處:https://www.cnblogs.com/CherishTheYouth/ 宣告:本文著作權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文鏈接,對于本博客如有任何問題,可發郵件與我溝通,我的QQ郵箱是:[email protected]

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

標籤:其他

上一篇:24張圖攻克border-image

下一篇:徹底學會快速部署vue框架,一篇就夠了

標籤雲
其他(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