Files
klp-oa/klp-ui/src/components/MemoInput/index.vue
砂糖 be48594b62 feat(发货单): 新增发货单管理页面和MemoInput组件
添加发货单管理页面,包含查询、新增、修改、删除等功能
引入MemoInput组件实现车牌号输入的历史记录和自动补全功能
2025-11-25 17:57:01 +08:00

168 lines
4.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<el-autocomplete class="inline-input" v-model="inputValue" :fetch-suggestions="querySearch" placeholder="请输入内容"
:trigger-on-focus="triggerMode === 'focus'" @select="handleSelect" @change="handleInputChange"
clearable></el-autocomplete>
</template>
<script>
export default {
name: 'LocalStorageAutocomplete',
props: {
// localStorage 存储键名,必填
value: {
type: String,
default: ''
},
storageKey: {
type: String,
required: true,
validator: (value) => value.trim() !== '' // 校验非空
},
// 最大缓存数量默认100条
maxCacheCount: {
type: Number,
default: 100,
validator: (value) => value > 0 // 校验正整数
},
// 匹配规则start-前缀匹配contain-包含匹配,默认前缀匹配
matchRule: {
type: String,
default: 'start',
validator: (value) => ['start', 'contain'].includes(value)
},
// 触发模式focus-激活即列出input-输入后匹配默认focus
triggerMode: {
type: String,
default: 'focus',
validator: (value) => ['focus', 'input'].includes(value)
}
},
data() {
return {
inputValue: '',
// 缓存历史列表(格式:[{value: 'xxx'}, ...]
historyList: []
};
},
computed: {
innerKey() {
if (!this.storageKey) {
throw new Error('storageKey is required');
}
return 'mono-' + this.storageKey;
}
},
watch: {
value: {
handler(newVal, oldVal) {
if (newVal !== oldVal) {
this.inputValue = newVal;
}
},
immediate: true
}
},
mounted() {
// 初始化时从localStorage读取历史记录
this.initHistoryList();
},
methods: {
/**
* 从localStorage初始化历史列表
*/
initHistoryList() {
const storedData = localStorage.getItem(this.innerKey);
this.historyList = storedData ? JSON.parse(storedData) : [];
},
/**
* 搜索查询方法Element UI autocomplete 要求的格式)
* @param {string} queryString - 输入的查询字符串
* @param {function} cb - 回调函数,返回匹配结果
*/
querySearch(queryString, cb) {
let results = [...this.historyList]; // 深拷贝避免修改原数组
// 根据查询字符串过滤结果
if (queryString) {
const lowerQuery = queryString.toLowerCase();
results = results.filter(item => {
const lowerValue = item.value.toLowerCase();
// 前缀匹配或包含匹配
return this.matchRule === 'start'
? lowerValue.indexOf(lowerQuery) === 0
: lowerValue.includes(lowerQuery);
});
}
cb(results); // 回调返回匹配结果
},
/**
* 选中建议项时的处理
* @param {object} item - 选中的项 {value: 'xxx'}
*/
handleSelect(item) {
this.cacheInputValue(item.value);
this.inputValue = item.value;
// 触发自定义事件,通知父组件选中结果
this.$emit('select', item.value);
},
/**
* 输入框内容变化时的处理(比如手动输入后回车/失焦)
* @param {string} value - 输入框的值
*/
handleInputChange(value) {
if (value && value.trim() !== '') {
this.cacheInputValue(value.trim());
// 触发自定义事件,通知父组件输入结果
this.$emit('input', value.trim());
}
},
/**
* 缓存输入值到localStorage
* @param {string} value - 要缓存的值
*/
cacheInputValue(value) {
// 去重:如果已存在则移除原记录(保证最新输入在最前面)
this.historyList = this.historyList.filter(item => item.value !== value);
// 添加新记录到头部
this.historyList.unshift({ value });
// 限制最大缓存数量
if (this.historyList.length > this.maxCacheCount) {
this.historyList = this.historyList.slice(0, this.maxCacheCount);
}
// 保存到localStorage
localStorage.setItem(this.innerKey, JSON.stringify(this.historyList));
},
/**
* 清空历史记录(提供给父组件调用的方法)
*/
clearHistory() {
this.historyList = [];
localStorage.removeItem(this.innerKey);
this.inputValue = '';
this.$emit('clear');
}
}
};
</script>
<style scoped>
.demo-autocomplete {
margin-bottom: 20px;
}
.sub-title {
margin-bottom: 10px;
color: #666;
font-size: 14px;
}
.inline-input {
width: 100%;
}
</style>