|
|
@ -8,6 +8,7 @@ |
|
|
:loading="loading" |
|
|
:loading="loading" |
|
|
@select="handleSelect" |
|
|
@select="handleSelect" |
|
|
@input="handleInput" |
|
|
@input="handleInput" |
|
|
|
|
|
@clear="handleManualClear" |
|
|
:clearable="clearable" |
|
|
:clearable="clearable" |
|
|
:size="size" |
|
|
:size="size" |
|
|
:disabled="disabled" |
|
|
:disabled="disabled" |
|
|
@ -78,7 +79,19 @@ |
|
|
loading: false, |
|
|
loading: false, |
|
|
timeout: null, |
|
|
timeout: null, |
|
|
lastSearchKeyword: '', |
|
|
lastSearchKeyword: '', |
|
|
schoolList: [] |
|
|
schoolList: [], |
|
|
|
|
|
// 新增:记录最后一次有效选择 |
|
|
|
|
|
lastValidSelection: null |
|
|
|
|
|
} |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
mounted() { |
|
|
|
|
|
// 初始化时记录当前选择 |
|
|
|
|
|
if (this.selectedSchoolId && this.value) { |
|
|
|
|
|
this.lastValidSelection = { |
|
|
|
|
|
id: this.selectedSchoolId, |
|
|
|
|
|
name: this.value |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
@ -89,13 +102,10 @@ |
|
|
methods: { |
|
|
methods: { |
|
|
/** |
|
|
/** |
|
|
* 异步搜索学校 |
|
|
* 异步搜索学校 |
|
|
* @param {string} queryString 搜索关键字 |
|
|
|
|
|
* @param {Function} callback 回调函数 |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
async querySearchAsync(queryString, callback) { |
|
|
async querySearchAsync(queryString, callback) { |
|
|
const keyword = queryString.trim() |
|
|
const keyword = queryString.trim() |
|
|
|
|
|
|
|
|
// 如果搜索内容为空或与上次相同,直接返回 |
|
|
|
|
|
if (!keyword || keyword === this.lastSearchKeyword) { |
|
|
if (!keyword || keyword === this.lastSearchKeyword) { |
|
|
callback([]) |
|
|
callback([]) |
|
|
return |
|
|
return |
|
|
@ -104,7 +114,6 @@ |
|
|
this.lastSearchKeyword = keyword |
|
|
this.lastSearchKeyword = keyword |
|
|
this.loading = true |
|
|
this.loading = true |
|
|
|
|
|
|
|
|
// 使用防抖 |
|
|
|
|
|
clearTimeout(this.timeout) |
|
|
clearTimeout(this.timeout) |
|
|
this.timeout = setTimeout(async () => { |
|
|
this.timeout = setTimeout(async () => { |
|
|
try { |
|
|
try { |
|
|
@ -122,8 +131,6 @@ |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 搜索学校API调用 |
|
|
* 搜索学校API调用 |
|
|
* @param {string} keyword 搜索关键字 |
|
|
|
|
|
* @returns {Promise<Array>} 学校列表 |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
async searchSchools(keyword) { |
|
|
async searchSchools(keyword) { |
|
|
try { |
|
|
try { |
|
|
@ -143,66 +150,76 @@ |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 处理选择事件 |
|
|
* 处理选择事件 |
|
|
* @param {Object} item 选中的学校对象 |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
handleSelect(item) { |
|
|
handleSelect(item) { |
|
|
// 派发选中事件 |
|
|
console.log('选中学校:', item) |
|
|
|
|
|
|
|
|
|
|
|
// 更新记录 |
|
|
|
|
|
this.lastValidSelection = { |
|
|
|
|
|
id: item.id, |
|
|
|
|
|
name: item.name |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
this.$emit('select', item) |
|
|
this.$emit('select', item) |
|
|
// 更新选中的学校ID |
|
|
|
|
|
this.$emit('update:selectedSchoolId', item.id) |
|
|
this.$emit('update:selectedSchoolId', item.id) |
|
|
// 更新输入框显示的值 |
|
|
|
|
|
this.$emit('input', item.name) |
|
|
this.$emit('input', item.name) |
|
|
this.$emit('change', item) |
|
|
this.$emit('change', item) |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 处理输入事件 |
|
|
* 处理输入事件 - 安全版本 |
|
|
* @param {string} value 输入的值 |
|
|
|
|
|
*/ |
|
|
*/ |
|
|
handleInput(value) { |
|
|
handleInput(value) { |
|
|
|
|
|
console.log('输入变化:', value, '当前选中:', this.selectedSchoolId) |
|
|
|
|
|
|
|
|
|
|
|
// 只更新显示的值 |
|
|
this.$emit('input', value) |
|
|
this.$emit('input', value) |
|
|
// 如果输入框被清空,触发清空事件 |
|
|
|
|
|
if (!value) { |
|
|
// 重要:这里不自动触发清空 |
|
|
this.$emit('clear') |
|
|
// 清空只会在 handleManualClear 中触发 |
|
|
|
|
|
}, |
|
|
|
|
|
handleManualClear() { |
|
|
|
|
|
console.log('用户手动清空') |
|
|
|
|
|
this.clearSelection() |
|
|
|
|
|
}, |
|
|
|
|
|
clearSelection() { |
|
|
|
|
|
console.log('执行清空操作') |
|
|
|
|
|
this.$emit('input', '') |
|
|
this.$emit('update:selectedSchoolId', null) |
|
|
this.$emit('update:selectedSchoolId', null) |
|
|
|
|
|
this.$emit('clear') |
|
|
this.lastSearchKeyword = '' |
|
|
this.lastSearchKeyword = '' |
|
|
} |
|
|
this.lastValidSelection = null |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 手动设置选中的学校 |
|
|
|
|
|
* @param {Object} school 学校对象 |
|
|
|
|
|
*/ |
|
|
|
|
|
setSelectedSchool(school) { |
|
|
setSelectedSchool(school) { |
|
|
if (school && school.id && school.name) { |
|
|
if (school && school.id && school.name) { |
|
|
|
|
|
this.lastValidSelection = { |
|
|
|
|
|
id: school.id, |
|
|
|
|
|
name: school.name |
|
|
|
|
|
} |
|
|
this.$emit('input', school.name) |
|
|
this.$emit('input', school.name) |
|
|
this.$emit('update:selectedSchoolId', school.id) |
|
|
this.$emit('update:selectedSchoolId', school.id) |
|
|
this.$emit('select', school) |
|
|
this.$emit('select', school) |
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 清空选择 |
|
|
|
|
|
*/ |
|
|
|
|
|
clear() { |
|
|
clear() { |
|
|
this.$emit('input', '') |
|
|
this.clearSelection() |
|
|
this.$emit('update:selectedSchoolId', null) |
|
|
|
|
|
this.$emit('clear') |
|
|
|
|
|
this.lastSearchKeyword = '' |
|
|
|
|
|
}, |
|
|
}, |
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 手动触发搜索 |
|
|
|
|
|
* @param {string} keyword 搜索关键字 |
|
|
|
|
|
* @returns {Promise<Array>} 学校列表 |
|
|
|
|
|
*/ |
|
|
|
|
|
async triggerSearch(keyword) { |
|
|
async triggerSearch(keyword) { |
|
|
return await this.searchSchools(keyword || this.value) |
|
|
return await this.searchSchools(keyword || this.value) |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 恢复上一次的有效选择 |
|
|
|
|
|
*/ |
|
|
|
|
|
restoreLastSelection() { |
|
|
|
|
|
if (this.lastValidSelection) { |
|
|
|
|
|
this.setSelectedSchool(this.lastValidSelection) |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style lang="scss" scoped> |
|
|
<style lang="scss" scoped> |
|
|
.school-auto-complete { |
|
|
.school-auto-complete { |
|
|
width: 100%; |
|
|
width: 100%; |
|
|
|