perf(dropdown): 新增 useClickOutside 监听, 外部点击关闭 dropdown
This commit is contained in:
		
							parent
							
								
									87168bbb00
								
							
						
					
					
						commit
						5468ead4e4
					
				@ -2,6 +2,7 @@
 | 
				
			|||||||
  <div
 | 
					  <div
 | 
				
			||||||
    v-if="trigger === 'click'"
 | 
					    v-if="trigger === 'click'"
 | 
				
			||||||
    class="layui-dropdown"
 | 
					    class="layui-dropdown"
 | 
				
			||||||
 | 
					    ref="dropdownRef"
 | 
				
			||||||
    :class="[openState ? 'layui-dropdown-up' : '']"
 | 
					    :class="[openState ? 'layui-dropdown-up' : '']"
 | 
				
			||||||
  >
 | 
					  >
 | 
				
			||||||
    <div @click="open">
 | 
					    <div @click="open">
 | 
				
			||||||
@ -30,7 +31,10 @@
 | 
				
			|||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script setup name="LaySelect" lang="ts">
 | 
					<script setup name="LaySelect" lang="ts">
 | 
				
			||||||
import { defineProps, ref } from 'vue'
 | 
					import { defineProps, ref, watch } from 'vue'
 | 
				
			||||||
 | 
					import useClickOutside from '../use/useClickOutside'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const dropdownRef = ref<null | HTMLElement>(null)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const props = withDefaults(
 | 
					const props = withDefaults(
 | 
				
			||||||
  defineProps<{
 | 
					  defineProps<{
 | 
				
			||||||
@ -46,4 +50,13 @@ const openState = ref(false)
 | 
				
			|||||||
const open = function () {
 | 
					const open = function () {
 | 
				
			||||||
  openState.value = !openState.value
 | 
					  openState.value = !openState.value
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					// 控制点击事件
 | 
				
			||||||
 | 
					const isClickOutside = useClickOutside(dropdownRef)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// 通过 watch 去监听事件的变化
 | 
				
			||||||
 | 
					watch(isClickOutside, () => {
 | 
				
			||||||
 | 
					  if (isClickOutside.value) {
 | 
				
			||||||
 | 
					    openState.value = false
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										29
									
								
								src/module/use/useClickOutside.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/module/use/useClickOutside.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					import { ref, onMounted, onUnmounted, Ref } from 'vue'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const useClickOutside = (elementRef: Ref<HTMLElement | null>) => {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // 设置一个导出值
 | 
				
			||||||
 | 
					  const isClickOutside = ref(false);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  // 给界面绑定上事件
 | 
				
			||||||
 | 
					  const handler = (e: MouseEvent) => {
 | 
				
			||||||
 | 
					    if (elementRef.value) {
 | 
				
			||||||
 | 
					      // e.target 有可能是为 null 所以需要断言
 | 
				
			||||||
 | 
					      if (elementRef.value.contains(e.target as HTMLElement)) {
 | 
				
			||||||
 | 
					        // 判断目标节点是不是当前的节点
 | 
				
			||||||
 | 
					        isClickOutside.value = false;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        isClickOutside.value = true
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  onMounted(() => {
 | 
				
			||||||
 | 
					    document.addEventListener('click', handler);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  onUnmounted(() => {
 | 
				
			||||||
 | 
					    document.removeEventListener('click', handler);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  return isClickOutside;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default useClickOutside;
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user