main.ts
/*** 應用程序主入口** 初始化 Vue 應用并掛載到 DOM*/
import "./assets/style/main.scss";import { createApp } from "vue";
// 全局引入element-plus,對打包后的文件大小不是很在乎,那么使用全局導入會更方便
import ElementPlus from "element-plus";
// 全局引入element-plus的樣式
import "element-plus/dist/index.css";
// 引入element-plus國際語言的中文,element-plus國際語言默認為英文
// import locale from 'element-plus/dist/locale/zh-cn.js' // 引入這個組件,還需額外處理無法找到模塊的報錯
import locale from "element-plus/es/locale/lang/zh-cn"; // 引入這個組件更簡單
// 全局引入自定義樣式,全局更改element-plus的文本顏色(通過樣式覆蓋,覆蓋上面全局引入element-plus的樣式中的文本顏色)
import "@/assets/style/element-plus-text-color.scss";
import router from "@/router";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
// 在env.d.ts文件中添加 declare module "vue3-print-nb";解決【無法找到模塊“vue3-print-nb”的聲明文件】的報錯
import print from "vue3-print-nb";
import App from "./App.vue";
// 引入全局樣式
import "@/assets/style/variables.scss";
import "@/assets/style/global.scss";
// 全局引入自定義的物資管理系統樣式
import "@/assets/style/global-warehouse.scss";const app = createApp(App);
const pinia = createPinia();
pinia.use(piniaPluginPersistedstate);
app.use(ElementPlus, { locale });
app.use(router);
app.use(pinia);
app.use(print);// 全局阻止非輸入區域的Backspace鍵,防止回退頁面
document.addEventListener("keydown", (e) => {if (e.key === "Backspace") {const activeElement = document.activeElement as HTMLElement;const isEditable =activeElement.tagName === "INPUT" || activeElement.tagName === "TEXTAREA" || activeElement.isContentEditable;// 非輸入區域按下Backspace時阻止默認行為if (!isEditable) {e.preventDefault();// 可選:提示用戶(根據需求決定是否添加)console.warn("Backspace鍵在非輸入區域已被禁用,防止回退頁面。");}}
});app.mount("#app");// 項目安裝開發依賴 dependencies
// element-plus: npm install element-plus --save
// vue-router: npm install vue-router@4
// axios: npm install axios
// pinia: npm install pinia
// pinia-plugin-persistedstate: npm i pinia-plugin-persistedstate
// mitt: npm i mitt
// vue3-print-nb: npm install vue3-print-nb --save
// xlsx: npm install xlsx // xlsx是一個優秀的表格處理庫,是一款適用于瀏覽器和nodejs的開源電子表格解析庫
// 安裝xlsx的TypeScript類型聲明 npm install @types/xlsx -D
// dayjs npm install dayjs // dayjs是一個輕量級的JavaScript時間日期庫
// vite-plugin-vue-setup-extend npm i vite-plugin-vue-setup-extend -D //擴展Vue SFC的編譯邏輯,允許在<script setup>標簽上添加name屬性,設置組件名稱
// crypto-js npm install crypto-js // crypto-js是一個開源的JavaScript加密庫
// 安裝crypto-js官方類型聲明文件 npm i --save-dev @types/crypto-js
// accounting npm install accounting // accounting.js 是一個用于格式化數字、貨幣和金額的輕量級庫,特別適合財務和會計應用。
// 安裝accounting官方類型聲明文件 npm install --save-dev @types/accounting
// lodash-es npm install lodash-es // lodash-es 是一個一致性、模塊化、高性能的 JavaScript 實用工具庫// scss: npm i sass sass-loader --save-dev// 安裝Vue文檔生成工具 VueDocGen npm install -D vue-docgen-api vue-docgen-cli
// 安裝Vue文檔生成工具 TypeDoc npm install -D typedoc
// 安裝typedoc-plugin-markdown npm install -D typedoc-plugin-markdown
// 安裝typedoc-plugin-vue npm install -D typedoc-plugin-vue
// 安裝typedoc-plugin-missing-exports npm install -D typedoc-plugin-missing-exports
// 安裝typedoc-vitepress-theme npm install -D typedoc-vitepress-theme
// 安裝vitepress npm install -D vitepress
在 Vue3 的?main.ts
中實現全局事件監聽以阻止非輸入區域的 Backspace 鍵觸發頁面回退,可以通過以下步驟實現:
??方法:全局事件監聽??
在?main.ts
中添加以下代碼,監聽?keydown
事件并判斷 Backspace 鍵是否在非輸入區域觸發:
typescript
復制
import { createApp } from 'vue'; import App from './App.vue'; const app = createApp(App); // 全局阻止非輸入區域的Backspace鍵 document.addEventListener('keydown', (e) => { if (e.key === 'Backspace') { const activeElement = document.activeElement as HTMLElement; const isEditable = activeElement.tagName === 'INPUT' || activeElement.tagName === 'TEXTAREA' || activeElement.isContentEditable; // 非輸入區域按下Backspace時阻止默認行為 if (!isEditable) { e.preventDefault(); // 可選:提示用戶(根據需求決定是否添加) console.warn('Backspace鍵在非輸入區域已被禁用'); } } }); app.mount('#app');
??關鍵點解析??
- 1.
??事件監聽范圍??
- ?
通過?
document.addEventListener
全局監聽?keydown
事件,覆蓋整個應用。 - ?
使用?
e.key === 'Backspace'
明確判斷 Backspace 鍵(兼容性更好,優于?keyCode
)1
6
。
- ?
- 2.
??輸入區域檢測??
- ?
檢查當前焦點元素 (
document.activeElement
) 是否為可編輯元素(input
、textarea
或?contentEditable
屬性為?true
的元素)1
6
。 - ?
若不在可編輯區域,則調用?
e.preventDefault()
阻止默認回退行為。
- ?
- 3.
??注意事項??
- ?
??性能優化??:無需手動移除監聽器,因為?
main.ts
是應用入口,監聽器會隨頁面生命周期持續生效。 - ?
??用戶體驗??:可根據需求添加提示(如?
alert
或?console.log
),但需謹慎避免頻繁干擾用戶6
。
- ?
??替代方案:自定義全局指令??
若需更靈活的局部控制,可在?main.ts
中注冊一個全局指令:
typescript
復制
app.directive('prevent-backspace', { mounted(el) { el.addEventListener('keydown', (e) => { if (e.key === 'Backspace') { const target = e.target as HTMLElement; if (!['INPUT', 'TEXTAREA'].includes(target.tagName) && !target.isContentEditable) { e.preventDefault(); } } }); } });
??使用方式??:在組件模板中添加?v-prevent-backspace
指令即可局部生效
1
6
。
??總結??
- ?
??推薦方案??:直接在?
main.ts
中添加全局事件監聽,簡單高效。 - ?
??擴展性??:如需動態控制,可結合路由守衛(
router.beforeEach
)或狀態管理(如?pinia
)進一步定制邏輯3
7
。 - ?
??兼容性??:確保測試不同瀏覽器(尤其是舊版本)的鍵盤事件行為。
在 Vue3 中防止 Backspace 鍵觸發頁面回退,可以通過以下幾種方法實現,涵蓋全局監聽、路由守衛和自定義指令等方式:
1. ??全局事件監聽(阻止非輸入區域的 Backspace 鍵)??
在?main.js
或組件的?mounted
鉤子中監聽?keydown
事件,判斷是否為 Backspace 鍵(key === 'Backspace'
),并檢查當前焦點是否在可編輯元素(如輸入框)外。若不在輸入區域,則阻止默認行為:
javascript
下載
復制
運行
document.addEventListener('keydown', (e) => { if (e.key === 'Backspace') { const isEditable = document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA' || document.activeElement.isContentEditable; if (!isEditable) { e.preventDefault(); alert('當前頁面禁止后退'); // 可選提示 } } });
??優點??:簡單直接,適用于全局攔截。
??注意??:需在組件銷毀時移除監聽(onUnmounted
鉤子)以避免內存泄漏
2
4
。
2. ??自定義 Vue 指令??
封裝一個指令?v-prevent-backspace
,僅在特定組件內生效:
javascript
下載
復制
運行
// 注冊指令 app.directive('prevent-backspace', { mounted(el) { el.addEventListener('keydown', (e) => { if (e.key === 'Backspace') { const target = e.target; if (!['INPUT', 'TEXTAREA'].includes(target.tagName) && !target.isContentEditable) { e.preventDefault(); } } }); } }); // 使用指令 <template> <div v-prevent-backspace>僅在此div內禁止Backspace回退</div> </template>
??適用場景??:需要局部控制的組件
2
。
3. ??路由守衛結合 History API??
通過?router.beforeEach
或?beforeRouteLeave
守衛攔截導航,并配合?history.pushState
修改瀏覽器歷史記錄:
javascript
下載
復制
運行
// 方法1:全局路由守衛 router.beforeEach((to, from, next) => { if (from.path === '/protected' && !confirm('確定離開?')) { next(false); // 取消導航 } else { next(); } }); // 方法2:組件內使用History API onMounted(() => { window.history.pushState(null, null, window.location.href); window.addEventListener('popstate', () => { window.history.pushState(null, null, window.location.href); }); });
??效果??:完全阻止后退操作,但需注意用戶體驗(如提示確認)
1
5
6
。
4. ??動態控制后退行為??
通過?ref
管理狀態,靈活啟用/禁用后退攔截:
javascript
下載
復制
運行
import { ref, onBeforeUnmount } from 'vue'; const isBackDisabled = ref(false); const disableBack = () => { window.history.pushState(null, '', window.location.href); isBackDisabled.value = true; window.addEventListener('popstate', handlePopstate); }; const handlePopstate = () => { if (isBackDisabled.value) { window.history.pushState(null, '', window.location.href); } }; onBeforeUnmount(() => { window.removeEventListener('popstate', handlePopstate); });
??優勢??:可動態恢復后退功能(設置?isBackDisabled.value = false
)
4
。
總結建議
- ?
??全局攔截??:優先使用 ??方法1?? 或 ??方法3?? 的路由守衛。
- ?
??局部控制??:選擇 ??方法2?? 的自定義指令。
- ?
??強限制場景??:結合 ??History API??(如方法3或方法4)徹底禁用后退,但需謹慎避免用戶體驗問題。
如需更詳細實現,可參考相關文檔或社區示例