使用 Vue 和 DOM 操作整合的最佳實踐指南
更新日期: 2025 年 1 月 3 日
本文為 JS 動態載入 案例探討,第 1 篇:
- 使用 Vue 和 DOM 操作整合的最佳實踐指南 👈 所在位置
- JavaScript 動態載入 import() 與靜態載入 import 指南
- JavaScript 模組與 module 的基礎指南
- JavaScript 動態載入模組|運行邏輯指南(附流程圖)
Vue 是一個功能強大的框架,適合用來構建動態和響應式的網頁應用。
但在多頁面應用中,如果將 Vue 與其他直接操作 DOM 的腳本混合使用,可能會導致意外的衝突或報錯。
為了解決這些問題,我們可以採用動態模組加載與模組化設計,讓應用更加穩定和高效。
本文將帶你一步步理解問題並採取對應的解決方法,適合新手快速上手。
常見問題與挑戰
Vue 與 DOM 操作的衝突
當 Vue 應用已經管理 DOM 時,外部腳本(例如 switching_tab.js
或 toggling_buttons.js
)可能不考慮 Vue 的生命周期,導致以下問題:
- DOM 操作無效:腳本找不到對應的 DOM 元素。
- Vue 狀態被覆蓋:直接操作 DOM 與 Vue 的響應式狀態不一致。
多頁面加載同一腳本的問題
在多頁面應用中,若每個 HTML 文件都加載相同的 JavaScript 打包文件(如 app.js
),但某些頁面不需要部分功能,可能出現以下情況:
- 不必要的腳本執行:加載未使用的功能模組。
- 報錯:腳本嘗試操作不存在的 DOM 元素。
解決方案
動態加載功能模組
我們可以修改 app.js
,根據當前頁面動態加載所需的功能模組,而不是一次性載入所有腳本。
以下是改進後的範例代碼:
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
// 創建 Vue 應用
const app = createApp(App);
// 使用路由
app.use(router);
// 動態加載其他功能模組
const pageElement = document.querySelector('[data-page]');
const pageName = pageElement ? pageElement.dataset.page : null;
if (pageName === "switching_tab") {
import("./scripts/switching_tab.js").then((module) => {
module.init();
});
} else if (pageName === "toggling_buttons") {
import("./scripts/toggling_buttons.js").then((module) => {
module.init();
});
}
// 掛載 Vue 應用到 DOM
app.mount("#app");
模組化功能腳本
確保每個功能腳本採用模組化設計,並導出初始化函數來避免全域變數污染。
switching_tab.js
export function init() {
const tabElements = document.querySelectorAll(".tab");
if (!tabElements) return;
tabElements.forEach((tab) => {
tab.addEventListener("click", () => {
console.log("Switching tab logic");
});
});
}
toggling_buttons.js
export function init() {
const buttons = document.querySelectorAll(".toggle-button");
if (!buttons) return;
buttons.forEach((button) => {
button.addEventListener("click", () => {
console.log("Toggling button logic");
});
});
}
HTML 文件配置
在每個 HTML 文件中,使用 data-page
屬性標記當前頁面,以便 app.js
動態加載對應的模組。
範例:freelancer_dashboard.html
<div data-page="switching_tab">
<div id="app"></div>
</div>
範例:service_detail.html
<body data-page="toggling_buttons">
<div id="app"></div>
</body>
打包配置檢查
確保你的打包工具(如 Webpack 或 esbuild)正確處理模組引入,並在 head
標籤中加載 app.js
:
<head>
<script src="{% static 'scripts/app.js' %}" type="module"></script>
</head>
測試與驗證
頁面功能測試
- 驗證每個 HTML 文件的
data-page
屬性是否正確配置。 - 確保對應的模組被加載且功能正常執行。
動態模組加載測試
- 在不同頁面測試,確保僅加載必要的腳本。
- 確認未加載多餘的模組或出現報錯。
Vue 全域狀態測試
- 確保 Vue 實例僅初始化一次。
- 驗證 Vue 的響應式狀態未被外部 DOM 操作干擾。
結論
透過動態模組加載和模組化設計,我們可以有效解決 Vue 和 DOM 操作衝突的問題,並提高代碼的可維護性。
這種方法不僅適用於多頁面應用,還能優化單頁面應用的代碼結構。
新手只需按照上述步驟實現,就能建立穩定、高效的前端架構!