主要功能:
- 點擊"停頓"按鈕切換對話框顯示狀態
- 輸入框聚焦時保持狀態
- 點擊對話框外的區域自動關閉
以下是代碼版本:
<template><div class="input-container"><el-inputv-model="input"style="width: 240px"placeholder="Please input"ref="inputRef"class="input-ref"@focus="handleFocus"/><el-button class="input-btn" @click.stop="toggleDialog" :disabled="!isFocused":type="showDialog ? 'primary' : ''">停頓 {{ isFocused ? 'ON' : 'OFF' }}</el-button><transition name="fade"><div v-if="showDialog" class="dialog-wrapper" @click.stop><dl class="dialog-content"><dt>插入內容</dt><dd @click="closeDialog" style="cursor: pointer">插入btn</dd></dl></div></transition></div>
</template><script lang="ts" setup>
import { ref, onMounted, onBeforeUnmount } from "vue";const showDialog = ref(false);
const input = ref("");
const inputRef = ref<HTMLInputElement>();
const isFocused = ref(false);const handleDocumentClick = (e: MouseEvent) => {const target = e.target as HTMLElement;const clickedInside = target.closest(".input-container");if (!clickedInside && isFocused.value) {closeDialog();}
};onMounted(() => {document.addEventListener("click", handleDocumentClick);
});onBeforeUnmount(() => {document.removeEventListener("click", handleDocumentClick);
});function closeDialog() {showDialog.value = false;if (inputRef.value) {inputRef.value.blur();}isFocused.value = false;
}function handleFocus() {isFocused.value = true;
}function toggleDialog() {showDialog.value = !showDialog.value;if (inputRef.value) {inputRef.value.focus();}
}
</script><style scoped>
.input-container {position: relative;display: inline-block;
}.dialog-wrapper {position: absolute;top: 100%;left: 0;margin-top: 8px;padding: 12px;background: white;border: 1px solid #ebeef5;border-radius: 4px;box-shadow: 0 2px 12px 0 rgba(0,0,0,0.1);z-index: 2000;
}.fade-enter-active, .fade-leave-active {transition: opacity 0.2s;
}
.fade-enter-from, .fade-leave-to {opacity: 0;
}
</style>
主要優點:
-
更好的結構:
- 添加了容器元素
.input-container
方便定位 - 使用 transition 實現平滑的對話框動畫
- 添加了容器元素
-
安全的實現:
- 添加了類型定義
inputRef.value
為HTMLInputElement
- 使用生命周期鉤子管理事件監聽
- 添加了點擊對話框防止事件冒泡的
@click.stop
- 添加了類型定義
-
用戶體驗:
- 按鈕狀態更直觀 (添加了 primary 樣式)
- 添加了過渡動畫
- 對話框樣式更美觀
-
代碼組織:
- 重命名方法更語義化 (
toggleDialog
替代 [pauseInput] - 分離了關閉邏輯到
closeDialog
方法
- 重命名方法更語義化 (
-
DOM 檢查優化:
- 使用整個容器檢查替代具體元素檢查