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)"中可以写两条语句,用分号分隔。这是组件通信的重点。

相关推荐
传人10 小时前
悬停旋转放大和位移效果如何写
前端·javascript·css
zhangzeyuaaa11 小时前
Ruby 方法参数完全指南:默认值、可变参数与关键字参数
前端·python·ruby
粥里有勺糖11 小时前
视野修炼-技术周刊第135期 | 鼠标跟随宠物
前端·github·aigc
粥里有勺糖11 小时前
拿 Codex 协助清理磁盘,Nice!
前端·后端·github
Highcharts.js11 小时前
可视化商用图表库对比,如何选择?
前端·javascript·学习·信息可视化·highcharts·前端可视化
TheITSea12 小时前
JavaScript Web APIs
开发语言·前端·javascript
恋猫de小郭12 小时前
Android CLI 支持 AI Agent 通过 Device Streaming 调试云真机
android·前端·flutter
Wang's Blog12 小时前
Java 项目实战: 外卖平台优化-前端dist部署与Nginx反向代理rewrite
java·前端·nginx
鬓戈12 小时前
Claude Code frontend-design 插件调研 与 Vue 旧系统风格一致性方案
前端·vue.js·人工智能
IT_陈寒12 小时前
SpringBoot自动配置的坑我帮你踩过了
前端·人工智能·后端