1.分析

首页的header背景是绿色的,并且有一个搜索框,其他页面都是灰色的背景,在header的左侧,是一个返回按钮,右侧,有分享或者评论等图标,中间就是header的标题。我们先不做有搜索框的header。

我们先在components文件中创建一个header.vue文件,并且在less文件里新建一个颜色变量var.less(统一管理app的颜色,保持统一),我们先将有其他元素的组件的大致框架,以及样式先写出来。然后在Index.vue里面引入。

var.less

//APP默认颜色
@defaultColor:#42bd56;
//header
@headerBg:@defaultColor;
@headerDefaultColor:rgb(73,73,73); //tabbar
@tabbarActiveColor: @defaultColor;

header.vue

<template>
<header class="m-header is-bg is-fixed" >
<div class="m-header-button is-left">
<a href="javascript:;"><img class="m-icon-img" src="../assets/images/ic_bar_back_white.png"/>返回</a>
</div> <h1 class="m-header-title">豆瓣app</h1> <div class="m-header-button is-right">
<a href="javascript:;">分享</a>
</div>
</header>
</template>
<script> </script>
<style lang="less">
/*导入颜色变量*/
@import "../assets/less/var.less";
.m-header{
display: flex;
align-items: center;
height: 44px;
padding: 0 10px;
background: #fff;
color: @headerDefaultColor;
border-bottom:1px solid #eee;
a{
color: @headerDefaultColor;
}
.m-header-button{
width: 70px;
align-items:stretch;
&.is-left{
text-align: left;
}
&.is-right{
text-align: right;
}
.m-icon-img{
width: 20px;
height: 20px;
}
.margin-right-10{
margin-right: 10px;
}
}
.m-header-title{
flex: 1;
text-align: center;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
&.is-bg{
background:@headerBg;
color: #fff;
a{color: #fff;}
.m-header-title{
color: #fff;
}
}
&.is-fixed{
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 9;
}
}
</style>

Index.vue 引入

效果图:

2.接下来我们就来把header改造成可以配置属性的组件,可以传递props(title,fixed,bg)

header.vue

<template>
<header class="m-header" :class="{'is-bg':bg,'is-fixed':fixed}">
<div class="m-header-button is-left">
<slot name="left"></slot>
</div> <h1 class="m-header-title" v-text="title"></h1> <div class="m-header-button is-right">
<slot name="right"></slot>
</div>
</header>
</template> <script>
export default{
props:{
title:{
type:String,
default:''
},
bg:{
type:Boolean,
default:false
},
fixed:{
type:Boolean,
default:false
}
}
}
</script> <style lang="less">
/*导入颜色变量*/
@import "../assets/less/var.less";
.m-header{
display: flex;
align-items: center;
height: 44px;
padding: 0 10px;
background: #fff;
color: @headerDefaultColor;
border-bottom:1px solid #eee;
a{
color: @headerDefaultColor;
}
.m-header-button{
width: 70px;
align-items:stretch;
&.is-left{
text-align: left;
}
&.is-right{
text-align: right;
}
.m-icon-img{
width: 20px;
height: 20px;
}
.margin-right-10{
margin-right: 10px;
}
}
.m-header-title{
flex: 1;
text-align: center;
font-size: 16px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
&.is-bg{
background:@headerBg;
color: #fff;
a{color: #fff;}
.m-header-title{
color: #fff;
}
}
&.is-fixed{
position: fixed;
left: 0;
right: 0;
top: 0;
z-index: 9;
}
}
</style>

3.改造tabbar,完成路由跳转

我们先新建底部tabbar的路由页面,豆瓣app这个项目说大不大说小也不小,为了规划好结构,我们将每一个路由都新建一个文件夹,然后在文件夹里面,新建这个页面。在每个页面都添加不同的header组件,如图所示:

然后在每一个路由页面里面,我们都添加上header组件.

Index.vue

<template>
<div>
<m-header title="豆瓣app" fixed :bg="true">
</m-header>
</div>
</template> <script>
import mHeader from '../../components/header' export default {
name: 'mine',
components: {
mHeader
}
}
</script>

AudioBook.vue

<template>
<div>
<m-header title="书影音" fixed>
<a href="javascript:;" slot="right"><img class="m-icon-img margin-right-10" src="../../assets/images/ic_actionbar_search_icon.png"/></a>
<a href="javascript:;" slot="right"><img class="m-icon-img" src="../../assets/images/ic_chat_green.png"/></a>
</m-header>
</div>
</template> <script>
import mHeader from '../../components/header' export default {
name: 'mine',
components: {
mHeader
}
}
</script>

Broadcast.vue

<template>
<div>
<m-header title="广播" fixed>
<a href="javascript:;" slot="right"><img class="m-icon-img margin-right-10" src="../../assets/images/ic_actionbar_search_icon.png"/></a>
<a href="javascript:;" slot="right"><img class="m-icon-img" src="../../assets/images/ic_chat_green.png"/></a>
</m-header>
</div>
</template> <script>
import mHeader from '../../components/header' export default {
name: 'mine',
components: {
mHeader
}
}
</script>

Group.vue

<template>
<div>
<m-header title="小组" fixed>
<a href="javascript:;" slot="right"><img class="m-icon-img margin-right-10" src="../../assets/images/ic_actionbar_search_icon.png"/></a>
<a href="javascript:;" slot="right"><img class="m-icon-img" src="../../assets/images/ic_chat_green.png"/></a>
</m-header>
</div>
</template> <script>
import mHeader from '../../components/header' export default {
name: 'mine',
components: {
mHeader
}
}
</script>

Mine.vue

<template>
<div>
<m-header title="我的" fixed>
<a href="javascript:;" slot="right"><img class="m-icon-img margin-right-10" src="../../assets/images/ic_actionbar_search_icon.png"/></a>
<a href="javascript:;" slot="right"><img class="m-icon-img" src="../../assets/images/ic_chat_green.png"/></a>
</m-header>
</div>
</template> <script>
import mHeader from '../../components/header' export default {
name: 'mine',
components: {
mHeader
}
}
</script>

路由的页面完成后我们就需要在router文件夹下面的index.js里面,来配置页面路由。如下:

index.js

import Vue from 'vue'
import Router from 'vue-router'
import Index from '../pages/Index/Index'
import Broadcast from '../pages/Broadcast/Broadcast'
import AudioBook from '../pages/AudioBook/AudioBook'
import Group from '../pages/Group/Group'
import Mine from '../pages/Mine/Mine' Vue.use(Router) // 路由配置
export default new Router({
routes: [
// 默认首页
{
path: '/',
name: 'Index',
component: Index
},
// 广播
{
path: '/broadcast',
name: 'Broadcast',
component: Broadcast
},
// 书影音
{
path: '/audioBook',
name: 'AudioBook',
component: AudioBook
},
// 小组
{
path: '/group',
name: 'Group',
component: Group
},
// 我的
{
path: '/mine',
name: 'Mine',
component: Mine
},
{
path: '/Index',
redirect: '/'
},
{
path: '*',
redirect: '/'
},
]
})
接下来我们就来改造tabbar实现路由跳转。我们先将index.vue里的tabbar组件移入到app.vue里面,并且将每一个id改成对应的路由,添加一个isRouter属性,来判断当前item是否是路由跳转。然后在tabbar-item.vue里我们在props添加isRouter,click点击跳转的方法放到methods里面,并且根据传递的isRouter判断当前是否通过路由跳转

App.vue

<template>
<div id="app">
<router-view></router-view>
<m-tabbar v-model="select">
<m-tabbar-item id='Index' isRouter>
<img src="./assets/images/ic_tab_home_normal.png" alt="" slot="icon-normal">
<img src="./assets/images/ic_tab_home_active.png" alt="" slot="icon-active">
首页
</m-tabbar-item>
<m-tabbar-item id='AudioBook' isRouter>
<img src="./assets/images/ic_tab_subject_normal.png" alt="" slot="icon-normal">
<img src="./assets/images/ic_tab_subject_active.png" alt="" slot="icon-active">
书影音
</m-tabbar-item>
<m-tabbar-item id='Broadcast' isRouter>
<img src="./assets/images/ic_tab_status_normal.png" alt="" slot="icon-normal">
<img src="./assets/images/ic_tab_status_active.png" alt="" slot="icon-active">
广播
</m-tabbar-item>
<m-tabbar-item id='Group' isRouter>
<img src="./assets/images/ic_tab_group_normal.png" alt="" slot="icon-normal">
<img src="./assets/images/ic_tab_group_active.png" alt="" slot="icon-active">
小组
</m-tabbar-item>
<m-tabbar-item id='Mine' isRouter>
<img src="./assets/images/ic_tab_profile_normal.png" alt="" slot="icon-normal">
<img src="./assets/images/ic_tab_profile_active.png" alt="" slot="icon-active">
我的
</m-tabbar-item>
</m-tabbar>
</div>
</template> <script>
import mTabbar from './components/tabbar'
import mTabbarItem from './components/tabbar-item'
export default {
name: 'app',
components:{
mTabbar,
mTabbarItem
},
data() {
return {
select:"Index"
}
}
}
</script> <style> </style>

tabbar-item.vue

<template>
<a class="m-tabbar-item" :class="{'is-active':isActive}" @click="goToRouter">
<span class="m-tabbar-item-icon" v-show="!isActive"><slot name="icon-normal"></slot></span>
<span class="m-tabbar-item-icon" v-show="isActive"><slot name="icon-active"></slot></span>
<span class="m-tabbar-item-text"><slot></slot></span>
</a>
</template>
<script>
export default{
props: {
id:{
type:String
},
isRouter:{
type:Boolean,
default:false
}
},
computed: {
isActive(){
if(this.$parent.value===this.id){
return true;
}
}
},
methods:{
goToRouter(){
this.$parent.$emit('input',this.id)
//判断是否为路由跳转
if(this.isRouter){
//根据id跳转到对应的路由页面
this.$router.push(this.id)
}
}
}
}
</script>
<style lang="less">
@import "../assets/less/var.less";
.m-tabbar-item{
flex: 1;
text-align: center;
.m-tabbar-item-icon{
display: block;
padding-top: 2px;
img{
width: 28px;
height: 28px;
} }
.m-tabbar-item-text{
display: block;
font-size: 10px;
color:#949494;
}
&.is-active{
.m-tabbar-item-text{
color: @tabbarActiveColor;
}
}
}
</style>

tabbar.vue

通过计算返回当前路由的值

<template>
<div class="m-tabbar">
<slot></slot>
</div>
</template>
<script>
import mTabbarItem from './tabbar-item';
export default {
computed:{
value(){
return this.$route.matched[0].name
}
}
}
</script>
<style lang="less">
.m-tabbar{
display: flex;
flex-direction: row;
position: fixed;
bottom: 0;
left: 0;
right: 0;
width: 100%;
overflow: hidden;
height: 50px;
background: #fff;
border-top: 1px solid #e4e4e4;
}
</style>

效果图

vue2.0 之 douban (三)创建header组件的更多相关文章

  1. vue2.0 + vux (一)Header 组件

    1.main.js import Vue from 'vue' import FastClick from 'fastclick' import VueRouter from 'vue-router' ...

  2. 《React后台管理系统实战 :三》header组件:页面排版、天气请求接口及页面调用、时间格式化及使用定时器、退出函数

    一.布局及排版 1.布局src/pages/admin/header/index.jsx import React,{Component} from 'react' import './header. ...

  3. vue2.0 之 douban (四)创建Swipe图片轮播组件

    swiper中文文档:http://www.swiper.com.cn 1.我们在components文件夹里创建一个swipe组件,将需要用到的js以及css文件复制到assets/lib文件夹下, ...

  4. vue2.0 之 douban (二)创建自定义组件tabbar

    1.大体布局 这个组件分为两部分:第一个是组件的外层容器,第二个是组件的子容器item,子组件里面又分为图片和文字组合.子组件有2个状态,一个默认灰色的状态,一个选中状态,我们来实现一下这个组件的布局 ...

  5. vue2.0 之 douban (五)创建cell,media-cell组件

    1.组件cell 这里的cell分为三种样式,左侧带图标,不带图标,以及左侧带竖线的cell. 每一个组件都有一个底部边框: 这里我们采用了移动端1px像素问题的解决方法:父级元素设置相对定位,构建1 ...

  6. vue2.0 之 douban (六)axios的简单使用

    由于项目中用到了豆瓣api,涉及到跨域访问,就需要在config的index.js添加代理,例如 proxyTable: { // 设置代理,解决跨域问题 '/api': { target: 'htt ...

  7. vue2.0 自定义 弹窗(MessageBox)组件

    组件模板 src/components/MessageBox/index.vue <!-- 自定义 MessageBox 组件 --> <template> <div c ...

  8. vue2.0 之 douban (一)框架搭建 及 整体布局

    1.创建豆瓣项目 我们通过官方vue-cli初始化项目 vue init webpack douban 填写项目描述,作者,安装vue-router 初始化后,通过npm install安装依赖 cd ...

  9. vue2.0 之 douban (七)APP 打包

    在打包之前需要修改一个地方,那就是config->index.js文件,修改assetsPublicPath: '/'为assetsPublicPath: './',截图如下 上面文件改好后,开 ...

随机推荐

  1. 编写Servlet步骤以及Servlet生命周期是怎样的

    一.编写Servlet步骤 1.继承HttpServlet,HttpServlet在javax-servlet-api依赖下 2.重写doGet()或者doPost()方法 3.在web.xml中注册 ...

  2. C++中的class和struct区别

    1,经过不停的改进,结构体 struct 变得原来越不像它在 C 语言中的样子了: 1,struct 在 C 语言中仅为了定义一个变量的集合,仅此而已,不能定义函数: 2,struct 在 C++ 中 ...

  3. lambda map() filter() zip()练习

    练习: 用map来处理字符串列表,把列表中所有人都变成sb,比方alex_sb l=[{'name':'alex'},{'name':'y'}] l=[{'name':'alex'},{'name': ...

  4. HNUSTOJ-1521 塔防游戏

    1521: 塔防游戏 时间限制: 1 Sec  内存限制: 128 MB提交: 117  解决: 38[提交][状态][讨论版] 题目描述 小明最近迷上了塔防游戏,塔防游戏的规则就是在地图上建炮塔,用 ...

  5. 五、JVM — 类加载器

    回顾一下类加载过程 类加载器总结 双亲委派模型 双亲委派模型介绍 双亲委派模型实现源码分析 双亲委派模型的好处 如果我们不想要双亲委派模型怎么办? 自定义类加载器 推荐 回顾一下类加载过程 类加载过程 ...

  6. 有十个div,怎样实现选中其中一个,改变其背景色,另外九个不变,当选中另一个时又改变另一个的背景色

    这个是jq写的,可以自己下载一个js库,配上这个就可以了,里面的div可以用class控制,比如你10个div class为a1 也就是<div class="a1"> ...

  7. jQuery之筛选方法

    1. 父parent.子children.find <div class="yeye"> <div class="father"> &l ...

  8. 2019 安洵杯 Re 部分WP

    0x01.EasyEncryption 测试文件:https://www.lanzous.com/i7soysb 1.IDA打开 int sub_416560() { int v0; // eax i ...

  9. vue : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\vue.ps1,因为在此系统上禁止运行脚本

    问题: 使用命令行安装完成vue/cli后,使用vue ui无法创建demo vue : 无法加载文件 C:\Users\yangx\AppData\Roaming\npm\vue.ps1,因为在此系 ...

  10. springboot easyexcel

    pom..xml <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel&l ...