主頁 > 企業開發 > Vue 的優化技巧

Vue 的優化技巧

2023-02-10 08:28:12 企業開發

演示代碼使用 Vue3 + ts + Vite 撰寫,但是也會列出適用于 Vue2 的優化技巧,如果某個優化只適用于 Vue3 或者 Vue2,我會在標題中標出來,

代碼優化

v-for 中使用 key


使用 v-for 更新已經渲染的元素串列時,默認用就地復用策略;串列資料修改的時候,他會根據 key 值去判斷某個值是否修改,如果修改,則重新渲染這一項,否則復用之前的元素;

使用key的注意事項:

  • 不要使用可能重復的或者可能變化 key 值(控制臺也會給出提醒)
  • 如果陣列中的資料有狀態需要維持時(例如輸入框),不要使用陣列的 index 作為 key 值,因為如果在陣列中插入或者移除一個元素時,其后面的元素 index 將會變化,這回讓vue進行原地復用時錯誤的系結狀態,
  • 如果陣列中沒有唯一的 key值可用,且陣列更新時不是全量更新而是采用類似push,splice來插入或者移除資料時,可以考慮對其添加一個 key 欄位,值為 Symbol() 即可保證唯一,

何時使用何種key?

這是一個非常有考究的問題,首先你要知道 vue 中的 原地復用 (大概就是 虛擬dom 變化時,兩個 虛擬dom節點key 如果一樣就不會重新創建節點,而是修改原來的節點),

當我們渲染的資料不需要保持狀態時,例如常見的單純的表格分頁渲染(不包含輸入,只是展示)、下拉加載更多等場景,那么使用 index 作為 key 再好不過,因為進入下一頁或者上一頁時就會原地復用之前的節點,而不是重新創建,如果使用唯一的 id 作為 key 反而會重新創建dom,性能相對較低,

此外使用 index 作為 key 我還應該要盡量避免對陣列的中間進行 增加/洗掉 等會影響后面元素key變化的操作,這會讓 vue 認為后面所有元素都發生了變化,導致多余的對比和原地復用,

所以使用 index 作為 key 需要滿足:

  1. 資料沒有獨立的狀態
  2. 資料不會進行 增加/洗掉 等會影響后面元素key變化的操作

哪何時使用 id 作為 key 呢?

對于大多數資料的 id 都是唯一的,這無疑的一個 key 的優選答案,對于任何大多數情況使用 id 作為 key 都不會出現上面 bug,但是如果你需要考慮性能問題,那就就要思考是否應該使用原地復用了,

同樣是上面的分頁資料展示,如果使用 id 作為 key ,可想而知每一頁的每一條資料 id 都是不一樣的,所以當換頁時兩顆 虛擬DOM樹 的節點的 key 完全不一致,vue 就會移除原來的節點然后創建新的節點,可想而知效率會更加低下,但是他也有它的優點,唯一的 key 可以幫助 diff 更加精確的為我們系結狀態,這尤其適合資料有獨立的狀態的場景,例如帶輸入框或者單選框的串列資料,

所以何時使用 id 作為 key?只有一點:

  1. 無法使用 index 作為 key 的時候

v-for 和 v-if 不要一起使用(Vue2)


此優化技巧僅限于Vue2,Vue3 中對 v-for 和 v-if 的優先級做了調整

這個大家都知道

永遠不要把 v-ifv-for 同時用在同一個元素上,

原因是 v-for 的 優先級高于 v-if,所以當它們使用再同一個標簽上是,每一個渲染都會先回圈再進行條件判斷,

注意: Vue3 中 v-if 優先級高于 v-for,所以當 v-forv-if 一起使用時效果類似于 Vue2 中把 v-if 上提的效果

例如下面這段代碼在 Vue2 中是不被推薦的,Vue 也會給出對應的警告.

<ul>
  <li v-for="user in users" v-if="user.active">
    {{ user.name }}
  </li>
</ul>

我們應該盡量將 v-if 移動到上級或者使用計算屬性來處理資料.

<ul v-if="active">
  <li v-for="user in users">
    {{ user.name }}
  </li>
</ul>

如果你不想讓回圈的內容多出一個無需有的上級容器,那么你可以選擇使用 template 來作為其父元素,template 不會被瀏覽器渲染為 DOM 節點.

如果我想要判斷遍歷物件里面每一項的內容來選擇渲染的資料的話,可以使用 computed 來對遍歷物件進行過濾.

// js
let usersActive = computed(()=>users.filter(user => user.active))

// template
<ul>
    <li v-for="user in usersActive">
      {{ user.name }}
    </li>
</ul>

合理的選擇 v-if 和 v-show


v-ifv-show 的區別相比大家都非常熟悉了;v-if 通過直接操作 DOM 的洗掉和添加來控制元素的顯示和隱藏;v-show 是通過控制 DOMdisplay CSS熟悉來控制元素的顯示和隱藏.

由于對 DOM 的 添加/洗掉 操作性能遠遠低于操作 DOM 的 CSS 屬性.

所以當元素需要頻繁的 顯示/隱藏 變化時,我們使用 v-show 來提高性能,

當元素不需要頻繁的 顯示/隱藏 變化時,我們通過 v-if 來移除 DOM 可以節約掉瀏覽器渲染這個的一部分DOM需要的資源.

使用簡單的計算屬性


應該把復雜計算屬性分割為盡可能多的更簡單的 property,

  • 易于測驗
    當每個計算屬性都包含一個非常簡單且很少依賴的運算式時,撰寫測驗以確保其正確作業就會更加容易,
  • 易于閱讀
    簡化計算屬性要求你為每一個值都起一個描述性的名稱,即便它不可復用,這使得其他開發者 (以及未來的你) 更容易專注在他們關心的代碼上并搞清楚發生了什么,
  • 更好的“擁抱變化”
    任何能夠命名的值都可能用在視圖上,舉個例子,我們可能打算展示一個資訊,告訴用戶他們存了多少錢;也可能打算計算稅費,但是可能會分開展現,而不是作為總價的一部分,
    小的、專注的計算屬性減少了資訊使用時的假設性限制,所以需求變更時也用不著那么多重構了,

computed 大家很熟悉, 它會在其運算式中依賴的回應式資料發送變化時重新計算,如果我們在一個計算屬性中書寫了比較復雜的運算式,那么其依賴的回應式資料也任意變得更多,當其中任何一個依賴項變化時整個運算式都需要重新計算.

let price = computed(()=>{
  let basePrice = manufactureCost / (1 - profitMargin)
  return (
      basePrice -
      basePrice * (discountPercent || 0)
  )
})

當 manufactureCost、profitMargin、discountPercent 中任何一個變化時都會重新計算整個 price,

但是如果我們改成下面這樣

let basePrice = computed(() => manufactureCost / (1 - profitMargin))
let discount = computed(() => basePrice * (discountPercent || 0))
let finalPrice = computed(() => basePrice - discount)

如果當 discountPercent 變化時,只會 重新計算 discount 和 finalPrice,由于 computed 的快取特性,不會重新計算 basePrice.

functional 函式式組件(Vue2)


注意:這僅僅在 Vue2 中被作為一種優化手段,在 3.x 中,有狀態組件和函式式組件之間的性能差異已經大大減少,并且在大多數用例中是微不足道的,因此,在 SFC 上使用 functional 的開發人員的遷移路徑是洗掉該 attribute,并將 props 的所有參考重命名為 $props,將 attrs 重命名為 $attrs

優化前:

<template>
    <div >
        <div v-if="value" ></div>
        <section v-else ></section>
    </div>
</template>

<script>
export default {
    props: ['value'],
}
</script>

優化后:

<template functional>
    <div >
        <div v-if="props.value" ></div>
        <section v-else ></section>
    </div>
</template>

<script>
export default {
    props: ['value'],
}
</script>
  • 沒有this(沒有實體)
  • 沒有回應式資料

拆分組件


什么?你寫的一個vue檔案有一千多行代碼???

合理的拆分組件不僅僅可以優化性能,還能夠讓代碼更清晰可讀,單一功能原則嘛.

優化前:

<template>
  <div :style="{ opacity: number / 300 }">
    <div>{{ heavy() }}</div>
  </div>
</template>

<script>
export default {
  props: ['number'],
  methods: {
    heavy () { /* HEAVY TASK */ }
  }
}
</script>

優化后:

<template>
  <div :style="{ opacity: number / 300 }">
    <ChildComp/>
  </div>
</template>

<script>
export default {
  props: ['number'],
  components: {
    ChildComp: {
      methods: {
        heavy () { /* HEAVY TASK */ }
      },
      render (h) {
        return h('div', this.heavy())
      }
    }
  }
}
</script>

由于 Vue 的更新是組件粒度的,雖然每一幀都通過資料修改導致了父組件的重新渲染,但是 ChildComp 卻不會重新渲染,因為它的內部也沒有任何回應式資料的變化,所以優化后的組件不會在每次渲染都執行耗時任務.

使用區域變數


優化前:

<template>
  <div :style="{ opacity: start / 300 }">{{ result }}</div>
</template>

<script>
import { heavy } from '@/utils'

export default {
  props: ['start'],
  computed: {
    base () { return 42 },
    result () {
      let result = this.start
      for (let i = 0; i < 1000; i++) {
        result += heavy(this.base)
      }
      return result
    }
  }
}
</script>

優化后:

<template>
  <div :style="{ opacity: start / 300 }">
    {{ result }}
  </div>
</template>

<script>
import { heavy } from '@/utils'

export default {
  props: ['start'],
  computed: {
    base () { return 42 },
    result () {
      const base = this.base
      let result = this.start
      for (let i = 0; i < 1000; i++) {
        result += heavy(base)
      }
      return result
    }
  }
}
</script>

這里主要是優化前后的組件的計算屬性 result 的實作差異,優化前的組件多次在計算程序中訪問 this.base,而優化后的組件會在計算前先用區域變數 base,快取 this.base,后面直接訪問 base

那么為啥這個差異會造成性能上的差異呢,原因是你每次訪問 this.base 的時候,由于 this.base 是一個回應式物件,所以會觸發它的 getter,進而會執行依賴收集相關邏輯代碼,類似的邏輯執行多了,像示例這樣,幾百次回圈更新幾百個組件,每個組件觸發 computed 重新計算,然后又多次執行依賴收集相關邏輯,性能自然就下降了,

從需求上來說,this.base 執行一次依賴收集就夠了,把它的 getter 求值結果回傳給區域變數 base,后續再次訪問 base 的時候就不會觸發 getter,也不會走依賴收集的邏輯了,性能自然就得到了提升,

使用 KeepAlive


在一些渲染成本比較高的組件需要被經常切換時,可以使用 keep-alive 來快取這個組件.

而在使用 keep-alive 后,被 keep-alive 包裹的組件在經過第一次渲染后,的 vnode 以及 DOM 都會被快取起來,然后再下一次再次渲染該組件的時候,直接從快取中拿到對應的 vnodeDOM,然后渲染,并不需要再走一次組件初始化,renderpatch 等一系列流程,減少了 script 的執行時間,性能更好,

注意:濫用 keep-alive 只會讓你的應用變得更加卡頓,因為他會長期占用較大的記憶體.

事件的銷毀


當一個組件被銷毀時,我們應該清除組件中添加的 全域事件 和 定時器 等來防止記憶體泄漏.

Vue3 的 HOOK 可以讓我們將事件的宣告和銷毀寫在一起,更加可讀.

function scrollFun(){ /* ... */}
document.addEventListener("scroll", scrollFun)

onBeforeUnmount(()=>{
  document.removeEventListener("scroll", scrollFun)
})

Vue2 依然可以通過 $once 來做到這樣的效果,當然你也可以在 optionsAPI beforeDestroy 中銷毀事件,但是我更加推薦前者的寫法,因為后者會讓相同功能的代碼更分散.

function scrollFun(){ /* ... */}
document.addEventListener("scroll", scrollFun)

this.$once('hook:beforeDestroy', ()=>{
  document.removeEventListener("scroll", scrollFun)
})
function scrollFun(){ /* ... */}

export default {
  created() {
    document.addEventListener("scroll", scrollFun)
  },
  beforeDestroy(){
    document.removeEventListener("scroll", scrollFun)
  }
}

圖片加載


圖片懶加載:適用于頁面上有較多圖片且并不是所有圖片都在一屏中展示的情況,vue-lazyload 插件給我們提供了一個很方便的圖片懶加載指令 v-lazy.

但是并不是所有圖片都適合使用懶加載,例如 banner、相冊等 更加推薦使用圖片預加載技術,將當前展示圖片的前一張和后一張優先下載,

使用合適的圖片型別


使用webp格式:這個沒什么好說的,大家都知道WebP的優勢體現在它具有更優的影像資料壓縮演算法,能帶來更小的圖片體積,而且擁有肉眼識別無差異的影像質量;同時具備了無損和有損的壓縮模式、Alpha 透明以及影片的特性,在 JPEG 和 PNG 上的轉化效果都相當優秀、穩定和統一,

使用交錯GIF或者是漸進JPEG:還有一種優化用戶體驗的方式,就是使用交錯GIF或者是漸進(Progressive Encoding)JPEG的圖片,漸進JPEG檔案首先是模糊的,然后漸漸清晰起來,

Baseline JPEG 和 Progressive JPEG 的區別:

  • Baseline JPEG
    image

  • Progressive JPEG
    image

JPEG檔案格式有兩種保存方式,他們是Baseline JPEG和Progressive JPEG,

兩種格式有相同尺寸以及影像資料,他們的擴展名也是相同的,唯一的區別是二者顯示的方式不同,

Progressive JPEG的優點:

  • 用戶體驗 一個以progressive方式編碼的jpeg檔案,在瀏覽器上的渲染方式是由模糊到清晰的,用戶能在漸變的影像當中獲得所需資訊的反饋,如果內容不是用戶所期待的,用戶就能提前前往新的頁面,
  • 檔案大小 有實驗證明,在JPEG檔案小于10KB的時候,使用標準型編碼(Huffman表已經被優化)的JPEG檔案要小于使用漸變式編碼的JPEG檔案(發生概率為75%),當檔案大于10KB時,漸變式編碼的JPEG檔案有94%的概率擁有比標準編碼的檔案更小的體積,

減少不必要的回應式資料


大家都知道vue中回應式資料需要額外的對其系結get、get處理函式,如果你的某些資料不會發生變化或者你不希望它的變化會導致任何副作用(更新視圖或者其他),一般我會這樣定義他,

export default {
  data() {
    this.version = '10'; // 不會被做回應式處理
    return {
        /* ... */
    }
  }
}

Tips: 其實這種方式并不是最好的,因為這會將資料直接系結到vue實體上,而vue更希望資料能夠統一在data中,然后通過代理到vue實體上的方式來訪問,所以更好的方式應該是對data中的資料進行凍結,

在Vue3中無法通過以上方式來解決,因為Proxy代理的粒度是整個物件而不是某一個屬性,

采用合理的資料處理演算法


這個相對比較考驗資料結構和演算法的功底.

例如一個將陣列轉化為多級結構的方法.

/**
 * 陣列轉樹形結構,時間復雜度O(n)
 * @param list 陣列
 * @param idKey 元素id鍵
 * @param parIdKey 元素父id鍵
 * @param parId 第一級根節點的父id值
 * @return {[]}
 */
function listToTree (list,idKey,parIdKey,parId) {
    let map = {};
    let result = [];
    let len = list.length;

    // 構建map
    for (let i = 0; i < len; i++) {
        //將陣列中資料轉為鍵值對結構 (這里的陣列和obj會相互參考,這是演算法實作的重點)
        map[list[i][idKey]] = list[i];
    }

    // 構建樹形陣列
    for(let i=0; i < len; i++) {
        let itemParId = list[i][parIdKey];
        // 頂級節點
        if(itemParId === parId) {
            result.push(list[i]);
            continue;
        }
        // 孤兒節點,舍棄(不存在其父節點)
        if(!map[itemParId]){
            continue;
        }
        // 將當前節點插入到父節點的children中(由于是參考資料型別,obj中對于節點變化,result中對應節點會跟著變化)
        if(map[itemParId].children) {
            map[itemParId].children.push(list[i]);
        } else {
            map[itemParId].children = [list[i]];
        }
    }
    return result;
}

其他


除了上面說的方法以外還有很多優化技巧,只是我在專案并不是太常用??

  • 凍結物件(避免不需要回應式的資料變成回應式)
  • 長串列渲染-分批渲染
  • 長串列渲染-動態渲染
  • ...

首屏/體積優化

我在專案中關于首屏優化主要有以下幾個優化方向:

  • 體積
  • 代碼分割
  • 網路

體積優化


  • 壓縮打包代碼: webpackvite 的生產環境打包默認就會壓縮你的代碼,這個一般不需要特殊處理,webpack 也可以通過對應的壓縮插件手動實作,

  • 取消 source-map: 可以查看你的打包產物中是否有 .map 檔案,如果有你可以將 source-map 的值設定為false或者空來關閉代碼映射(這個占用的體積是真的大),

  • 打包啟用 gizp 壓縮: 這個需要服務器也開啟允許 gizp 傳輸,不然啟用了也沒啥用( webpack 有對應的 gzip 壓縮插件,不太版本的 webpack 壓縮插件可能不同,建議先到官網查詢),

代碼分割


代碼分割的作用的將打包產物分割為一個一個的小產物,其依賴 esModule,所以當你使用 import() 函式來匯入一個檔案或者依賴,那么這個檔案或者依賴就會被單獨打包為一個小產物,路由懶加載異步組件 都是使用這個原理,

  • 路由懶加載
  • 異步組件

對于 UI庫 我一般不會使用按需加載組件,而是比較喜歡 CDN 引入的方式來優化,

網路


CDN: 首先就是上面的說的 CDN 引入把,開發階段使用本地庫,通過配置 外部擴展(Externals) 打包時來排除這些依賴,然后在 html 檔案中通過 CDN 的方式來引入它們,

Server Push: HTTP2已經相對成熟了;經過上面的 CDN 引入,我們可以對網站使用 HTTP2 的 Server Push 功能來讓瀏覽器提前加載 這些 CDN 和 其他檔案,

開啟 gzip: 這個上面已經說過了,其原理就是當客戶端和服務端都支持 gzip 傳輸時,服務端會優先發送經過 gzip 壓縮過的檔案,然后客戶端接收到在進行解壓,

開啟快取: 一般我使用的是協商快取,但是這并不適用于所有情況,例如對于使用了 Server Push 的檔案,就不能隨意的修改其檔案名,所以我一般還會將生產的主要檔案固定檔案名,

用戶優化


我們可以在核心檔案加載完成之前,通過展示loading或者骨架屏等方式來提升用戶體驗,即可縮短白屏時間,

但是需要注意的是,頁面剛開始加載時有許多資源需要加載,如果將loading相關的資源放到dom后的話,有可能會導致loading的資源被其他資源阻塞,

所以推薦loading相關的css或者js代碼最好是行內到html中的頭部,這樣即可保證展示loading時對應的css和js已經加載完成,并且不推薦loading中使用高性能或者高網路消化的邏輯,這樣會延長后面其他資源的決議或者加載時間,


原文作者: 月夕
原文地址: 我在專案中用實際用到的22個Vue優化技巧

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

標籤:其他

上一篇:JavaScript 評測代碼運行速度

下一篇:淺談JS詞法環境

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