Vue webAPP首页开发

逆水行舟用力撑,一篙松劲退千寻。这篇文章主要讲述Vue webAPP首页开发相关的知识,希望能为你提供帮助。
接上篇  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=‘上拉结束文本‘;

【Vue webAPP首页开发】 
pages/home/index.vue
< template> < div class="home"> < header class="g-header-container"> < !-- 没有内容自闭合即可--> < home-header/> < /header> < !-- 滚动条接收到数据后开始更新 --> < !-- pullDown是布尔值,可以使用简写直接传入,不加冒号 --> < !-- 接收到pull-down消息后,触发pullToRefresh方法 --> < me-scroll :data="https://www.songbingjia.com/android/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="https://www.songbingjia.com/android/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=https://www.songbingjia.com/android/> { 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>

 
效果图
Vue webAPP首页开发

文章图片

 
完善滚动条组件
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>

 

    推荐阅读