vue3 下拉菜单

子组件

html 复制代码
<template>
    <div>
        <div class="m-input" @click.stop="isopen = !isopen">
            {{ selectedLabel || '请选择' }}
            <span class="arrow" :class="{up:isopen}">▼</span>
        </div>
        <div class="m-show" v-if="isopen">
            <div class="m-item" v-for="val in items" @click.stop="seletitem(val);$emit('open-change',selectedValue)"
                :class="{ active: selectedValue === val.value }">{{ val.label }}</div>
        </div>
    </div>





</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue';



const selectedLabel = ref('')
const selectedValue = ref('')
const isopen = ref(false)
const items = [
    { label: '苹果', value: 'apple' },
    { label: '香蕉', value: 'banana' },
    { label: '橙子', value: 'orange' },
]

const seletitem = (item) => {
    selectedLabel.value = item.label
    selectedValue.value = item.value
    isopen.value = false
}

onMounted(() => {
    document.addEventListener('click', handleDocClick)
})

onUnmounted(() => {
    document.removeEventListener('click', handleDocClick)
})

//全局点击关闭下拉
const handleDocClick = () => {
    isopen.value = false
}


</script>

<style scoped>
.m-input {
    width: 200px;
    font-size: 14px;
    padding: 10px;
    border: 1px solid #dadada;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    align-items: center;

}

.m-input:hover {
    cursor: pointer;
    border: 1px solid #7ff3e4;

}

.m-show {
    width: 220px;
    height: auto;
    border: 1px solid #ccc;
}

.active {
    background-color: azure;
    color: #157e70;
}

.arrow {
  font-size: 10px;
  transition: transform 0.2s;
}
.arrow.up {
  transform: rotate(180deg);
}



.m-item {
    padding: 10px;
    font-size: 14px;
}

.m-item:hover {

    background-color: rgb(190, 255, 255);
    cursor: pointer;
}
</style>

父组件

html 复制代码
<template>
  
<Menu2 @open-change="getvalue"/>
<br>


</template>

<script setup>
import Menu2 from './views/Menu2.vue';

function getvalue(val){
  console.log(val)

}
</script>

<style scoped>

.ceshi{
  height: 20px;
  width:20px
}

</style>

知识点:

@click.stop="seletitem(val);$emit('open-change',selectedValue)"中可以写两条语句,用分号分隔。这是组件通信的重点。

相关推荐
赤壁小虾1 小时前
【渲染流水线】[逐片元阶段]-[透明度测试]以UnityURP为例
java·前端·数据库
Bigger2 小时前
我给 Han Design 做了 6 套很值钱的中国风配色主题
前端·设计·视觉设计
幸福摩天轮2 小时前
function Calling工具系统怎么实现
前端
Jul1en_3 小时前
【Claude Code Compact】源码级别的学习上下文压缩
java·前端·学习·github·ai编程
windliang3 小时前
Claude Code 源码分析(五):一次 Tool 调用怎样通过权限检查
前端·人工智能·面试
fengci.3 小时前
Microweber CMS 未授权路径穿越漏洞(CVE-2026-65694)
android·开发语言·前端·学习·php
Deryck_德瑞克3 小时前
【Nginx】配置差异分析
服务器·前端·nginx
前端 贾公子3 小时前
第06章:结构化输出 (上)
java·服务器·前端
北斗落凡尘3 小时前
React面试题
前端