1、tabbar案例01

进行了简单的布局

  • 1、创建一个样式文件base.css
body{margin:0; padding: 0;}
  • 2、修改App.vue
<template><div id="app"><div id="tab-bar"><div class="tab-bar-item">首页</div><div class="tab-bar-item">分类</div><div class="tab-bar-item">购物车</div><div class="tab-bar-item">我的</div></div></div>
</template><script>
export default {name: 'App',}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
#tab-bar{display: flex; background-color: #f6f6f6; position: fixed; left:0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100,100,100,0.3);}
.tab-bar-item{flex: 1; text-align: center; height: 49px;}
</style>

2、tabbar案例02

这一讲主要是对组件各种封装和嵌套,其中嵌套使用插槽的方式进行多重嵌套

模板层面(从大到小层面)
App.vue—>TabBar.vue—>TabBarItem

代码层面层面(从小到大层面)
TabBarItem.vue—>TabBar.vue—>App.vue

1、TabBarItem.vue

在tab-bar-item放入两个具名插槽(包含name属性)<slot name=“item-icon”>和<slot name=“item-text”>

<template><div class="tab-bar-item"><slot name="item-icon"></slot><slot name="item-text"></slot></div>
</template>

2、TabBar.vue

在TabBar中放入一个不具名插槽

<template><div id="tab-bar"><slot></slot></div>
</template>

2、App.vue

在最上层的模板中匹配所有插槽,注意,嵌套的div标签名是跟随id和class来的

<template><div id="app"><tab-bar><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar></div>
</template>
  • 1、拷贝各种资源图标
    将资源图标放在assets文件夹下的相关目录中

  • 2、创建最底层的组件页面TabBarItem.vue
    在页面中同时设计插槽内插入标签的样式(实际插槽内的具体div标签都是写好的,等最顶层App.vue文件创建具体标签的时候,再拷贝过去就行)

TabBarItem.vue

<template><div class="tab-bar-item"><slot name="item-icon"></slot><slot name="item-text"></slot></div>
</template><script>
export default {name:'TabBarItem'
}
</script>
<style>
.tab-bar-item{flex: 1; text-align: center; height: 49px; font-size: 14px;}
.tab-bar-item img{ width: 24px; height: 24px; vertical-align: middle; margin-top: 2px;}
</style>
  • 2、创建中间层的组件页面TabBar.vue
    在这里放入一个插槽,用来防止整个导航条的插槽

TabBar.vue

<template><div id="tab-bar"><slot></slot></div>
</template>
<script>
export default {name:'TabBar'
}
</script>
<style>#tab-bar{display: flex; background-color: #f6f6f6; position: fixed; left:0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100,100,100,0.3);}</style>
  • 3、修改最顶层组件页面App.vue
    在这一层,要匹配所有插槽

App.vue

<template><div id="app"><tab-bar><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar></div>
</template><script>
import TabBar from './components/tabbar/TabBar';
import TabBarItem from './components/tabbar/TabBarItem';export default {name: 'App',components:{TabBar,TabBarItem}
}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
</style>
  • 4、文件目录
  • 4、本集效果

3、tabbar案例03插槽内容动态显示

  • 1、在app.vue中给图片多添加一个备选标签img。用于动态(根据标签值匹配)匹配插槽
<template><div id="app"><tab-bar><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/homeactive.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/categoryactive.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/shopcartactive.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/profileactive.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar></div>
</template><script>
import TabBar from './components/tabbar/TabBar';
import TabBarItem from './components/tabbar/TabBarItem';export default {name: 'App',components:{TabBar,TabBarItem}
}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
</style>
  • 2、在TableBarItem.vue修改data和模板代码
    数据部分
 <script>
export default {name:'TabBarItem',data(){return{isActive:true}}
}
</script>

模板部分
添加一个插槽,同时由于动态显示的需要,一定要把插槽上层嵌套一个div
此外绑定class属性使用对象形式 :class="{ative:isActive}",这里类名为ative:isActive

<template><div class="tab-bar-item"><div v-if="!isActive" ><slot name="item-icon"></slot></div><div v-else><slot name="item-icon-active"></slot></div>   <div :class="{ative:isActive}"><slot slot  name="item-text"></slot></div></div>
</template>

完整代码

<template><div class="tab-bar-item"><div v-if="!isActive" ><slot name="item-icon"></slot></div><div v-else><slot name="item-icon-active"></slot></div>   <div :class="{ative:isActive}"><slot slot  name="item-text"></slot></div></div>
</template><script>
export default {name:'TabBarItem',data(){return{isActive:true}}
}
</script>
<style>
.tab-bar-item{flex: 1; text-align: center; height: 49px; font-size: 14px;}
.tab-bar-item img{ width: 24px; height: 24px; vertical-align: middle; margin-top: 2px;}
.ative{color:blue
}
</style>

效果:

4、tabbar案例04

在各个导航上添加导航跳转动作,通过路由跳转到不同的页面

  • 1、创建不同的页面

在src目录中单独创建views目录,并在views目录下创建不同的页面(.vue)

<template><h2>分类</h2>
</template>
<script>
export default {name:'Category'
}
</script>
<style scoped></style>

  • 2、在路由index.js中导入路由信息
    首先要导入路由
    其次在设置路由映射
    router/index.js
import Vue from 'vue'
import Router from 'vue-router'
//导入组件,使用懒加载的方式
const Home = () => import('../views/home/Home.vue');
const Category = () => import('../views/category/Category.vue');
const Profile = () => import('../views/profile/Profile');
const Shopcart = () => import('../views/shopcart/Shopcart');//使用路由对象
Vue.use(Router)export default new Router({routes: [{path: '/',redirect:'/Home'},{path: '/home',component:Home},{path: '/category',component:Category},{path: '/profile',component:Profile},{path: '/shopcart',component:Shopcart}],//设置路由显示模式,history直接显示路径,哈希模式会显示一个#mode:'history'
})
  • 3、在TabeBarItem.vue中设置props用来向子组件传值
 //创建一个父组件向子组件传值的propsprops:{//指定一个字符串型的link属性path:String},

在模板代码中添加跳转方法

  <div class="tab-bar-item" @click="itemClick">
<script>
export default {name:'TabBarItem',//创建一个父组件向子组件传值的propsprops:{//指定一个字符串型的link属性path:String},data(){return{isActive:true,}},methods:{itemClick(){//路由跳转this.$router.replace(this.path)}}
}
</script>

完整代码

<template><div class="tab-bar-item" @click="itemClick"><div v-if="!isActive" ><slot name="item-icon"></slot></div><div v-else><slot name="item-icon-active"></slot></div>   <div :class="{ative:isActive}"><slot slot  name="item-text"></slot></div></div>
</template><script>
export default {name:'TabBarItem',//创建一个父组件向子组件传值的propsprops:{//指定一个字符串型的link属性path:String},data(){return{isActive:true,}},methods:{itemClick(){//解决两次点击报错问题,连续点击导致当前路由和点击的路由相同,导致重复替换if(this.$route.path==this.path){return}//路由跳转this.$router.replace(this.path)}}
}
</script>
<style>
.tab-bar-item{flex: 1; text-align: center; height: 49px; font-size: 14px;}
.tab-bar-item img{ width: 24px; height: 24px; vertical-align: middle; margin-top: 2px;}
.ative{color:blue
}
</style>
  • 3、在App.vue总组件中为每个item设置path
    这里的path值是要向props传递的值
  <tab-bar-item path="/home">

完整代码

<template><div id="app"><tab-bar><tab-bar-item path="/home"><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/homeactive.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item path="/category"><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/categoryactive.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item path="/shopcart"><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/shopcartactive.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item path="/profile"><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/profileactive.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar><router-view></router-view></div>
</template><script>
//导入模块
import TabBar from './components/tabbar/TabBar';
import TabBarItem from './components/tabbar/TabBarItem';export default {name: 'App',components:{TabBar,TabBarItem}
}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
</style>

5、tabbar案例05解决不同状态下不同导航图标样式的问题

需求1:不同样式不同文字颜色
需求2:动态封装样式

  • 1、在文字颜色上使用动态样式绑定
    使用计算属性(activeStyle)动态绑定文本的样式
<div :style="activeStyle"><slot slot  name="item-text"></slot></div>
  • 2、添加新的props属性
props:{//指定一个字符串型的link属性path:String,activeColor:{type:String,default:'blue'}},
  • 3、添加新的计算属性activeStyle**
    activeColor是通过app.vue的props传过来的
 computed:{isActive(){//如果当前path在路由映射表内,则返回true(隐式返回),不在数组里,indexOf会返回-1,这是indexOf函数return this.$route.path.indexOf(this.path)!==-1},activeStyle(){//根据isActive计算属性的值,返回不同的color值return this.isActive?{color:this.activeColor}:{}}},
  • 4、原有.active的演示文件不用了
/*
//由于在TabeBarItem文件里直接设置activColor,则不需要这个样式了
.ative{color:blue
}
*/

完整TabBarItem.vue文件

<template><div class="tab-bar-item" @click="itemClick"><div v-if="!isActive" ><slot name="item-icon"></slot></div><div v-else><slot name="item-icon-active"></slot></div>   <div :style="activeStyle"><slot slot  name="item-text"></slot></div></div>
</template><script>
export default {name:'TabBarItem',//创建一个父组件向子组件传值的propsprops:{//指定一个字符串型的link属性path:String,activeColor:{type:String,default:'blue'}},data(){return{//isActive:true,}},computed:{isActive(){//如果当前path在路由映射表内,则返回true(隐式返回),不在数组里,indexOf会返回-1,这是indexOf函数return this.$route.path.indexOf(this.path)!==-1},activeStyle(){//根据isActive计算属性的值,返回不同的color值return this.isActive?{color:this.activeColor}:{}}},methods:{itemClick(){//解决两次点击报错问题if(this.$route.path==this.path){return}//路由跳转this.$router.replace(this.path)}}
}
</script>
<style>
.tab-bar-item{flex: 1; text-align: center; height: 49px; font-size: 14px;}
.tab-bar-item img{ width: 24px; height: 24px; vertical-align: middle; margin-top: 2px;}
/*
//由于在TabeBarItem文件里直接设置activColor,则不需要这个样式了
.ative{color:blue
}
*/
</style>
  • 5、App.vue模板中,把props的值传过去
 <tab-bar-item path="/home" activeColor="blue"><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/homeactive.svg"/><div slot="item-text" >首页</div></tab-bar-item>

完整代码:

<template><div id="app"><tab-bar><tab-bar-item path="/home" activeColor="blue"><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/homeactive.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item path="/category" activeColor="blue"><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/categoryactive.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item path="/shopcart" activeColor="blue"><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/shopcartactive.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item path="/profile" activeColor="blue"><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/profileactive.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar><router-view></router-view></div>
</template><script>
//导入模块
import TabBar from './components/tabbar/TabBar';
import TabBarItem from './components/tabbar/TabBarItem';export default {name: 'App',components:{TabBar,TabBarItem}
}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
</style>

效果

6、整个项目完整代码

  • 1、单个页面Category.vue

其他文件也一样,不再重复写

<template><h2>分类</h2>
</template>
<script>
export default {name:'Category'
}
</script>
<style scoped></style>
  • 2、index.js(路由目录下)
import Vue from 'vue'
import Router from 'vue-router'
//导入组件,使用懒加载的方式
const Home = () => import('../views/home/Home.vue');
const Category = () => import('../views/category/Category.vue');
const Profile = () => import('../views/profile/Profile');
const Shopcart = () => import('../views/shopcart/Shopcart');//使用路由对象
Vue.use(Router)export default new Router({routes: [{path: '/',redirect:'/Home'},{path: '/home',component:Home},{path: '/category',component:Category},{path: '/profile',component:Profile},{path: '/shopcart',component:Shopcart}],//设置路由显示模式,history直接显示路径,哈希模式会显示一个#mode:'history'
})
  • 3、TabVBar.vue
<template><div id="tab-bar"><slot></slot></div>
</template>
<script>
export default {name:'TabBar'
}
</script>
<style>#tab-bar{display: flex; background-color: #f6f6f6; position: fixed; left:0; right: 0; bottom: 0; box-shadow: 0 -1px 1px rgba(100,100,100,0.3);}</style>
  • 4、TabVBarItem.vue
<template><div class="tab-bar-item" @click="itemClick"><div v-if="!isActive" ><slot name="item-icon"></slot></div><div v-else><slot name="item-icon-active"></slot></div>   <div :style="activeStyle"><slot slot  name="item-text"></slot></div></div>
</template><script>
export default {name:'TabBarItem',//创建一个父组件向子组件传值的propsprops:{//指定一个字符串型的link属性path:String,activeColor:{type:String,default:'blue'}},data(){return{//isActive:true,}},computed:{isActive(){//如果当前path在路由映射表内,则返回true(隐式返回),不在数组里,indexOf会返回-1,这是indexOf函数return this.$route.path.indexOf(this.path)!==-1},activeStyle(){//根据isActive计算属性的值,返回不同的color值return this.isActive?{color:this.activeColor}:{}}},methods:{itemClick(){//解决两次点击报错问题if(this.$route.path==this.path){return}//路由跳转this.$router.replace(this.path)}}
}
</script>
<style>
.tab-bar-item{flex: 1; text-align: center; height: 49px; font-size: 14px;}
.tab-bar-item img{ width: 24px; height: 24px; vertical-align: middle; margin-top: 2px;}
/*
//由于在TabeBarItem文件里直接设置activColor,则不需要这个样式了
.ative{color:blue
}
*/
</style>
  • 5、App.vue
<template><div id="app"><tab-bar><tab-bar-item path="/home" activeColor="blue"><img slot="item-icon" src="./assets/images/tabbar/home.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/homeactive.svg"/><div slot="item-text" >首页</div></tab-bar-item><tab-bar-item path="/category" activeColor="blue"><img slot="item-icon" src="./assets/images/tabbar/category.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/categoryactive.svg"/><div slot="item-text">分类</div></tab-bar-item><tab-bar-item path="/shopcart" activeColor="blue"><img slot="item-icon"  src="./assets/images/tabbar/shopcart.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/shopcartactive.svg"/><div slot="item-text">购物车</div></tab-bar-item><tab-bar-item path="/profile" activeColor="blue"><img slot="item-icon"  src="./assets/images/tabbar/profile.svg"/><img slot="item-icon-active" src="./assets/images/tabbar/profileactive.svg"/><div slot="item-text">我的</div></tab-bar-item></tab-bar><router-view></router-view></div>
</template><script>
//导入模块
import TabBar from './components/tabbar/TabBar';
import TabBarItem from './components/tabbar/TabBarItem';export default {name: 'App',components:{TabBar,TabBarItem}
}
</script><style>
/*引入样式文件*/
@import url('./assets/style/base');
</style>
  • 6、目录结构

最终效果

Vue(小码哥王洪元)笔记07路由案例tabbar相关推荐

  1. Vue(小码哥王洪元)笔记06路由,url的hash,history,router-linke,路由跳转,动态路由,懒加载,路由嵌套,router参数传递,导航守卫

    1.什么是路由 路由器提供了两种机制:路由和传送 路由:数据报从来源到目的地的路径 传输:将输入端的数据转移到合适的输出端 路由有一个非常重要的概念教路由表 路由表本质上就是一个映射表,决定了数据包的 ...

  2. 小码哥iOS学习笔记第二天: OC对象的分类

    Objective-C中的对象, 简称OC对象, 主要可以分为3种 instance对象(实例对象) class对象(类对象) meta-class对象(元类对象) 一.instance instan ...

  3. 小码哥iOS学习笔记第十二天:Class结构

    一.Class的结构 通过查看源码, 可以得出Class的底层结构如下图 一开始class_data_bits_t bits;指向ro, 在加载的过程中创建了rw, 此时的指向顺序是bits-> ...

  4. 小码哥iOS学习笔记第八天: block的底层结构

    一.最简单的block 1.最简单的block结构 ^{NSLog(@"this is a block");NSLog(@"this is a block"); ...

  5. iOS-多线程-(小码哥底层原理笔记)

    iOS中常见的多线程方案 GCD的常用函数 同步方式执行任务 dispatch_sync(dispatch_queue_t _Nonnull queue, ^(void)block) queue - ...

  6. naarray查询 swift_从入门到精通Swift编程(完整 未加密 小码哥) [16.3G]

    目录:/从入门到精通Swift编程(完整 未加密 小码哥) [16.3G] : U! s1 a8 i- s+ O, c7 i      ┣━━01-基础语法.汇编初探 [367.2M]# D% l* ...

  7. 零基础轻松学python pdf 小码哥_零基础轻松学Python

    零基础轻松学Python电子书 Python之父Guido van Rossum力荐的Python门书.本书以通俗易懂的语言.好玩有趣的案例让读者轻轻松松.循序渐地从零始掌握Python 3 编程.本 ...

  8. 跟小甲鱼学Web开发笔记07

    跟小甲鱼学Web开发笔记07 格式化大作战 加粗效果 strong元素 b元素 斜体效果 em元素 i元素 使用css代替b和i元素 久的不去新的不来 del和ins元素 s元素 u元素 mark元素 ...

  9. 百度松果 小码哥考研小技巧 (概率期望)

    题目描述 要考研了,小码哥非常焦急,他要开始背英语单词,每个单词的长度是lil_ili​ ,小码哥有pipipi的概率认识这个单词,小码哥要从一个有nnn个单词的总清单里按顺序的背单词,小码哥有一个认 ...

最新文章

  1. Android架构详解
  2. CentOS转的服务器磁盘规划
  3. WEB前端 vue学习二 组件之间的数据传递
  4. Account mobile phone in CRM and C4C
  5. C++笔记-函数参数使用void *的野路子
  6. vimb java,我可以让vim接受\b而不是\lt;和\gt ;?
  7. 【英语学习】【Level 08】U03 My Choice L1 Good books are like good friends
  8. uc点网页显示服务器升级,让uc浏览器网页加载速度提升100%
  9. 给小白的 Nginx 30分钟入门指南
  10. java 实现敏感词汇的过滤
  11. 与朋友分享的生活日记
  12. python读取grd数据_ARWpost处理后的grd数据使用fortran来读取
  13. Unity 艺术字体制作
  14. 顶尖作者介绍 | 心理学领域研究“情绪”的大牛们有哪些?
  15. 25岁从零开始学习平面设计会不会晚
  16. 智能工厂具体的名词解释
  17. asterisk连接sip139网络电话
  18. python求列表list平均值的方法
  19. 国乒28人出战匈牙利公开赛 新增混双项目受关注
  20. unity3D游戏开发实战原创视频讲座系列13之帽子戏法游戏开发(预告)

热门文章

  1. 一种TPMS胎压传感器工作模式介绍--汽车胎压监测方案
  2. 索引全扫描与索引快速扫描的区别
  3. wmic 设置环境变量 不需要重启
  4. 取消wps右键菜单_一款神器级别的神器 超级右键 iRightMouse | Mac软件天堂
  5. 组件分享之前端组件——甘特图时间表时间线日历组件
  6. DIjskstra曰
  7. charles 过滤器-简单过滤和设置过滤
  8. Android APP Camera2应用(02)预览流程
  9. 2022年618活动什么时候,客厅卧室数码家电当贝投影仪值得看
  10. 论文免费下载:关于工业文明汽车工业技术被引次数较高论文文献下载