18. vue-router案例-tabBar导航

目标: 做一个导航tabbar

一. 分析

我们的目标是做一个导航tabbar, 要求

这个导航不仅可以在一个页面使用, 可以在多个页面通用

每个页面的样式可能不一样

每个页面的图标, 文字可能不一样

每个页面导航的个数可能不一样

要想实现上面的情况, 需要进行功能拆解:

提炼出一个通用的tabBar, 然后在里面定义插槽, 根据需要放入tabBarItem,

tabBarItem里面包含图片, 文字. 图片和文字也是插槽, 不同的tabBarItem显示的图片的文字都有可能不同.

tabBarItem的数据结构需要定义为一个json, 指定跳转的url

二. 框架实现 1. 通常我们如何实现? 第一步: 在App.vue中定义一段HTML, 外层div的id是tabBar, 内层div的class标签属性是tabBarItem. <template> <div> <div> <div>首页</div> <div>分类</div> <div>购物车</div> <div>我的</div> </div> </div> </template> 第二步: 定义body样式.

通常body样式, 我们将其单独定义到main.css文件中. 放在assets目录下

body { margin: 0px; padding: 0px; }

定义好了main.css文件, 需要将其引入到App.vue文件中

<style> @import "./assets/main.css"; </style>

引入css文件样式使用的是@import '文件路径', 而引入js文件使用的是import '文件路径'

第三步: 定义tabBar样式

tabBar采用的是Flex弹性布局的布局方式.

#tabBar { display: flex; } .tabBarItem { flex: 1; text-align: center; }

上面这段代码就指定了tabBar采用的布局方式. 它会根据子元素的个数进行弹性布局. 在子元素中我们设置每个元素的flex: 1
表示的是在空间可用的情况下, 平均分配空间.

第四步: 定义其他样式 <style> @import "./assets/main.css"; #tabBar { display: flex; background-color: #e6e6e6; position: fixed; left: 0; right: 0; bottom: 0; box-shadow: 0 -3px 1px darkgrey; } .tabBarItem { flex: 1; text-align: center; } </style>

这里面除了有布局样式,还有底部对齐, 导航的阴影等等.

总结: 这样的导航不通用, 如果我们要复用, 需要拷贝html内容, 还要拷贝css样式. 我们可以把公共部分提成一个组件

2. 抽象tabBarItem组件 第一步: 在components中新建一个组件tabBarItem

这个提取比较简单, 就是将我们刚刚在App.vue中的功能提取出一个单独的组件

<template> <div> <div>首页</div> <div>分类</div> <div>购物车</div> <div>我的</div> </div> </template> <script> export default { name: "tabBarItem" } </script> <style scoped> #tabBar { display: flex; background-color: #e6e6e6; position: fixed; left: 0; right: 0; bottom: 0; box-shadow: 0 -3px 1px darkgrey; } .tabBarItem { flex: 1; text-align: center; } </style>

然后, 在App.vue中引入组件

<script> import TabBar from "./components/TabBar" export default { name: 'App', components: { TabBar } } </script>

vue里面, 可以使用组件的简称调用组件, 如下所示:

<div> <tab-bar></tab-bar> </div>

这样, tabBarItem的可复用性就更强了.

3. 完善tabBarItem组件

我们知道tabBar除了有图片, 还有文字. 当我们鼠标点击的时候还有对应的图片或者蚊子样式的变化.
下面我们来实现, 改变图片和文字.
第一步: 在tabBarItem中放两张图片, 一张是未点击的, 另一张是点击后的图片. 图片自备, 什么图都可以

<div> <slot></slot> <slot></slot> <div ><slot></slot></div> </div>

如上代码: 比之前多了一个slot, 用来存放第二张图片的.
在调用的地方传两张图片过来

<tab-bar-item> <img slot="item-pic" src=""> <img slot="item-pic-active" src=""> <div slot="item-name">首页</div> </tab-bar-item>

这里就传了两张图片, 并指定每张图片的插槽位置

然后我们来看看效果:

18. vue-router案例-tabBar导航

效果出来了,达到预期. 但我们希望:鼠标不点击,显示图一; 鼠标点击, 显示图二.
这个容易实现, 使用一个isActive变量即可
修改TabBarItem组件

<template> <div> <div v-if="!isActive"><slot></slot></div> <div v-else><slot></slot></div> <div><slot></slot></div> </div> </template> <script> export default { name: "TabBarItem", data() { return { isActive: false } } } </script>

在组件脚本中定义一个变量isActive, 然后对插槽使用v-if即可实现效果. 注意v-if和v-else的写法.

这里我们有一个约定,通常不在插槽的里面写v-if或者v-else, 因为这部分内容后面会被替换掉. 所以, 在外层包一个div

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfxyp.html