# vue3 vant4 Tabbar 标签栏组件的封装 和Popup弹出层的封装

vue3 vant4 Tabbar 标签栏组件的封装 和Popup弹出层的封装

在这里插入图片描述
在这里插入图片描述

需求如上,标签栏里第三个是图片,整个项目有两种场景,

  1. 标签栏正常跳转页面,
  2. 标签拦渲染别的图片时候,点击就是打开弹出层,

封装了标签栏,弹出层两部分,作为公共组件

标签栏的封装

<template>
  <div class="customTabbar">
    <van-tabbar v-model="state.active">
      <template v-for="(item, index) in state.iconList" :key="index">
        <van-tabbar-item :icon="getDisplayIcon(item)" :to="item.url" :badge= "index === 3 ? state.message : null">
          {{ item.name }}
          <template v-if="item.type === 'image'">
            <img :src="item.icon" alt="" class="navImg" @click="handleImageClick(item)" />
          </template>
        </van-tabbar-item>
      </template>
    </van-tabbar>
  </div>
</template>
  
<script setup>
import { defineProps, reactive } from 'vue';
import { Tabbar, TabbarItem } from 'vant';
import aaa from '../../../assets/aaaa.png';


const state = reactive({
  active: 0,
  iconList: [
    { name: "首页", icon: "home-o", url: "", type: "normal" },
    { name: "分析", icon: "search", url: "", type: "normal" },
    { name: "", icon: aaa, url: "",type: "image" }, // 新增的图片图标
    { name: "消息", icon: "chat-o", url: "", type: "normal" },
    { name: "我的", icon: "contact", url: "", type: "normal" }, // 保留之前的最后一个图标
  ],
  message:null,
});

const getDisplayIcon = (item) => (item.type === "image" ? "" : item.icon);

const emit = defineEmits(['show-popup-visible']);

const handleImageClick = (item) => {
  // if (!item.url) {
  // 打开弹出层的逻辑  给父组件传入自定义事件,专门用于打开弹出层
  // emit('show-popup-visible', true)
  // }
};

</script>

<style lang="less" scoped>
.customTabbar {
  .navImg {
    width: 7.3rem;
    height: 7.3rem;
    border-radius: 50%;
  }
}

:deep(.van-tabbar-item__icon) {
  font-size: 44px;
}

:deep.van-tabbar {
  height: 7.3rem;

}

:deep .van-tabbar-item__text {
  font-size: 1rem;
}

</style>

徽标样式需要调整,list现在是自己暂时再state里写的假数据

下面是再使用标签组件时候

<CustomTabbar />

或者是

<CustomTabbar @show-popup-visible = popupVisible />
@show-popup-visible = popupVisible    这里作用往下看,是打开弹出层的事件

直接引用再内容区域使用
如果不是需要打开弹出层的操作,不需要写上自定义事件,需要再加上

这里有个坑 <img :src=“item.icon” alt=“” class=“navImg” @click=“handleImageClick(item)” />
如果图片采用是变量方式渲染
如果不导入图片import aaa from ‘…/…/…/assets/aaaa.png’
引用图片时候是不会展示的,
相反直接把地址写在img上是可以正常渲染

----------------------------------------------------------------------------------------------
弹出层的封装,这里是子组件和父组件的数据可以实现双向数据绑定

<template>
  <van-popup :show="showPopupVisible" :position="position" :closeable="closeable" :close-icon-position="closeIconPosition" :style="{ height: '30%' }" :overlay=false @close="onClose">
    <template v-slot:default>
      <!-- 弹出层的内容 -->
      <slot></slot>
    </template>
  </van-popup>
</template>

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

const props = defineProps({
  showPopupVisible: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(['update-showPopupVisible']);

const popupVisible = ref(props.showPopupVisible);
const position = 'bottom';
const closeable = true;
const closeIconPosition = 'top-right';

const onClose = () => {
  popupVisible.value = false;
  emit('update-showPopupVisible', popupVisible.value);
};
</script>

----父组件调用弹出层时候:-----


<CustomPopup :show-popup-visible="state.showPopupVisible" @update-showPopupVisible="onPopupUpdate">
插入需要弹出的内容 
</CustomPopup>


父组件声明

const state = reactive({
  showPopupVisible: false
})
这里的
state.showPopupVisible 组件显示关闭的状态值

这里的
state.showPopupVisible 组件显示关闭的状态值

触发打开弹出层事件
const popupVisible = (flag) => {
  state.showPopupVisible = ! state.showPopupVisible
}

------@update-showPopupVisible 关闭弹出层时传递过来自定义事件-----
const onPopupUpdate = (value) => {
  state.showPopupVisible = value;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值