文章目录

  • 目标
  • 代码和过程
  • Vant库引入
  • 自定义样式初步修改
  • 样式修改
  • 修改active颜色
  • icon调大
  • 实现路由跳转
  • 效果
  • 总代码
  • 修改的文件
  • tab-bar.vue
  • main.js


目标

vant在ios系统下弹框不是从最底部弹出 vant tabbar_ico

前文手写了TabBar的样式和功能,本篇我们用vant库重新实现这些功能。

代码和过程

Vant库引入

Vant4 官方文档

安装:

npm i vant

引入组件:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_vue.js_02

写个button试试:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_旅游_03


说明引入成功。

注:这种引入组件的方式是:要用什么就注册什么,比较麻烦。本来用的是插件的方式,但它一直报错,博主想着这个项目的目的只是锻炼一下前端水平,重点不在怎么用vant,于是换了这种方式。

自定义样式初步修改

按文档方式引入组件:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_ico_04


显然我们要自定义图标,把它的代码复制一下,并了解它的功能:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_ico_05

为实现自己的目标,将UI库的代码改一下:

<!-- 用Vant库的代码 -->
<template>
    <!-- 双向绑定currentIndex,则不用监听点击 -->
    <van-tabbar v-model="currentIndex">
        <van-tabbar-item v-for="(item,index) in tabbarData">
            <span>{{item.text}}</span>
            <template #icon>
                <img :src="currentIndex===index?getAssetsUrl(item.item.imageActive):getAssetsUrl(item.image)" />
            </template>
        </van-tabbar-item>
        
    </van-tabbar>

</template>

<script setup>
import tabbarData from '@/assets/data/tabbarData'
import { getAssetsUrl } from '@/utils/load_assets'
import { ref } from 'vue'

const currentIndex = ref(0)

</script>

效果:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_06

显然有如下问题:

  • 主题颜色不对:这里用的是Vant库的默认颜色
  • 样式不对:字体图标的img要大
  • 没有实现路由跳转

样式修改

修改active颜色

F12一下,看看主题颜色怎么设置的,可以得知是--van-tabbar-item-active-color设置的主题颜色:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_07


显然本项目的主题颜色是橙色,且一致,所以我们可以直接在common.css中自己设置--van-tabbar-item-active-color的值。也可以直接修改样式color。这里我们用后者。

前者代码:直接写无法显示,要用!important覆盖一下。

:root {
    --van-tabbar-item-active-color: #ff9854 !important;
}

后者代码:

看一下文档,得知此功能已经被封装(一般都会封装):要放在van-tabbar中。

vant在ios系统下弹框不是从最底部弹出 vant tabbar_vue.js_08

<van-tabbar v-model="currentIndex" active-color=var(--primary-color)>
icon调大

F12一下看看为什么icon这么小:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_09


是这个.van-tabbar-item__icon imgheight设置成了20px,这是库写好的样式。我们要修改它。

修改库的样式一般有四种方法:

  1. 如果用了插槽插入了自己的元素,那么在自己的作用域中直接修改这个元素。
  2. 全局定义一个变量,覆盖它默认变量的值(:root 里面修改),会影响整个文件的样式
  3. 局部定义一个变量,覆盖它默认变量的值
  4. 直接查找对应的子组件选择器,进行修改 :deep(子组件中元素的选择器) {}


这里我们用第四种方法。

这里直接修改.van-tabbar-item__icon的样式无效,原因:

scoped表示这里的css是局部的,只在本文件中生效。
本文件template中没有.van-tabbar-item,若是直接重写.van-tabbar-item的样式不会生效 。
解决方法:
本template中没有.van-tabbar-item,但本文件用的子组件中有。使用:deep(),令写在其中的子组件 样式生效。

代码:

:deep(.van-tabbar-item) {
    height: 50px;

    img{
        height: 30px;
    }
}

效果:

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_10

实现路由跳转

再看一下文档:库为我们封装好了路由跳转的功能。

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_11


注意to是TabbarItem的属性。

vant在ios系统下弹框不是从最底部弹出 vant tabbar_旅游_12


代码:

<van-tabbar-item v-for="(item, index) in tabbarData" :to="item.path">

效果

完全一致。

vant在ios系统下弹框不是从最底部弹出 vant tabbar_前端_13

总代码

修改的文件

vant在ios系统下弹框不是从最底部弹出 vant tabbar_vue.js_14

将不用库的代码保存到copy中。

tab-bar.vue

用库果然代码简洁多了。

<!-- 用Vant库的代码 -->
<template>
    <!-- 双向绑定currentIndex,则不用监听点击 -->
    <van-tabbar v-model="currentIndex" active-color=var(--primary-color)>
        <van-tabbar-item v-for="(item, index) in tabbarData" :to="item.path">
            <span>{{ item.text }}</span>
            <template #icon>
                <img :src="currentIndex === index ? getAssetsUrl(item.imageActive) : getAssetsUrl(item.image)" />
            </template>
        </van-tabbar-item>
    </van-tabbar>
</template>

<script setup>
import tabbarData from '@/assets/data/tabbarData'
import { getAssetsUrl } from '@/utils/load_assets'
import { ref } from 'vue'

const currentIndex = ref(0)

</script>

<style lang="less" scoped>
:deep(.van-tabbar-item) {
    height: 50px;

    img {
        height: 30px;
    }
}
</style>

main.js

import { createApp } from 'vue'
import App from './App.vue'
import "normalize.css"
import './assets/css/index.css'
import router from './router'
import pinia from './store'

// 以下是添加和修改的部分

// 引入vant组件
import { Button } from 'vant';
import { Tabbar, TabbarItem } from 'vant';
// 引入组件样式
import 'vant/lib/index.css';

const app = createApp(App)

app.use(router).use(pinia)
app.use(Button).use(Tabbar).use(TabbarItem)

app.mount('#app')