一、背景:
使用select的dropdownRender,里面渲染表格,点击表格行,获取相关内容到下拉框中,测试发现有的电脑点击后下拉框消失,但是数据没选中,或者偶尔选中失灵。
二、贴下大致代码:
html
<Select :value="value" :dropdownStyle="{ minWidth: '800px', padding: 0, border: 0, }" :options="tableData" :dropdownMatchSelectWidth="300" showSearch @focus="focus" @search="search" > <template #dropdownRender> <VxeGrid v-if="showTable" v-bind="gridOptions" ref="accountSearchDownTable" @current-change="selectData" > ... </VxeGrid> </template> </YdSelect>
Js: 通过 showTable控制表格显隐
//聚焦 const focus = async ({ currentTarget }) => { showTable.value = true; await getAccountOptions(currentTarget?._value ?? ''); }; //搜索 const search = debounce(async (val) => { showTable.value = true; await getAccountOptions(val); }, 500); //选择数据 const selectData = ({ row }) => { if (row) { emits('setRow', row); showTable.value = false; } };
三、问题描述:
通过在几个方法中增加console.log 发现有些电脑在点击的时候并没有进入selectData。更夸张的是,测试的几台windows电脑,使用鼠标点击可以进入,但是使用触摸板轻触却不行。
四、解决思路:
无奈之下,只能放弃上面的写法,通过select中open属性控制下拉框的开闭。
五、修改后的代码:
select外层增加div, dropdownRender内部增加div,用来控制点击事件,如果open属性为true,并且点击组件外部,就关闭下拉框。
html:
<div ref="selectRef"> <YdSelect :value="value" :style="{ width: '100%' }" :dropdownStyle="{ minWidth: '800px', padding: 0, border: 0, }" :options="tableData" :dropdownMatchSelectWidth="300" :open="showTable" :allow-clear="isJoint" showSearch @change="change" @focus="focus" @search="search" > <template #dropdownRender> <div ref="dropdownRef"> <VxeGrid v-bind="gridOptions" ref="accountSearchDownTable" @current-change="selectData" > ... </VxeGrid> </div> </template> </YdSelect> </div>
js:增加click监听事件
//聚焦 const focus = async ({ currentTarget }) => { console.log('focus'); showTable.value = true; await getAccountOptions(currentTarget?._value ?? ''); }; //搜索 const search = debounce(async (val) => { if (!showTable.value) return; console.log('search', val); await getAccountOptions(val); }, 500); //改变 const change = async (val) => { if (!val) { //针对清空的情况 emits('setRow', {}); } }; //选择数据 const selectData = ({ row }) => { if (row) { emits('setRow', row); showTable.value = false; } };// 点击外部关闭下拉的处理函数 const dropdownRef = ref<HTMLElement | null>(null); const selectRef = ref<HTMLElement | null>(null); const handleClickOutside = (event: MouseEvent) => { if (!showTable.value) return; const target = event.target as Node; const isInsideContainer = dropdownRef.value?.contains(target); const isInsideSelect = selectRef.value?.contains(target); console.log(isInsideContainer, isInsideSelect); // 如果点击发生在组件外部 if (!isInsideContainer && !isInsideSelect) { showTable.value = false; } }; // 组件卸载时移除监听 onBeforeUnmount(() => { document.removeEventListener('click', handleClickOutside); }); // 添加全局点击事件监听 onMounted(async () => { await getAccountOptions(); document.addEventListener('click', handleClickOutside); });
浙公网安备 33010602011771号