介绍
下拉菜单是一种常见的用户界面元素,在本文中,我们将使用 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 的特性和功能,为我们的应用程序添加更多功能和特性。