标签:flow nts 设置 拖动 param blog htm page from
接上篇 https://www.cnblogs.com/chenyingying0/p/12635080.html
上拉加载更多
base/scroll/index.vue
<template>
<!-- wiper会实例化构造函数,生成swiper实例 -->
<!-- ref="swiper"能够获取到这个swiper实例 -->
<swiper :options="swiperOption" ref=‘swiper‘>
<div class="mine-scroll-pull-down" v-if="pullDown">
<!-- ref="pullDownLoading" -- 获取下拉的loading -->
<me-loading :text="pullDownText" inline ref="pullDownLoading" />
</div>
<swiper-slide>
<slot></slot>
</swiper-slide>
<div class="mine-scroll-pull-up" v-if="pullUp">
<!-- ref="pullUpLoading" -- 获取上拉的loading -->
<me-loading :text="pullUpText" inline ref="pullUpLoading" />
</div>
<div class="swiper-scrollbar" v-if="scrollbar" slot="scrollbar"></div>
</swiper>
</template>
<script>
// 组件首字母大写,否则会报错
import {Swiper,SwiperSlide} from ‘vue-awesome-swiper‘;
import MeLoading from ‘base/loading‘;
import {
PULL_DOWN_HEIGHT,
PULL_DOWN_TEXT_INIT,
PULL_DOWN_TEXT_START,
PULL_DOWN_TEXT_ING,
PULL_DOWN_TEXT_END,
PULL_UP_HEIGHT,
PULL_UP_TEXT_INIT,
PULL_UP_TEXT_START,
PULL_UP_TEXT_ING,
PULL_UP_TEXT_END
} from ‘./config‘;
export default {
name:"MeScroll",
components:{
Swiper,
SwiperSlide,
MeLoading
},
props:{//过滤器
scrollbar:{
type:Boolean,
default:true
},
data:{//热门推荐加载完成后传递过来的recommends数据
type:[Array,Object]
},
pullDown:{//是真就开启下拉刷新
type:Boolean,
default:false
},
pullUp:{//是真就开启下拉加载
type:Boolean,
default:false
}
},
data(){
return {
pulling:false,//是否正在下拉
pullDownText:PULL_DOWN_TEXT_INIT,//设置下拉初始化文字
pullUpText:PULL_UP_TEXT_INIT,//设置上拉初始化文字
swiperOption:{
direction:‘vertical‘,//垂直方向
slidesPerView:‘auto‘,//一次显示几张
freeMode:true,//任意滑动多少距离
setWrapperSize:true,//根据内容设置容器尺寸
scrollbar:{
el:this.scrollbar?‘.swiper-scrollbar‘:null,
hide:true //滚动条自动隐藏
},
on:{
//swiper配置时会触发sliderMove方法,这里调用时执行自定义的scroll方法
sliderMove:this.scroll,
touchEnd:this.touchEnd//touchEnd是swiper提供的滚动结束的函数,this.touchEnd是我们自己写的函数
}
}
}
},
methods:{
update(){//不知道怎么写就去swiper官网查api
//console.log(this.$refs.swiper);//打印swiper实例
this.$refs.swiper && this.$refs.swiper.$swiper.update();//调用swiper.update()更新滚动条
},
scroll(){
const swiper=this.$refs.swiper.$swiper;
//如果正在下拉中,不会再次执行
if(this.pulling) return;
//console.log(swiper.translate);//打印出滚动条滚过的距离
if(swiper.translate>0){//下拉
if(!this.pullDown){//如果不需要下拉刷新
return;
}
if(swiper.translate>PULL_DOWN_HEIGHT){
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_START);
}else{
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_INIT);
}
}else if(swiper.isEnd){//上拉
if(!this.pullUp){
return;
}
//是否达到上拉的触发条件
//swiper的位移加上swiper的高度(617px)-50px的值如果大于当前内容高度
//swiper.translate这个属性可以获取到wrapper的位移,其实可以理解为滚动条滚动的距离
//swiper.height这个属性获取swiper容器的高度, 也就是显示区域的高度
//PULL_UP_HEIGHT是我们设置的一个值。为了让页面不是到达最低部的时候,可以提前加载内容
//parseInt(swiper.$wrapperEl.css(‘height‘))是wrapper的HTML元素的height属性, 也就是所有内容的高度
const isPullUp=Math.abs(swiper.translate)+swiper.height-PULL_UP_HEIGHT>parseInt(swiper.$wrapperEl.css(‘height‘));
if(isPullUp){//开始上拉
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_START);
}else{//保持初始化
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_INIT);
}
}
},
touchEnd(){
const swiper=this.$refs.swiper.$swiper;
//如果正在下拉中,不会再次执行
if(this.pulling) return;
if(swiper.translate>PULL_DOWN_HEIGHT){//如果距离大于设定的距离
if(!this.pullDown){//如果不需要下拉刷新
return;
}
this.pulling=true;
swiper.allowTouchMove=false;//禁止触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.setTranslate(PULL_DOWN_HEIGHT);//移动到设定的位置(拖动过度时回到设置的位置)
swiper.params.virtualTranslate=true;//定住不给回弹
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_ING);//设置正在刷新中的文字
this.$emit("pull-down",this.pullDownEnd);//触发消息,传递结束下拉的函数
}else if(swiper.isEnd){//上拉
//是否达到上拉的触发条件
const isPullUp=Math.abs(swiper.translate)+swiper.height-PULL_UP_HEIGHT>parseInt(swiper.$wrapperEl.css(‘height‘));
if(isPullUp){//开始上拉
if(!this.pullUp){//如果不需要上拉刷新
return;
}
this.pulling=true;
swiper.allowTouchMove=false;//禁止触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.setTranslate(-(parseInt(swiper.$wrapperEl.css(‘height‘))+PULL_UP_HEIGHT-swiper.height));//超过拉动距离时回弹
swiper.params.virtualTranslate=true;//定住不给回弹
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_ING);//设置正在刷新中的文字
this.$emit("pull-up",this.pullUpEnd);//触发消息,传递结束下拉的函数
}
}
},
pullDownEnd(){
const swiper=this.$refs.swiper.$swiper;
this.pulling=false;
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_END);//设置加载结束后的文字
swiper.allowTouchMove=true;//可以触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.params.virtualTranslate=false;//可以回弹
swiper.setTranslate(0);//移动到最初的位置
},
pullUpEnd(){
const swiper=this.$refs.swiper.$swiper;
this.pulling=false;
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_END);//设置加载结束后的文字
swiper.allowTouchMove=true;//可以触摸
swiper.params.virtualTranslate=false;//可以回弹
}
},
watch:{//检测数据变化的事件
data(){
this.update();//data数据变化时执行update函数
}
}
}
</script>
<style lang="scss" scoped>
@import ‘~assets/scss/mixins‘;
.swiper-container{
width:100%;
height:100%;
overflow:hidden;
& .swiper-slide{
height:auto;
}
}
//默认是不显示的
.mine-scroll-pull-down{
position:absolute;
left:0;
bottom:100%;
width:100%;
height:80px;
}
.mine-scroll-pull-up{
position:absolute;
left:0;
top:100%;
width:100%;
height:30px;
}
</style>
base/scroll/config.js
// 下拉相关常量 export const PULL_DOWN_HEIGHT=100; export const PULL_DOWN_TEXT_INIT=‘再拉,再拉就刷新给你看‘; export const PULL_DOWN_TEXT_START=‘够了啦,松开人家嘛‘; export const PULL_DOWN_TEXT_ING=‘刷的好累呀,喵~‘; export const PULL_DOWN_TEXT_END=‘刷新完啦‘; // 上拉相关常量 export const PULL_UP_HEIGHT=50; export const PULL_UP_TEXT_INIT=‘上拉初始文本‘; export const PULL_UP_TEXT_START=‘上拉开始文本‘; export const PULL_UP_TEXT_ING=‘正在上拉中‘; export const PULL_UP_TEXT_END=‘上拉结束文本‘;
pages/home/index.vue
<template>
<div class="home">
<header class="g-header-container">
<!-- 没有内容自闭合即可-->
<home-header/>
</header>
<!-- 滚动条接收到数据后开始更新 -->
<!-- pullDown是布尔值,可以使用简写直接传入,不加冒号 -->
<!-- 接收到pull-down消息后,触发pullToRefresh方法 -->
<me-scroll :data="recommends" pullDown pullUp @pull-down="pullToRefresh" @pull-up="pullToLoadMore">
<home-slider ref="slider" />
<home-nav />
<!-- 接收热门推荐加载完毕的消息 -->
<home-recommend @loaded="getRecommends" ref="recommend" />
</me-scroll>
<div class="g-backup-container"></div>
<!-- 当前页面存在二级页面时需要使用router-view -->
<router-view></router-view>
</div>
</template>
<script>
import MeScroll from ‘base/scroll‘;
import HomeHeader from ‘./header‘;
import HomeSlider from ‘./slider‘;
import HomeNav from ‘./nav‘;
import HomeRecommend from ‘./recommend‘;
export default {
name:"Home",
components:{
HomeHeader,
HomeSlider,
MeScroll,
HomeNav,
HomeRecommend
},
data(){
return{
recommends:[]
}
},
methods:{
getRecommends(recommends){
this.recommends=recommends;
},
updateScroll(){
},
pullToRefresh(end){
this.$refs.slider.update().then(end);
},
pullToLoadMore(end){
this.$refs.recommend.update().then(end).catch(err=>{
//没有更多内容时
if(err){
console.log(err);
}
end();
//禁止继续加载更多数据
//替换上拉时的loading,改为“没有更多数据了”
});
}
}
}
</script>
<style lang="scss" scoped>
// 引入前面需要加波浪线,否则会报错
@import "~assets/scss/mixins";
.home{
overflow:hidden;
width:100%;
height:100%;
background:$bgc-theme;
}
</style>
pages/home/recommend.vue
<template>
<div class="recommend">
<h3 class="recommend-title">热卖推荐</h3>
<div class="loading-container" v-if="!recommends.length">
<!-- 完整写法是 inline:inline ,不过布尔值类型可以直接写 inline -->
<me-loading inline />
</div>
<ul class="recommend-list">
<li class="recommend-item" v-for="(item,index) in recommends" :key="index">
<router-link class="recommend-link" :to="{name:‘home-product‘,params:{id:item.baseinfo.itemId}}">
<p class="recommend-pic"><img class="recommend-img" v-lazy="item.baseinfo.picUrl" ></p>
<!-- <p class="recommend-pic"><img class="recommend-img" :src="item.baseinfo.picUrl" ></p> -->
<p class="recommend-name">{{item.name.shortName}}</p>
<p class="recommend-oriPrice"><del>¥{{item.price.origPrice}}</del></p>
<p class="recommend-info">
<span class="recommend-price">¥<strong class="recommend-price-num">{{item.price.actPrice}}</strong></span>
<span class="recommend-count">{{item.remind.soldCount}}件已售</span>
</p>
</router-link>
</li>
</ul>
</div>
</template>
<script>
import {getHomeRecommend} from ‘api/home‘;
import MeLoading from ‘base/loading‘;
export default {
name:"HomeRecommend",
data(){
return {
recommends:[],
curPage:1,
totalPage:1
}
},
components:{
MeLoading
},
created(){
this.getRecommends();
},
methods:{
//api
update(){
return this.getRecommends();//返回promise对象
},
getRecommends(){
if(this.curPage>this.totalPage) return Promise.reject(new Error(‘没有更多了‘));
return getHomeRecommend(this.curPage).then(data=>{
return new Promise(resolve=>{
if(data){
//console.log(data);
this.curPage++;
this.totalPage=data.totalPage;
// concat合并数组内容,每次获取的数据都追加进来
this.recommends=this.recommends.concat(data.itemList);
this.$emit("loaded",this.recommends);//热门推荐区域加载完毕后触发消息
resolve();
}
})
});
}
}
}
</script>
<style lang="scss" scoped>
@import ‘~assets/scss/mixins‘;
.recommend{
position:relative;
width:100%;
padding:10px 0;
font-size:$font-size-l;
text-align:center;
&:before,
&:after{
content:"";
display:block;
position:absolute;
top:50%;
width:40%;
height:1px;
background:#ddd;
}
&:before{
left:0;
}
&:after{
right:0;
}
}
.recommend-list{
@include flex-between();
flex-wrap:wrap;
}
.recommend-title{
margin-bottom:8px;
}
.recommend-item{
width:49%;
background:#fff;
box-shadow:0 1px 1px 0 rgba(0,0,0,0.12);
margin-bottom:8px;
}
.recommend-link{
display:block;
}
.recommend-pic{
position:relative;
width:100%;
padding-top:100%;// 可以实现高度与宽度一致
margin-bottom:5px;
}
.recommend-img{
width:100%;
position:absolute;
top:0;
left:0;
height:100%;
}
.recommend-name{
height:40px;
padding:0 5px;
margin-bottom:8px;
line-height:1.5;
@include multiline-ellipsis();
text-align:left;
}
.recommend-oriPrice{
padding:0 5px;
margin-bottom:8px;
color:#ccc;
del{
}
}
.recommend-info{
@include flex-between();
padding:0 5px;
margin-bottom:8px;
}
.recommend-price{
color:#e61414;
&-num{
font-size:20px;
}
}
.recommend-count{
color:#999;
}
.loading-container{
padding-top:150px;
}
</style>
效果图

完善滚动条组件
base/scroll/index.vue
<template>
<!-- wiper会实例化构造函数,生成swiper实例 -->
<!-- ref="swiper"能够获取到这个swiper实例 -->
<swiper :options="swiperOption" ref=‘swiper‘>
<div class="mine-scroll-pull-down" v-if="pullDown">
<!-- ref="pullDownLoading" -- 获取下拉的loading -->
<me-loading :text="pullDownText" inline ref="pullDownLoading" />
</div>
<swiper-slide>
<slot></slot>
</swiper-slide>
<div class="mine-scroll-pull-up" v-if="pullUp">
<!-- ref="pullUpLoading" -- 获取上拉的loading -->
<me-loading :text="pullUpText" inline ref="pullUpLoading" />
</div>
<div class="swiper-scrollbar" v-if="scrollbar" slot="scrollbar"></div>
</swiper>
</template>
<script>
// 组件首字母大写,否则会报错
import {Swiper,SwiperSlide} from ‘vue-awesome-swiper‘;
import MeLoading from ‘base/loading‘;
import {
PULL_DOWN_HEIGHT,
PULL_DOWN_TEXT_INIT,
PULL_DOWN_TEXT_START,
PULL_DOWN_TEXT_ING,
PULL_DOWN_TEXT_END,
PULL_UP_HEIGHT,
PULL_UP_TEXT_INIT,
PULL_UP_TEXT_START,
PULL_UP_TEXT_ING,
PULL_UP_TEXT_END
} from ‘./config‘;
export default {
name:"MeScroll",
components:{
Swiper,
SwiperSlide,
MeLoading
},
props:{//过滤器
scrollbar:{
type:Boolean,
default:true
},
data:{//热门推荐加载完成后传递过来的recommends数据
type:[Array,Object]
},
pullDown:{//是真就开启下拉刷新
type:Boolean,
default:false
},
pullUp:{//是真就开启下拉加载
type:Boolean,
default:false
}
},
methods:{
update(){//不知道怎么写就去swiper官网查api
//console.log(this.$refs.swiper);//打印swiper实例
this.$refs.swiper && this.$refs.swiper.$swiper.update();//调用swiper.update()更新滚动条
},
scrollToTop(speed,runCallback){
// slideTo回到第x张幻灯片,swiper的API提供的
this.$refs.swiper && this.$refs.swiper.$swiper.slideTo(0,speed,runCallback);
},
init(){
//将不需要设置getter和setter的数据,放在init中初始化即可
this.pulling=false;//是否正在下拉
this.pullDownText=PULL_DOWN_TEXT_INIT;//设置下拉初始化文字
this.pullUpText=PULL_UP_TEXT_INIT;//设置上拉初始化文字
this.swiperOption={
direction:‘vertical‘,//垂直方向
slidesPerView:‘auto‘,//一次显示几张
freeMode:true,//任意滑动多少距离
setWrapperSize:true,//根据内容设置容器尺寸
scrollbar:{
el:this.scrollbar?‘.swiper-scrollbar‘:null,
hide:true //滚动条自动隐藏
},
on:{
//swiper配置时会触发sliderMove方法,这里调用时执行自定义的scroll方法
sliderMove:this.scroll,
touchEnd:this.touchEnd,//touchEnd是swiper提供的滚动结束的函数,this.touchEnd是我们自己写的函数,
transitionEnd:this.scrollEnd
}
};
},
scroll(){
const swiper=this.$refs.swiper.$swiper;
//滚动时触发scroll事件
this.$emit("scroll",swiper.translate,this.$refs.swiper.$swiper);
//如果正在下拉中,不会再次执行
if(this.pulling) return;
//console.log(swiper.translate);//打印出滚动条滚过的距离
if(swiper.translate>0){//下拉
if(!this.pullDown){//如果不需要下拉刷新
return;
}
if(swiper.translate>PULL_DOWN_HEIGHT){
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_START);
}else{
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_INIT);
}
}else if(swiper.isEnd){//上拉
if(!this.pullUp){
return;
}
//是否达到上拉的触发条件
//swiper的位移加上swiper的高度(617px)-50px的值如果大于当前内容高度
//swiper.translate这个属性可以获取到wrapper的位移,其实可以理解为滚动条滚动的距离
//swiper.height这个属性获取swiper容器的高度, 也就是显示区域的高度
//PULL_UP_HEIGHT是我们设置的一个值。为了让页面不是到达最低部的时候,可以提前加载内容
//parseInt(swiper.$wrapperEl.css(‘height‘))是wrapper的HTML元素的height属性, 也就是所有内容的高度
const isPullUp=Math.abs(swiper.translate)+swiper.height-PULL_UP_HEIGHT>parseInt(swiper.$wrapperEl.css(‘height‘));
if(isPullUp){//开始上拉
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_START);
}else{//保持初始化
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_INIT);
}
}
},
scrollEnd(){
this.$emit("scroll-end",this.$refs.swiper.$swiper.translate,this.$refs.swiper.$swiper);
},
touchEnd(){
const swiper=this.$refs.swiper.$swiper;
//如果正在下拉中,不会再次执行
if(this.pulling) return;
if(swiper.translate>PULL_DOWN_HEIGHT){//如果距离大于设定的距离
if(!this.pullDown){//如果不需要下拉刷新
return;
}
this.pulling=true;
swiper.allowTouchMove=false;//禁止触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.setTranslate(PULL_DOWN_HEIGHT);//移动到设定的位置(拖动过度时回到设置的位置)
swiper.params.virtualTranslate=true;//定住不给回弹
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_ING);//设置正在刷新中的文字
this.$emit("pull-down",this.pullDownEnd);//触发消息,传递结束下拉的函数
}else if(swiper.isEnd){//上拉
//是否达到上拉的触发条件
const isPullUp=Math.abs(swiper.translate)+swiper.height-PULL_UP_HEIGHT>parseInt(swiper.$wrapperEl.css(‘height‘));
if(isPullUp){//开始上拉
if(!this.pullUp){//如果不需要上拉刷新
return;
}
this.pulling=true;
swiper.allowTouchMove=false;//禁止触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.setTranslate(-(parseInt(swiper.$wrapperEl.css(‘height‘))+PULL_UP_HEIGHT-swiper.height));//超过拉动距离时回弹
swiper.params.virtualTranslate=true;//定住不给回弹
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_ING);//设置正在刷新中的文字
this.$emit("pull-up",this.pullUpEnd);//触发消息,传递结束下拉的函数
}
}
},
pullDownEnd(){
const swiper=this.$refs.swiper.$swiper;
this.pulling=false;
this.$refs.pullDownLoading.setText(PULL_DOWN_TEXT_END);//设置加载结束后的文字
swiper.allowTouchMove=true;//可以触摸
swiper.setTransition(swiper.params.speed);//设置初始速度
swiper.params.virtualTranslate=false;//可以回弹
swiper.setTranslate(0);//移动到最初的位置
//下拉完成后,显示head组件(下拉过程中会被隐藏)
setTimeout(()=>{
this.$emit("pull-down-transition-end");
},swiper.params.speed);
},
pullUpEnd(){
const swiper=this.$refs.swiper.$swiper;
this.pulling=false;
this.$refs.pullUpLoading.setText(PULL_UP_TEXT_END);//设置加载结束后的文字
swiper.allowTouchMove=true;//可以触摸
swiper.params.virtualTranslate=false;//可以回弹
}
},
watch:{//检测数据变化的事件
data(){
this.update();//data数据变化时执行update函数
}
},
created(){//在created中初始化数据
this.init();
}
}
</script>
<style lang="scss" scoped>
@import ‘~assets/scss/mixins‘;
.swiper-container{
width:100%;
height:100%;
overflow:hidden;
& .swiper-slide{
height:auto;
}
}
//默认是不显示的
.mine-scroll-pull-down{
position:absolute;
left:0;
bottom:100%;
width:100%;
height:80px;
}
.mine-scroll-pull-up{
position:absolute;
left:0;
top:100%;
width:100%;
height:30px;
}
</style>
标签:flow nts 设置 拖动 param blog htm page from
原文地址:https://www.cnblogs.com/chenyingying0/p/12635369.html