vue-H5实现弹框选择器菜单

254 阅读1分钟

前言

实现效果: 与原系统统一风格,样式上方圆角、固定高、有分割线;含有关闭按钮;含有选框标题;选项多个时可上下滚动。
实现思路: 外层弹框使用Vant组件<van-popup>,仅实现内部弹框内容。

背景: 使用框架vue3,使用组件库Vant@3.6.5

实现效果:

image.png

代码

template

<template>
<!-- <van-popup
:show="show || props.memuShow"
closeable
position="bottom"
round
:style="{ height: columns.length > 4 ? '' : '35%' }"
> -->
<div style="text-align: center;z-index:999999999999">
<div id="popupTitle">{{ props.menuTitle||'' }}</div>
<hr id="popupTitleStyle" />
<div :class="menuTitle ? 'menuContent' : 'menuContent_noTitle'">
<div class="menuItem" v-for="(item, index) in columns" :key="index">
<div class="menuItem_content">
<div
:class="
defaultIndex === index ? 'menuItem_content_world_focus' : 'menuItem_content_world'
"
@click="clickValue(item, index)"
>
<!-- :tabindex="index" -->
<span> {{ item }}</span>
</div>
<hr class="menuItem_content_line" />
</div>
</div>
</div>
</div>
<!-- </van-popup> -->
</template>

script setup

<script setup>
import { ref, defineEmits, defineProps } from 'vue';

const emit = defineEmits(['click']);
const props = defineProps({
  memuShow: Boolean, // 是否展示弹框,必填
  menuColumns: Array, // 选择项列表,必填
  defaultIndex: String, // 默认选中值得索引,选填
  menuTitle: String, // 选择框标题,选填
});

const show = ref(props.memuShow);
const columns = ref(props.menuColumns || []);
const defaultIndex = ref(Number(props.defaultIndex || '0'));
const menuTitle = ref(props.menuTitle || '');

const clickValue = (value, index) => {
  defaultIndex.value = index;
  emit('click', value, index);
  show.value = false;
};
</script>

style样式

<style>
:root {
  --contentHeight: 1.4445rem;
  --backgroundColor: #f2f2f2;
}
#popupTitle {
  height: var(--contentHeight);
  font-size: 36px;
  line-height: var(--contentHeight);
}
#popupTitleStyle {
  height: 1px;
  margin: 0;
  background-color: var(--backgroundColor);
  border: none;
}
.menuContent {
  height: 7.5rem;  
  overflow: hidden;
  font-size: 0.42rem;
   /* 当内容超过,出现滚动条 7.2225rem*/
   overflow-y:auto;
}
/* 隐藏滚动条 */
.menuContent::-webkit-scrollbar{
  display:none;
}
.menuContent_noTitle {
   height: 7.5rem;  
  overflow: hidden;
  font-size: 0.42rem;
   /* 当内容超过,出现滚动条 7.2225rem*/
   overflow-y:auto;

}
.menuItem {
  height: var(--contentHeight);
}
.menuItem_content {
  height: var(--contentHeight);
}
.menuItem_content_world {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--contentHeight);
  text-align: center;
}
.menuItem_content_world_focus {
  display: flex;
  align-items: center;
  justify-content: center;
  height: var(--contentHeight);
  color: #1989fa;
  text-align: center;

}
/* .menuItem_content_world:focus {
  color: #1989fa;
} */
.menuItem_content_line {
  height: 1px;
  margin: 0 0.5rem;
  border: none;
    background-color: var(--backgroundColor);
}
.menuItem:first-of-type .menuItem_content_line {
    background-color: var(--backgroundColor);
}
</style>

使用

  <PickerMenu
    menuTitle="来访地点"
    :menuColumns="addressList"   
    @click="onConfirm"
    :defaultIndex="defaultaddress"
  />

若有问题,请多多指教。🎃