首页的基础布局已经完成 接下来 接下来还要配置一些通用的模块
tabbar 底部导航
本质
在 webApp 中底部导航 其实就是一个 position:fixed 固定定位到页面底部的盒子 里面再使用弹性盒布局 选项
(小程序在对应的 json文件中设置)
引入位置
在 传统 vue-cli 中 在app.vue 根目录当中引入
页面通过路由 显示在 router-view 容器当中 tabbat组件在页面下面
还可以根据 配置路由中设置布尔值 决定哪些页面不显示 tabbar
在nuxt.js中
layout 文件夹中存放的是页面默认布局 default.vue 文件类似于 app.vue
内部封装
外部 tabbar
<template>
<div id="main">
<tabbaritem
:path=tt.path
:activeTextColor=tt.activeTextColor
v-for="tt in tabList"
:num=tt.num
:key=tt.text>
<img slot="item-icon" :src=tt.DSrc alt="" >
<img slot="item-active" :src=tt.ASrc alt="" >
<div slot="item-text">{{tt.text}}</div>
</tabbaritem>
</div>
</template>
<script>
import tabbaritem from './Tabbar-item'
export default {
data(){
return{
tabList:[
{
path:'/home',
activeTextColor:'#f64257',
DSrc:'http://www.wsg3096.com/ass/tabbar/home-deactive.svg',
ASrc:'http://www.wsg3096.com/ass/tabbar/home-active.svg',
text:'首页'
},
{
path:'/class',
activeTextColor:'#f64257',
DSrc:'http://www.wsg3096.com/ass/tabbar/class-deactive.svg',
ASrc:'http://www.wsg3096.com/ass/tabbar/class-active.svg',
text:'分类'
},
{
path:'/car',
activeTextColor:'#f64257',
DSrc:'http://www.wsg3096.com/ass/tabbar/car-deactive.svg',
ASrc:'http://www.wsg3096.com/ass/tabbar/car-active.svg',
text:'购物车',
num:true
},
{
path:'/profile',
activeTextColor:'#f64257',
DSrc:'http://www.wsg3096.com/ass/tabbar/me-deactive.svg',
ASrc:'http://www.wsg3096.com/ass/tabbar/me-active.svg',
text:'我的'
}
]
}
},
name: "Main-tabbar",
components:{
tabbaritem
}
}
</script>
<style scoped>
#main{
display: flex;
box-shadow: 1px -1px rgba(88,88,88,0.1);
background: #f0f0f0;
position: fixed;
left: 0;
bottom: 0;
width: 100%;
}
</style>
根据数据 v-for 渲染 内部tabbaritem
细节1 查找自己的 path 属性 是否存在于当前路由中 来显示高亮效果
isActive(){ return this.$route.path.indexOf(this.path) !== -1 }
细节二 根据需要显示右上角 信息小标
这里只有一项需求 购物车哪一项显示当前购物车内商品数量 默认不显示
购物车这一项 新增 num:true
{ path:'/car', activeTextColor:'#f64257', DSrc:'http://www.wsg3096.com/ass/tabbar/car-deactive.svg', ASrc:'http://www.wsg3096.com/ass/tabbar/car-active.svg', text:'购物车', num:true },
<div class="item-num" v-if="num"> {{numss}} </div>props:{ num:{ type:Boolean, default:false }
<template>
<div class="tab-bat-item" @click="barclick">
<div v-if="isActive">
<slot name="item-active"></slot>
</div>
<div v-else>
<slot name="item-icon"></slot>
</div>
<div :style="activeStyle">
<slot name="item-text"></slot>
</div>
<div class="item-num" v-if="num">
{{numss}}
</div>
</div>
</template>
<script>
import {mapGetters} from 'vuex'
export default {
name: "Tabbar-item",
props:{
path:String,
activeTextColor:{
type:String,
default:'#f64257'
},
num:{
type:Boolean,
default:false
}
},
data(){
return{
//isActive:true,
}
},
computed:{
isActive(){
// /home -> item1(/home) = true
// /home -> item1(/class) = false
// /home -> item1(/car) = false
// /home -> item1(/profile) = false
return this.$route.path.indexOf(this.path) !== -1
// 返回 活跃的路由的path 是不是我这个路由 !== -1(不等于负一) 就是找到了 找到了 isActive 就是true
},
activeStyle(){
return this.isActive ? {color:this.activeTextColor} : {}
// isActive是true的话返回 父组件传过来的数据 父组件没有传这个数据就用默认的
},
...mapGetters('car',['numss'])
},
methods:{
barclick(){
this.$router.push(this.path);
//console.log('00');
}
}
}
</script>
<style scoped>
.tab-bat-item{
flex: 1;
text-align: center;
height: 49px;
font-size: 14px;
color: #b3b3b3;
padding-top: 3px;
box-sizing: border-box;
position: relative;
}
.tab-bat-item img{
width: 24px;
height: 24px;
vertical-align:middle;
}
.item-num{
position: absolute;
right: 6px;
top: 0px;
width: 24px;
height: 24px;
border-radius: 12px;
background: #ff3355;
color: white;
font-size: 14px;
line-height: 24px;
text-align: center;
}
</style>
效果:
挂载事件总线
步骤
pulgin/bus.js
import Vue from 'vue' Vue.prototype.$bus = new Vue()
nuxt.config.js中配置
plugins: [ '@plugins/bus', '@plugins/better-scroll', ],
Better-scroll
使用这个插件会使 移动端手指触屏滑动 更加丝滑
先安装
npm install better-scroll@2.4.2
pulgin/better-scroll.js :
import Bscroll from ‘better-scroll’
然后在 nuxt.config.js中配置 上面已经写到
封装组件:
模板部分:
wrapper 和 content 为固定结构
预留插槽 使用方法 使用此组件包裹 想要滚动的元素
<template> <div content="wrapper" ref="wrapper"> <div class="content"> <slot></slot> </div> </div> </template>
在mounted 生命周期中 new 一个 Bscroll 实例 增加相关配置
click 添加内部的点击事件
probeType 记录滚动的位置 可选择值 0 1 2
当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;
当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;(在手指滚动的过程中侦测,手指离开后的惯性滚动过程中不侦测。)
当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。( 就是我们用手用力滑动的时候,手放开之后,屏幕还在滑动,这就叫momentum 滚动动画 )
————————————————
版权声明:本文为CSDN博主「阿清呀.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wzg0817/article/details/108013765
pullUpLoad 上拉加载更多
mounted() { //创建 scroll 对象 this.scroll =new Bscroll(this.$refs.wrapper,{ click:true, // probeType:this.probeType, pullUpLoad:this.pullUpLoad, }) // probeType 是2 或者3 监听滚动的位置 if (this.probeType ===2 || this.probeType ===3){ this.scroll.on('scroll' ,(position)=>{ this.$emit('scrollpos',position) }) } //监听滚动到底部 this.scroll.on('pullingUp',()=>{ this.$emit('ToDown') }) },
组件内部的方法 外部可以通过 $refs.xxx 调用
methods:{ // 0.5杪返回到滚动顶部 scrollTo(x,y,time=500){ this.scroll.scrollTo(x,y,time) }, // 重新刷新 计算滚动高度 refresh(){ this.scroll.refresh() }, // 获取组件距离 页面最顶部的距离 getScrollY(){ return this.scroll ? this.scroll.y : 0 } }
在首页当中使用
传入 probeType= 3 需要记录滚动的位置
pullUpLoad= true 开启下拉加载更多
给类名 content 需要有一个 限定高度 (减去底部 tabbar的高度)
.content{ overflow: hidden; height: calc(100vh - 49px); }
<scroll class="content" ref="scroll" @scrollpos="scrollpos" :probeType="3" :pullUpLoad="true" @ToDown="ToDown"> ..... </scroll>
接收实时滚动的事件 scrollpos 和 滚动到底部的事件 ToDown
//监听位置 到1000了 显示返回顶部按钮 scrollpos(position){ this.isShow = (-position.y) >1000 // 到一定位置了goods按钮贴合顶部 this.isgoodfix = (-position.y) > this.$refs.goodbtns2.$el.offsetTop },//到底部时做什么 ToDown(){ console.log('我是有底线的'); //this.GetGoods(this.current.type) },
到1000了 显示返回顶部按钮
.backtop{ position: fixed; bottom: 68px; right: 6%; }
点击时返回顶部
backtop(){ this.$refs.scroll.scrollTo(0,0) },
调用的还是scroll组件内部的方法
还可以 返回首页的时候 停留在上次 离开的位置
//进入组件时做什么 activated() { this.$refs.scroll.scrollTo(0,this.saveY,0) this.$refs.scroll.refresh() }, // 离开组件时做什么 deactivated() { //记录离开时的Y位置 this.saveY = this.$refs.scroll.getScrollY() //取消商品列表图片加载时间的监听 this.$bus.$off('goodsimgload',this.goodsimglisten) }