文章目录
- 目标
- 代码与过程
- 静态html
- css
- 改成动态数据
- 效果
- 总代码
- 修改或新建的文件
- tabbarData.js
- tab-bar.vue
- load_assets
- App.vue
目标
有两种实现方式:
- 把数据写死(静态、直接写在html中)
- 动态数据:封装、vite获取动态数据方法
代码与过程
静态html
把数据写死在html中:
<template>
<div class="tab-bar">
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_home.png" alt="">
<div class="text">首页</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_favor.png" alt="">
<div class="text">收藏</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_order.png" alt="">
<div class="text">订单</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_message.png" alt="">
<div class="text">消息</div>
</div>
</div>
</template>
注意,由于tab-bar功能独立,我们把它写在单独的一个组件中。所以在App.vue中把router-link注释掉,把tabBar引入。
<template>
<div class="app">
<router-view/>
<tab-bar></tab-bar>
<!-- <router-link to="/home">首页</router-link>
<router-link to="/favor">收藏</router-link>
<router-link to="/order">订单</router-link>
<router-link to="/message">消息</router-link> -->
</div>
</template>
效果:
css
写css要用到less:开发环境有,生产环境无。
npm install less -D
代码:
.tab-bar {
// fixed 绝对位置 位于浏览器窗口的位置
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 55px;
// flex布局,
display: flex;
// 浅浅的上边缘
border-top: 1px solid #f3f3f3;
.tab-bar-item {
// 每一个item各占1个位置:平分所有位置
flex: 1;
// 对于每个item里面的img和text
// 要求上下排列,要求他们居中,所以flex
display: flex;
flex-direction: column;
// x轴方向上居中
justify-content: center;
// 若无align-items,每个item会把flex格子占满
// align-items会让元素在Y轴对齐
align-items: center;
img {
height: 36px;
}
.text {
font-size: 12px;
}
}
}
效果:
改成动态数据
我们在html中的数据是这样的:显然有许多重复代码。
<div class="tab-bar">
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_home.png" alt="">
<div class="text">首页</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_favor.png" alt="">
<div class="text">收藏</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_order.png" alt="">
<div class="text">订单</div>
</div>
<div class="tab-bar-item">
<img src="@/assets/img/tabbar/tab_message.png" alt="">
<div class="text">消息</div>
</div>
</div>
我们可以把数据抽取出来,用循环来动态地显示数据。这是封装的思想。
tabbarData.js:我们把它放在assets/data中。
const tabbarData=[
{
image:'tab_home.png',
imageActive:'tab_home_active.png',
text:'首页',
path:'/home'
},
{
image:'tab_favor.png',
imageActive:'tab_favor_active.png',
text:'收藏',
path:'/favor'
},
{
image:'tab_order.png',
imageActive:'tab_order_active.png',
text:'订单',
path:'/order'
},
{
image:'tab_message.png',
imageActive:'tab_message_active.png',
text:'消息',
path:'/message'
}
]
export default tabbarData
接下来在tab-bar中引入tabbarData,用v-for对数据进行循环遍历。
注意,vite中获得动态路径的方法应如下:
const getAssetsUrl=(image)=>{
// 参数:相对路径,当前文件路径URL
return new URL(`../../assets/img/tabbar/${image}`,import.meta.url).href
}
因此,tab-bar.vue如下:
<template>
<div class="tab-bar">
<template v-for="(item,index) in tabbarData">
<div class="tab-bar-item">
<img :src="getAssetsUrl(item.image)" alt="">
<div class="text">{{item.text}}</div>
</div>
</template>
</div>
</template>
<script setup>
import tabbarData from '@/assets/data/tabbarData'
const getAssetsUrl=(image)=>{
// 参数:相对路径,当前文件路径URL
return new URL(`../../assets/img/tabbar/${image}`,import.meta.url).href
}
</script>
<style lang="less" scoped>
.tab-bar {
// fixed 绝对位置 位于浏览器窗口的位置
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 55px;
// flex布局,
display: flex;
// 浅浅的上边缘
border-top: 1px solid #f3f3f3;
.tab-bar-item {
// 每一个item各占1个位置:平分所有位置
flex: 1;
// 对于每个item里面的img和text
// 要求上下排列,要求他们居中,所以flex
display: flex;
flex-direction: column;
// x轴方向上居中
justify-content: center;
// 若无align-items,每个item会把flex格子占满
// align-items会让元素在Y轴对齐
align-items: center;
img {
height: 36px;
}
.text {
font-size: 12px;
}
}
}
</style>
显然,整个项目中会获取动态数据的地方不止这里。
我们可以把getAssetsUrl作为工具封装到utils
注意,将getAssetsUrl放进utils后相对路径要改。
效果
总代码
修改或新建的文件
tabbarData.js
封装了tabbar的数据。
const tabbarData=[
{
image:'tab_home.png',
imageActive:'tab_home_active.png',
text:'首页',
path:'/home'
},
{
image:'tab_favor.png',
imageActive:'tab_favor_active.png',
text:'收藏',
path:'/favor'
},
{
image:'tab_order.png',
imageActive:'tab_order_active.png',
text:'订单',
path:'/order'
},
{
image:'tab_message.png',
imageActive:'tab_message_active.png',
text:'消息',
path:'/message'
}
]
export default tabbarData
tab-bar.vue
tab-bar组件:
<template>
<div class="tab-bar">
<template v-for="(item, index) in tabbarData">
<div class="tab-bar-item">
<img :src="getAssetsUrl(item.image)" alt="">
<div class="text">{{ item.text }}</div>
</div>
</template>
</div>
</template>
<script setup>
import tabbarData from '@/assets/data/tabbarData'
import { getAssetsUrl } from '@/utils/load_assets'
</script>
<style lang="less" scoped>
.tab-bar {
// fixed 绝对位置 位于浏览器窗口的位置
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 55px;
// flex布局,
display: flex;
// 浅浅的上边缘
border-top: 1px solid #f3f3f3;
.tab-bar-item {
// 每一个item各占1个位置:平分所有位置
flex: 1;
// 对于每个item里面的img和text
// 要求上下排列,要求他们居中,所以flex
display: flex;
flex-direction: column;
// x轴方向上居中
justify-content: center;
// 若无align-items,每个item会把flex格子占满
// align-items会让元素在Y轴对齐
align-items: center;
img {
height: 36px;
}
.text {
font-size: 12px;
}
}
}
</style>
load_assets
存放封装的读取assets文件的工具。本篇的工具getAssetsUrl用来获取动态数据(vite获取动态数据的方法)
// vite中要这样获取动态数据
export const getAssetsUrl=(image)=>{
// 参数:相对路径,当前文件路径URL
return new URL(`../assets/img/tabbar/${image}`,import.meta.url).href
}
App.vue
略有修改。
<template>
<div class="app">
<router-view/>
<tab-bar></tab-bar>
</div>
</template>
<script setup>
import tabBar from './components/tab-bar/tab-bar.vue';
</script>
<style lang="less" scoped>
</style>