Vue3實現(xiàn)全局自動大寫轉(zhuǎn)換的兩種方案
做業(yè)務(wù)系統(tǒng)時,車牌號、零件號、訂單號……各種編號字段都需要大寫。后端存大寫、前端也顯示大寫,但用戶打字時往往習慣輸入小寫,每次都要等表單報錯才知道改。
與其讓用戶"試錯",不如在前端直接幫用戶轉(zhuǎn)大寫——體驗好,后端壓力也小。本文分享一套完整方案:自定義指令精準控制 + 全局插件一次搞定。
方案一:自定義指令v-input-uppercase
適合對特定輸入框做精細化控制。
創(chuàng)建指令文件
src/directives/inputUppercase.js
const globalUppercaseConfig = {
defaultEnabled: true,
processedInputs: new WeakSet(),
disabledInputs: new WeakSet()
};
export default {
mounted(el, binding) {
const inputElement = el.querySelector('.el-input__inner')
|| el.querySelector('input')
|| el.querySelector('textarea');
if (!inputElement) return;
const config = binding.value || {};
const enabled = config.enabled !== false;
if (!enabled) {
globalUppercaseConfig.disabledInputs.add(el);
return;
}
if (globalUppercaseConfig.processedInputs.has(el)) return;
globalUppercaseConfig.processedInputs.add(el);
let isComposing = false;
const toUpperCase = () => {
if (isComposing || !inputElement.value) return;
const oldValue = inputElement.value;
const newValue = oldValue.toUpperCase();
if (oldValue !== newValue) {
inputElement.value = newValue;
inputElement.dispatchEvent(new Event('input', { bubbles: true }));
}
};
if (inputElement.value) toUpperCase();
inputElement.addEventListener('input', toUpperCase);
inputElement.addEventListener('paste', () => setTimeout(toUpperCase, 10));
inputElement.addEventListener('compositionstart', () => { isComposing = true; });
inputElement.addEventListener('compositionend', () => {
isComposing = false;
setTimeout(toUpperCase, 10);
});
el._toUpperCase = toUpperCase;
el._inputElement = inputElement;
},
beforeUnmount(el) {
if (el._inputElement && el._toUpperCase) {
el._inputElement.removeEventListener('input', el._toUpperCase);
el._inputElement.removeEventListener('paste', el._toUpperCase);
}
globalUppercaseConfig.processedInputs.delete(el);
}
};
export { globalUppercaseConfig };
注冊指令
// src/main.js
import uppercase from './directives/inputUppercase.js'
app.directive('input-uppercase', uppercase)
使用
<!-- 自動大寫 -->
<el-input v-model="plateNo" v-input-uppercase placeholder="請輸入車牌號" />
<!-- 某些字段不需要轉(zhuǎn)大寫 -->
<el-input v-model="name" v-input-uppercase="{ enabled: false }" />方案二:全局插件(推薦)
一個插件,覆蓋所有 el-input / el-textarea / el-select,無需逐個添加指令。
創(chuàng)建插件文件
src/plugins/globalUppercase.js
import { globalUppercaseConfig } from '../directives/inputUppercase.js';
// 排除某些頁面(如登錄頁不需要大寫)
const globalUppercasePluginConfig = {
excludedPaths: ['/home/login', '/qp/tableModuSet']
};
export const GlobalUppercasePlugin = {
install(app) {
app.mixin({
mounted() {
this.$nextTick(() => {
if (!this.$el || typeof this.$el.querySelectorAll !== 'function') return;
const currentPath = window.location.hash || window.location.pathname;
if (globalUppercasePluginConfig.excludedPaths.some(p => currentPath.includes(p))) return;
const applyTo = (el) => {
if (globalUppercaseConfig.processedInputs.has(el)) return;
const actualInput = el.querySelector('.el-input__inner')
|| el.querySelector('input')
|| el.querySelector('textarea')
|| (['INPUT', 'TEXTAREA'].includes(el.tagName) ? el : null);
if (!actualInput) return;
let isComposing = false;
const toUpperCase = () => {
if (isComposing || !actualInput.value) return;
const newVal = actualInput.value.toUpperCase();
if (actualInput.value !== newVal) {
actualInput.value = newVal;
actualInput.dispatchEvent(new Event('input', { bubbles: true }));
}
};
if (actualInput.value) toUpperCase();
actualInput.addEventListener('input', toUpperCase);
actualInput.addEventListener('paste', () => setTimeout(toUpperCase, 10));
actualInput.addEventListener('compositionstart', () => { isComposing = true; });
actualInput.addEventListener('compositionend', () => {
isComposing = false;
setTimeout(toUpperCase, 10);
});
globalUppercaseConfig.processedInputs.add(el);
el._toUpperCase = toUpperCase;
el._inputElement = actualInput;
};
// 處理 el-input
this.$el.querySelectorAll('.el-input').forEach(applyTo);
// 處理 el-textarea
this.$el.querySelectorAll('.el-textarea').forEach(applyTo);
// 處理 el-select(搜索模式下的輸入框)
this.$el.querySelectorAll('.el-select').forEach(el => {
const selectInput = el.querySelector('.el-select__input');
if (selectInput) applyTo(selectInput);
});
});
},
beforeUnmount() {
if (!this.$el) return;
this.$el.querySelectorAll('.el-input, .el-textarea, .el-select').forEach(el => {
if (el._inputElement && el._toUpperCase) {
el._inputElement.removeEventListener('input', el._toUpperCase);
el._inputElement.removeEventListener('paste', el._toUpperCase);
}
globalUppercaseConfig.processedInputs.delete(el);
});
}
});
}
};
export { globalUppercasePluginConfig };
注冊插件
// src/main.js
import { GlobalUppercasePlugin } from './plugins/globalUppercase.js'
app.use(GlobalUppercasePlugin)
完成! 全站所有輸入框自動大寫,用戶輸入 abc123 → 直接顯示 ABC123。
兩種方案對比
| 自定義指令 | 全局插件 | |
|---|---|---|
| 適用范圍 | 單個輸入框 | 全站 |
| 控制粒度 | 精準 | 全局 + 路徑排除 |
| 支持組件 | el-input / input / textarea | el-input / el-textarea / el-select |
| 注冊方式 | app.directive() | app.use() |
和單引號禁止方案的對比
| 單引號禁止 | 大寫轉(zhuǎn)換 | |
|---|---|---|
| 核心操作 | replace(/'/g, '') 刪除 | toUpperCase() 轉(zhuǎn)換 |
| 行為 | 輸入時被阻止 | 輸入后自動轉(zhuǎn)換 |
| 默認觸發(fā)時機 | input + blur | input |
| 特殊處理 | 中文輸入法 | 中文輸入法 |
兩套方案代碼結(jié)構(gòu)幾乎一致,如果你兩個功能都要,完全可以合并成一個插件,通過配置項切換行為。
合并成一套插件
export const GlobalInputFilterPlugin = {
install(app, options = {}) {
const { mode = 'uppercase' } = options; // 'uppercase' | 'noQuote' | 'both'
app.mixin({
mounted() {
this.$nextTick(() => {
// ...統(tǒng)一的處理邏輯
const transform = (val) => {
if (mode === 'uppercase') return val.toUpperCase();
if (mode === 'noQuote') return val.replace(/'/g, '');
if (mode === 'both') return val.toUpperCase().replace(/'/g, '');
return val;
};
// ...
});
}
});
}
};
// 使用
app.use(GlobalInputFilterPlugin, { mode: 'both' })
總結(jié)
- 全局覆蓋 → 插件
app.use()一次搞定 - 局部控制 → 指令
v-input-uppercase精準禁用 - 兩個功能都要 → 合并成一個插件,
mode參數(shù)切換 - 中文輸入法兼容,始終是標配
以上就是Vue3實現(xiàn)全局自動大寫轉(zhuǎn)換的兩種方案的詳細內(nèi)容,更多關(guān)于Vue3全局自動大寫轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
vue中使用element ui的input框?qū)崿F(xiàn)模糊搜索的輸入框
這篇文章主要介紹了vue中使用element ui的input框?qū)崿F(xiàn)模糊搜索的輸入框,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11
vue?cli?局部混入mixin和全局混入mixin的過程
這篇文章主要介紹了vue?cli?局部混入mixin和全局混入mixin的過程,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05

