EP50 - 伺服器端渲染

更新於 2024/10/27閱讀時間約 25 分鐘
Server-Side Rendering (SSR) 這個名稱真的是很常看到!
今天終於來到ep50,但怎麼還是對Vue還是覺得很陌生www
繼續學習吧SSR 這張卡片吧~ www

概論 - Overview

什麼是SSR? - What is SSR?​

Vue.js 是一個用於構建客戶端應用的框架。默認情況下,Vue 組件會在瀏覽器中生成並操作 DOM 作為輸出。然而,也可以在伺服器上將相同的組件渲染為 HTML 字串,然後直接將其發送到瀏覽器,最終將靜態標記「水合」成為在客戶端的完全互動應用。

伺服器渲染的 Vue.js 應用也可以被視為「同構」isomorphic或「通用」universal,因為您應用的大部分代碼在伺服器和客戶端上運行。

為什麼使用 SSR? - Why SSR?

與客戶端的單頁應用(SPA)相比,SSR 的主要優勢在於:

  • 更快的內容顯示時間:這在網速慢或設備性能差的情況下更加明顯。伺服器渲染的標記不需要等到所有 JavaScript 下載並執行完成才能顯示,因此用戶將更快看到完全渲染的頁面。此外,初次訪問的數據獲取是在伺服器端進行的,伺服器通常與數據庫的連接速度比客戶端更快。這通常會改善核心網絡指標(Core Web Vitals)的度量,提升用戶體驗,對於內容顯示時間直接關聯於轉換率的應用尤為關鍵。
  • 統一的思維模型:您可以使用相同的語言和相同的聲明式、組件導向的思維模型來開發整個應用,而無需在後端模板系統和前端框架之間來回跳轉。
  • 更好的 SEO:搜索引擎爬蟲將直接看到完全渲染的頁面。
提示: 目前,Google 和 Bing 可以很好地索引同步 JavaScript 應用。這裡的關鍵詞是「同步」。如果您的應用以加載旋轉器開始,然後通過 Ajax 獲取內容,爬蟲不會等您完成。這意味著如果您在 SEO 重要的頁面上有異步獲取的內容,那麼使用 SSR 可能是必要的。

使用 SSR 時還需要考慮一些權衡:

  • 開發限制:瀏覽器特定的代碼只能在某些生命週期鉤子內使用;某些外部庫可能需要特殊處理才能在伺服器渲染的應用中運行。
  • 更複雜的構建設置和部署要求:與可以在任何靜態文件伺服器上部署的完全靜態 SPA 不同,伺服器渲染的應用需要能夠運行 Node.js 伺服器的環境。
  • 更多的伺服器端負載:在 Node.js 中渲染完整的應用將比僅服務靜態文件更耗費 CPU,因此如果您預期有高流量,請為相應的伺服器負載做好準備,並明智地使用緩存策略。

在使用 SSR 開發應用之前,您首先要問的問題是您是否真的需要它。這主要取決於內容顯示時間對您應用的重要性。例如,如果您正在構建一個內部儀表板,初次加載多幾百毫秒並不太重要,那麼使用 SSR 將會是多餘的。然而,在內容顯示時間至關重要的情況下,SSR 可以幫助您實現最佳的初始加載性能。

SSR vs. SSG

靜態網站生成(SSG),也稱為預渲染,是另一種構建快速網站的流行技術。如果渲染一個頁面所需的數據對每個用戶都是相同的,那麼我們可以在每次請求到達時只渲染一次,而是在構建過程中提前渲染。預渲染的頁面生成並作為靜態 HTML 文件提供。

SSG 保留了 SSR 應用的相同性能特徵:提供出色的內容顯示時間性能。同時,由於輸出是靜態 HTML 和資源,它的部署成本較低且更容易。這裡的關鍵詞是靜態:SSG 只能應用於提供靜態數據的頁面,即在構建時已知且在請求之間不會改變的數據。每當數據更改時,都需要進行新的部署。

如果您僅在調查 SSR 以改善少數營銷頁面的 SEO(例如 /、/about、/contact 等),那麼您可能希望選擇 SSG 而不是 SSR。SSG 對於基於內容的網站(如文檔網站或博客)也非常適合。事實上,您現在正在閱讀的這個網站就是使用 VitePress(一個基於 Vue 的靜態網站生成器)靜態生成的。

基本教學 - Basic Tutorial

渲染應用 - Rendering an App

讓我們看看 Vue SSR 的最基本範例。

  1. 創建一個新目錄並進入該目錄。
  2. 執行 npm init -y
  3. package.json 中添加 "type": "module",以便 Node.js 以 ES 模組模式運行。
  4. 執行 npm install vue
  5. 創建 example.js 文件:
// 這在伺服器上的 Node.js 中運行。
import { createSSRApp } from 'vue'
// Vue 的伺服器渲染 API 在 `vue/server-renderer` 下暴露。
import { renderToString } from 'vue/server-renderer'

const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`
})

renderToString(app).then((html) => {
console.log(html)
})

然後執行:

> node example.js

這應該會在命令行上打印以下內容:

<button>1</button>

renderToString() 接收一個 Vue 應用實例,並返回一個 Promise,該 Promise 解析為應用的渲染 HTML。還可以使用 Node.js Stream APIWeb Streams API 進行流式渲染。請查看 SSR API 參考以獲取完整詳細資訊。

然後我們可以將 Vue SSR 代碼移動到伺服器請求處理程序中,將應用程序標記包裝在完整的頁面 HTML 中。我們將在接下來的步驟中使用 express

  1. 執行 npm install express
  2. 創建以下 server.js 文件:
import express from 'express'
import { createSSRApp } from 'vue'
import { renderToString } from 'vue/server-renderer'

const server = express()

server.get('/', (req, res) => {
const app = createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`
})

renderToString(app).then((html) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<title>Vue SSR Example</title>
</head>
<body>
<div id="app">${html}</div>
</body>
</html>
`)
})
})

server.listen(3000, () => {
console.log('ready')
})

最後,執行 node server.js,並訪問 http://localhost:3000。您應該會看到頁面正常工作並顯示按鈕。

Try it on StackBlitz

客戶端水合 - Client Hydration

如果您單擊按鈕,您會注意到數字不會改變。由於我們沒有在瀏覽器中加載 Vue,因此 HTML 在客戶端完全靜態。

要使客戶端應用具備交互性,Vue 需要執行水合步驟。在水合期間,它創建與在伺服器上運行的相同 Vue 應用,將每個組件與它應該控制的 DOM 節點匹配,並附加 DOM 事件監聽器。

要在水合模式下掛載應用,我們需要使用 createSSRApp() 而不是 createApp()

// 這在瀏覽器中運行。
import { createSSRApp } from 'vue'

const app = createSSRApp({
// ...與伺服器上的相同應用
})

// 在客戶端掛載 SSR 應用假設
// HTML 是預渲染的,將執行
// 水合而不是掛載新的 DOM 節點。
app.mount('#app')

代碼結構 - Code Structure

注意到我們需要重用與伺服器上相同的應用實現。這是我們需要開始考慮 SSR 應用中的代碼結構的地方——如何在伺服器和客戶端之間共享相同的應用代碼?

這裡我們將演示最基本的設置。首先,讓我們將應用創建邏輯分割到一個專用文件 app.js 中:

// app.js(在伺服器和客戶端之間共享)
import { createSSRApp } from 'vue'

export function createApp() {
return createSSRApp({
data: () => ({ count: 1 }),
template: `<button @click="count++">{{ count }}</button>`
})
}

該文件及其依賴項在伺服器和客戶端之間共享——我們稱之為通用代碼。在編寫通用代碼時,您需要注意許多事項,稍後我們將討論

我們的客戶端入口導入通用代碼,創建應用並執行掛載:

// client.js
import { createApp } from './app.js'

createApp().mount('#app')

而伺服器則在請求處理程序中使用相同的應用創建邏輯:

// server.js(不相關代碼省略)
import { createApp } from './app.js'

server.get('/', (req, res) => {
const app = createApp()
renderToString(app).then(html => {
// ...
})
})

此外,為了在瀏覽器中加載客戶端文件,我們還需要:

  1. server.js 中添加 server.use(express.static('.')) 來服務客戶端文件。
  2. 在 HTML 外殼中添加 <script type="module" src="/client.js"></script> 來加載客戶端入口。
  3. 通過在 HTML 外殼中添加 Import Map 來支持在瀏覽器中使用 import * from 'vue' 的語法。

在 StackBlitz 上試試完成的範例。按鈕現在可以交互了!

高階解決方案 - Higher Level Solutions

從範例轉向生產就緒的 SSR 應用涉及更多工作。我們需要:

  • 支持 Vue SFC 和其他構建步驟要求。實際上,我們需要為同一應用協調兩個構建:一個用於客戶端,另一個用於伺服器。
提示: Vue 組件在用於 SSR 時的編譯方式不同——模板被編譯為字符串連接,而不是虛擬 DOM 渲染函數,以提高渲染性能。
  • 在伺服器請求處理程序中,使用正確的客戶端資源鏈接和最佳的資源提示來渲染 HTML。我們還可能需要在 SSR 和 SSG 模式之間切換,甚至在同一應用中混合使用兩者。
  • 以通用方式管理路由、數據獲取和狀態管理商店。

完整的實現將相當複雜,並且取決於您選擇的構建工具鏈。因此,我們強烈建議使用更高級、具有主見的解決方案,以便為您抽象掉複雜性。以下將介紹一些在 Vue 生態系統中推薦的 SSR 解決方案。

Nuxt

Nuxt 是一個基於 Vue 生態系統的高級框架,為編寫通用 Vue 應用提供了一個流暢的開發體驗。更好的是,您還可以將其用作靜態網站生成器!我們強烈推薦您試試。

Quasar

Quasar 是一個完整的基於 Vue 的解決方案,允許您針對 SPA、SSR、PWA、移動應用、桌面應用和瀏覽器擴展,所有這些都使用同一代碼庫。它不僅處理構建設置,還提供一整套符合 Material Design 的 UI 組件。

Vite SSR

Vite 提供對 Vue 伺服器端渲染的內建支持,但它的設計是故意較低階的。如果您希望直接使用 Vite,請查看 vite-plugin-ssr,這是一個社區插件,為您抽象掉許多具有挑戰性的細節。

您還可以在這裡找到使用手動設置的 Vue + Vite SSR 項目的範例,這可以作為構建的基礎。請注意,這僅建議給有 SSR / 構建工具經驗並且真的想要對高級架構有完全控制權的人。

撰寫適合 SSR 的代碼 - Writing SSR-friendly Code

無論您的構建設置或高級框架選擇為何,以下原則適用於所有 Vue SSR 應用。

伺服器上的響應性 - Reactivity on the Server

在 SSR 過程中,每個請求 URL 都映射到我們應用程序的期望狀態。因為沒有用戶互動和 DOM 更新,所以在伺服器上不需要響應性。為了提高性能,默認情況下在 SSR 期間禁用響應性。

組件生命週期鉤子 - Component Lifecycle Hooks

由於沒有動態更新,生命週期鉤子如 onMountedonUpdated 在 SSR 期間將不會被調用,只會在客戶端執行。

您應避免在 setup()<script setup> 的根範圍內編寫需要清理的副作用代碼。例如,設置計時器的 setInterval 就是這樣的副作用。在僅用於客戶端的代碼中,我們可能會設置計時器,然後在 onBeforeUnmountonUnmounted 中將其拆除。然而,由於卸載鉤子在 SSR 期間不會被調用,計時器將永久存在。為避免此問題,請將您的副作用代碼移到 onMounted 中。

訪問平台特定 API - Access to Platform-Specific APIs

通用代碼不能假定訪問平台特定的 API,因此如果您的代碼直接使用僅在瀏覽器中的全局變量如 windowdocument,在 Node.js 中執行時會引發錯誤,反之亦然。

對於在伺服器和客戶端之間共享但具有不同平台 API 的任務,建議將平台特定的實現包裝在通用 API 內,或使用為您執行此操作的庫。例如,您可以使用 node-fetch 來在伺服器和客戶端上使用相同的 fetch API。

對於僅在瀏覽器中的 API,通常的做法是在僅用於客戶端的生命週期鉤子(如 onMounted)中延遲訪問它們。

請注意,如果第三方庫不是以通用使用為考量而編寫的,將其集成到伺服器渲染的應用中可能會很棘手。您可能能夠通過模擬某些全局變量使其運行,但這會顯得不穩定,並可能干擾其他庫的環境檢測代碼。

跨請求狀態污染 - Cross-Request State Pollution

在狀態管理章節中,我們介紹了一種使用響應性 API 的簡單狀態管理模式。在 SSR 的上下文中,這一模式需要一些額外的調整。

這一模式在 JavaScript 模塊的根範圍內聲明共享狀態。這使它們成為單例,即在我們的應用程序整個生命週期中只有一個響應式對象的實例。在純客戶端 Vue 應用中,這樣的工作是預期的,因為我們應用中的模塊在每次瀏覽器頁面訪問時都是新初始化的。

然而,在 SSR 的上下文中,應用程序模塊通常僅在伺服器啟動時初始化一次。相同的模塊實例將在多個伺服器請求之間重用,我們的單例狀態對象也將如此。如果我們用特定於一個用戶的數據來變更共享的單例狀態,則可能意外地洩露到另一個用戶的請求中。我們稱這種情況為跨請求狀態污染。

技術上,我們可以在每次請求時重新初始化所有 JavaScript 模塊,就像在瀏覽器中一樣。然而,初始化 JavaScript 模塊可能是成本高昂的,因此這將顯著影響伺服器性能。

建議的解決方案是在每次請求時創建整個應用的新實例——包括路由器和全局商店。然後,而不是直接在我們的組件中導入它,我們使用應用級的 provide 提供共享狀態,並在需要它的組件中注入:

// app.js(伺服器和客戶端共享)
import { createSSRApp } from 'vue'
import { createStore } from './store.js'

// 每次請求時調用
export function createApp() {
const app = createSSRApp(/* ... */)
// 每次請求創建新的商店實例
const store = createStore(/* ... */)
// 在應用級別提供商店
app.provide('store', store)
// 也為水合目的暴露商店
return { app, store }
}

像 Pinia 這樣的狀態管理庫是為此設計的。更多細節請參考 Pinia 的 SSR 指南

水合不匹配 - Hydration Mismatch

如果預渲染的 HTML 的 DOM 結構與客戶端應用的預期輸出不匹配,將會出現水合不匹配錯誤。水合不匹配最常見的原因有以下幾個:

  1. 模板包含無效的 HTML 嵌套結構,渲染的 HTML 被瀏覽器的原生 HTML 解析行為“修正”。例如,一個常見的錯誤是 <div> 不能放在 <p> 裡:
<p><div>hi</div></p>

如果我們在伺服器渲染的 HTML 中生成這個,當瀏覽器遇到 <div> 時,將會終止第一個 <p> 並解析為以下 DOM 結構:

<p></p>
<div>hi</div>
<p></p>
  1. 渲染時使用的數據包含隨機生成的值。由於同一應用將運行兩次——一次在伺服器上,另一次在客戶端——隨機值不保證在兩次運行之間相同。有兩種方法可以避免隨機值引起的不匹配:
    1. 使用 v-if + onMounted 僅在客戶端渲染依賴隨機值的部分。您的框架可能還具有內建功能使這更容易,例如 VitePress 中的 <ClientOnly> 組件。
    2. 使用支持種子生成的隨機數生成庫,並保證伺服器運行和客戶端運行使用相同的種子(例如,通過在序列化狀態中包含種子並在客戶端檢索它)。
  1. 伺服器和客戶端位於不同的時區。有時,我們可能想將時間戳轉換為用戶的當地時間。然而,伺服器運行期間的時區和客戶端運行期間的時區不一定相同,並且我們在伺服器運行期間可能無法可靠地知道用戶的時區。在這種情況下,本地時間轉換也應作為僅客戶端的操作來執行。

當 Vue 遇到水合不匹配時,將嘗試自動恢復並調整預渲染的 DOM 以匹配客戶端狀態。這將導致一些渲染性能損失,因為不正確的節點將被丟棄,新的節點將被掛載,但在大多數情況下,應用應該繼續正常運行。儘管如此,在開發過程中消除水合不匹配仍然是最佳做法。

抑制水合不匹配 - Suppressing Hydration Mismatches 

在 Vue 3.5+ 中,可以使用 data-allow-mismatch 屬性選擇性地抑制不可避免的水合不匹配。

自定義指令 - Custom Directives

由於大多數自定義指令涉及直接的 DOM 操作,因此在 SSR 期間會被忽略。然而,如果您想指定自定義指令的渲染方式(即它應該向渲染的元素添加什麼屬性),可以使用 getSSRProps 指令鉤子:

const myDirective = {
mounted(el, binding) {
// 客戶端實現:
// 直接更新 DOM
el.id = binding.value
},
getSSRProps(binding) {
// 伺服器端實現:
// 返回要渲染的屬性。
// `getSSRProps` 只接收指令綁定。
return {
id: binding.value
}
}
}

傳送內容 - Teleports

在 SSR 期間,傳送內容需要特別處理。如果渲染的應用包含傳送內容,則傳送的內容不會成為渲染字符串的一部分。一個簡單的解決方案是在掛載時有條件地渲染傳送內容。

如果您需要水合傳送的內容,它們會在 SSR 上下文對象的 teleports 屬性下暴露:

const ctx = {}
const html = await renderToString(app, ctx)

console.log(ctx.teleports) // { '#teleported': 'teleported content' }

您需要將傳送的標記注入到最終頁面 HTML 的正確位置,這與您需要注入主要應用標記的方式類似。

提示:在同時使用傳送內容和 SSR 時,避免針對 <body> 進行操作——通常 <body> 會包含其他伺服器渲染的內容,這使得傳送內容無法確定水合的正確起始位置。
相反,建議使用專用容器,例如 <div id="teleported"></div>,該容器僅包含傳送的內容。
這一篇也是內容好多~再來看看AI的總結吧

在使用 Vue.js 的應用中,選擇使用 SSR(伺服器端渲染)還是其他渲染方式(如 CSR,客戶端渲染)通常取決於以下幾個因素:

何時使用 SSR

  1. SEO(搜尋引擎優化)
    • SSR 可以使搜尋引擎在爬取您的網站時更容易獲得完整的 HTML 內容,因為它在伺服器上預先渲染了頁面,這對於需要良好 SEO 的網站特別重要。
  2. 初始加載速度
    • 伺服器端渲染的內容可以更快地呈現給用戶,因為用戶不需要等到 JavaScript 被下載和執行後才能看到內容,這樣可以改善首次訪問的使用體驗。
  3. 社交媒體分享
    • 當用戶分享您的網站連結到社交媒體時,許多社交平台會在分享時抓取頁面的內容。SSR 確保這些平台可以正確獲取頁面信息(例如標題和描述)。
  4. 改善性能
    • SSR 可以在伺服器上進行數據獲取和處理,這樣用戶的客戶端就不需要進行這些操作,特別是在移動設備或低性能設備上可以提升性能。

何時不使用 SSR

  1. 應用互動性高
    • 如果您的應用是以高度互動為主的單頁應用(SPA),並且不需要 SEO 或快速的初始加載速度,則 CSR 可能更適合。
  2. 開發和部署複雜性
    • SSR 通常需要更複雜的伺服器配置和部署過程,對開發團隊的技能要求更高。如果團隊對 SSR 的經驗不足,則可能會增加開發時間和維護成本。
  3. 即時性內容
    • 對於一些需要即時性更新的內容,SSR 可能不是最佳選擇,因為每次更新都需要重新渲染頁面。

總結

選擇 SSR 的時機主要取決於您的應用需求、性能考量及 SEO 需求。如果您需要良好的搜尋引擎可見性和更快的加載速度,那麼 SSR 是一個不錯的選擇。如果您的應用更注重用戶互動,則 CSR 可能會更合適。

avatar-img
2會員
71內容數
分享生活趣事~
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
卡關的人生 的其他內容
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
狀態管理在 Vue 應用中非常重要,尤其是當多個組件需要共享狀態時。每個 Vue 組件管理自己的響應式狀態,但隨著組件數量增加,簡單的管理方式可能變得複雜。這時,可以使用如 Pinia 的狀態管理庫來簡化這一過程。Pinia 提供了一個更簡單的 API 和更強的類型推斷,並由 Vue 核心團隊維護。
前後端路由的協作是現代應用開發的重要部分。後端路由根據用戶的 URL 發送相應的回應,而前端路由則使得單頁應用(SPA)能在不重新加載整個頁面的情況下更新內容。前端路由會攔截用戶的導航,並動態加載所需的組件。
Vite 作為輕量快速的建置工具,原生支持 Vue SFC,並且提供簡化的配置與優越的開發體驗。文章還介紹了 IDE 支援、測試工具(如 Cypress 和 Vitest)、Linting 和格式化工具的使用,幫助開發者提高開發效率與代碼質量。
Vue 單文件元件(SFC)是 *.vue 文件,將模板、邏輯和樣式封裝在一個文件中,提供模組化開發。SFC 需建置步驟,但帶來多項好處,如元件範圍內的 CSS、預編譯模板和熱模塊替換(HMR)。適合單頁應用、靜態網站生成等前端專案。
<Suspense> 是 Vue 3 的一個實驗性組件,用於協調異步組件的加載狀態,簡化異步處理。它能在等待多個嵌套組件的異步依賴解決時顯示加載指示器,避免每個組件獨立處理加載和錯誤狀態,從而提高用戶體驗。
測試對於構建複雜的 Vue 應用至關重要,因為它能防止回歸並鼓勵將應用拆分為可測試的模組。我們介紹了測試的基本術語和推薦的工具,包括單元測試、組件測試和端對端測試。建議越早開始測試,避免隨著時間推移而增加的相依性。單元測試專注於函數和邏輯的正確性,而組件測試則驗證 UI 元素的行為與交互。
狀態管理在 Vue 應用中非常重要,尤其是當多個組件需要共享狀態時。每個 Vue 組件管理自己的響應式狀態,但隨著組件數量增加,簡單的管理方式可能變得複雜。這時,可以使用如 Pinia 的狀態管理庫來簡化這一過程。Pinia 提供了一個更簡單的 API 和更強的類型推斷,並由 Vue 核心團隊維護。
前後端路由的協作是現代應用開發的重要部分。後端路由根據用戶的 URL 發送相應的回應,而前端路由則使得單頁應用(SPA)能在不重新加載整個頁面的情況下更新內容。前端路由會攔截用戶的導航,並動態加載所需的組件。
Vite 作為輕量快速的建置工具,原生支持 Vue SFC,並且提供簡化的配置與優越的開發體驗。文章還介紹了 IDE 支援、測試工具(如 Cypress 和 Vitest)、Linting 和格式化工具的使用,幫助開發者提高開發效率與代碼質量。
Vue 單文件元件(SFC)是 *.vue 文件,將模板、邏輯和樣式封裝在一個文件中,提供模組化開發。SFC 需建置步驟,但帶來多項好處,如元件範圍內的 CSS、預編譯模板和熱模塊替換(HMR)。適合單頁應用、靜態網站生成等前端專案。
<Suspense> 是 Vue 3 的一個實驗性組件,用於協調異步組件的加載狀態,簡化異步處理。它能在等待多個嵌套組件的異步依賴解決時顯示加載指示器,避免每個組件獨立處理加載和錯誤狀態,從而提高用戶體驗。
你可能也想看
Google News 追蹤
Thumbnail
本文探討了複利效應的重要性,並藉由巴菲特的投資理念,說明如何選擇穩定產生正報酬的資產及長期持有的核心理念。透過定期定額的投資方式,不僅能減少情緒影響,還能持續參與全球股市的發展。此外,文中介紹了使用國泰 Cube App 的便利性及低手續費,幫助投資者簡化投資流程,達成長期穩定增長的財務目標。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
※ 靜態資源回傳 ※ 什麼是靜態資源: 定義:是指事先準備好的資源,這些資源在伺服器上是靜態的、不會隨著每個請求而改變。 資源通常包括: 靜態 HTML 文件。 CSS。 圖像(Image)。 Video。 字體文件:google fonts。 favicon:網頁名稱旁邊的ico
VIPER(View Interactor Presenter Entities Router) View 負責顯示資料。 Interactor 負責管理model。 Presenter 負責處理View的業務邏輯。 Entities 負責data model。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找
Thumbnail
本文探討了複利效應的重要性,並藉由巴菲特的投資理念,說明如何選擇穩定產生正報酬的資產及長期持有的核心理念。透過定期定額的投資方式,不僅能減少情緒影響,還能持續參與全球股市的發展。此外,文中介紹了使用國泰 Cube App 的便利性及低手續費,幫助投資者簡化投資流程,達成長期穩定增長的財務目標。
Thumbnail
這篇文章介紹了網站的整體架構以及開發時所使用的工具和套件,包括 Next.js、Tailwind CSS 和 socket.io 等。文章回顧了程式碼的重構與優化,幫助開發者提高工作效率,適合希望深入瞭解前端開發和網站架構的讀者。
Thumbnail
在這篇教學文章中,我們將展示如何使用 Node.js 建立一個簡單的伺服器,並解決常見的跨來源資源共享(CORS)問題,確保伺服器能夠接收並處理來自不同來源的資料。
Thumbnail
各位使用 Vue.js 開發的小夥伴們,你們都怎麼實作父子層組件資料的雙向綁定呢?如果你還在寫 prop + emit 的話,不妨進來看看吧。
Thumbnail
※ 原本狀態:伺服器渲染 這是 MVC 架構下的 request / response 示意圖,在這張圖呈現的架構裡,畫面和資料都由同一個架構處理。 伺服器渲染流程: 瀏覽器針對特定網址送出請求。 路由器解析請求後,轉接給對應的 controller。 controller 按照要求,透過
Thumbnail
切換頁面卡卡有很多種原因,這裡舉的例子只針對元件太大的情境。 除了想辦法拆分外,還有一個方法就是利用 Vue 的 Async Component。
Thumbnail
※ 視圖模板 視圖模板(View Templates) 是在 MVC 架構中負責展示數據的 HTML 文件,包含模板語法,用於在渲染時插入實際數據。它們的主要目的是分離數據與展示邏輯,讓代碼更加模塊化和易於維護。 視圖模板設計和使用的核心理念,就是「重複的事情不要重複做、效益最大化、有效利用資源
Thumbnail
※ 靜態資源回傳 ※ 什麼是靜態資源: 定義:是指事先準備好的資源,這些資源在伺服器上是靜態的、不會隨著每個請求而改變。 資源通常包括: 靜態 HTML 文件。 CSS。 圖像(Image)。 Video。 字體文件:google fonts。 favicon:網頁名稱旁邊的ico
VIPER(View Interactor Presenter Entities Router) View 負責顯示資料。 Interactor 負責管理model。 Presenter 負責處理View的業務邏輯。 Entities 負責data model。
Thumbnail
平常我們在 html 上常看到的例如 v-for、v-model 等等... 也是VUE已經幫我們定義好的指令,而這次我們可以依這自己的需求來建立。 此功能屬於較進階的功能,因此實戰中會比較少見,市面上還是有不少完善的套件能達到同樣效果,建議可以先往這方面察找