介绍
下拉菜单是一种常见的用户界面元素,在本文中,我们将使用 Vue 3 和 TypeScript 创建一个下拉菜单组件,并深入解析其实现细节。
我们将创建一个名为 DropdownMenu 的 Vue 3 组件,它将接受一组选项作为参数,并允许用户通过点击按钮来选择。
本文实现效果如下:
创建组件
首先,我们需要创建一个 Vue 组件。组件将包含一个按钮和一个下拉菜单。用户点击按钮时,下拉菜单将展开,显示所有可选项。点击选项后,下拉菜单将关闭,并更新按钮上显示的选项。
Dropdown.vue 文件
Template 部分
<template> <div ref="dropdownRef" class="dropdown"> <!-- Dropdown button --> <button @click="toggleDropdown"> {{ selectedOption }} <svg :class="isOpen ? 'down' : ''" aria-hidden="true" class="icon icon-caret" role="presentation" viewBox="0 0 10 6" > <path clip-rule="evenodd" d="M9.354.646a.5.5 0 00-.708 0L5 4.293 1.354.646a.5.5 0 00-.708.708l4 4a.5.5 0 00.708 0l4-4a.5.5 0 000-.708z" fill="currentColor" fill-rule="evenodd" ></path> </svg> </button> <!-- Dropdown menu --> <ul v-if="isOpen" class="dropdown-menu"> <li v-for="(option, index) in options" :key="index" @click="selectOption(option)" > {{ option }} </li> </ul> </div> </template>
复制
我们通过以上代码,分别创建了一个下拉菜单的按钮,和下拉菜单显示的列表
script部分
<script> import { ref, onMounted, onUnmounted, nextTick } from "vue"; export default { name: "DropdownMenu", props: { options: { type: Array, required: true, }, }, setup(props) { // 响应变量 const isOpen = ref(false); // Dropdown 开启/关闭状态 const selectedOption = ref(props.options[0]); // 当前选中的选项 const dropdownRef = ref(null); // 下拉元素的Ref // Toggle dropdown open/close state const toggleDropdown = () => { isOpen.value = !isOpen.value; }; // 下拉切换打开/关闭状态 const selectOption = (option) => { selectedOption.value = option; // 更新当前选中选项 isOpen.value = false; // 关闭菜单 }; // 当点击外部时关闭下拉菜单 const closeDropdown = (event) => { if (!dropdownRef.value.contains(event.target)) { isOpen.value = false; } }; //生命周期钩子: 挂载 onMounted(() => { nextTick(() => { document.addEventListener("click", closeDropdown); // 监听下拉框外的点击事件 }); }); // 生命周期钩子: 卸载 onUnmounted(() => { document.removeEventListener("click", closeDropdown); // 当组件被卸载时移除事件监听器 }); return { isOpen, selectedOption, toggleDropdown, selectOption, dropdownRef, }; }, }; </script>
复制
除了基本的操作之外,我们还在onMounted中对document绑定了一个closeDropdown点击事件,判断点击菜单之外的区域,视为关闭菜单。并且在组件unmounted时卸载该绑定事件
Style样式部分,注意我这里使用了SCSS
<style lang="scss" scoped> .dropdown { position: relative; display: inline-block; } .dropdown button { background: none; color: inherit; padding: 0; border: none; cursor: pointer; font-size: inherit; font-weight: inherit; } .dropdown-menu { position: absolute; left: 50%; transform: translate(-50%, 10px); background-color: #f9f9f9; min-width: 180px; max-height: 300px; box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2); z-index: 1; margin: 0; padding: 0; overflow-y: auto; } .dropdown-menu li { padding: 12px 16px; text-decoration: none; display: block; cursor: pointer; font-size: 16px; line-height: 1.5; font-weight: 500; } .dropdown-menu li:hover { background-color: #f1f1f1; } .icon-caret { color: #666; stroke: #666; height: 1.3rem; width: 1.3rem; margin-left: 0.3rem; stroke-width: 0.02rem; pointer-events: auto; transition: transform 0.2s ease-in-out; // 加入动画效果 &.down { transform: rotate(180deg); } } </style>
复制
通过上面的CSS代码,我们将Button的样式进行了plain化,调整了下拉角标的样式和增加了下拉状态动画,最后对下拉列表的样式进行了美化
组件解析
Template
在模板中,我们定义了一个包含按钮和下拉菜单的容器。按钮包含当前选定的选项以及一个下拉箭头图标。当用户点击按钮时,下拉菜单的显示状态会切换。下拉菜单中的每个选项都会遍历展示,并在用户点击时触发相应的选择操作。
Script
在脚本部分,我们使用 Vue 3 的 Composition API 来编写组件逻辑。我们定义了一些响应式变量,如下拉菜单的打开状态 (isOpen)、当前选定的选项 (selectedOption),以及对下拉菜单 DOM 元素的引用 (dropdownRef)。
通过 setup 函数,我们设置了一些功能函数,包括打开/关闭下拉菜单、选择选项、以及在点击页面其他区域时关闭下拉菜单。我们还使用了 Vue 3 提供的生命周期钩子函数 onMounted 和 onUnmounted,分别用于在组件挂载和卸载时执行特定的操作。
当然, 你还可以基于这个组件,拓展其参数,让它更灵活使用 ~
总结
通过本文,我们了解了如何使用 Vue 3 和 TypeScript 创建一个简单而功能强大的下拉菜单组件。我们深入研究了组件的各个部分,包括模板、脚本和样式,并解释了它们的作用和实现细节。
这个下拉菜单组件可以作为 Vue 3 应用程序中的重要组成部分,用于提供用户友好的界面,并增强用户与应用程序的交互体验。通过理解组件的构建和实现过程,我们可以更好地利用 Vue 3 的特性和功能,为我们的应用程序添加更多功能和特性。