正在回答
同学你好,都是可以下拉的哦,可以测试下源码也是会下拉的。这个跟首页的下拉刷新使用的是同一个组件,并没有设置说要在顶部的时候不能下拉哦。
希望能帮助到你,祝学习愉快!
<template>
<swiper :options="swiperOption" ref="swiper">
<!-- 下拉 -->
<div class="mine-scroll-pull-down" v-if="pullDown">
<me-loading :text="pullDownText" ref="loadingPullDown"></me-loading>
</div>
<swiper-slide>
<slot></slot>
</swiper-slide>
<!-- 上拉 -->
<div class="mine-scroll-pull-up" v-if="pullUp">
<me-loading :text="pullUpText" ref="loadingPullUp"></me-loading>
</div>
<div class="swiper-scrollbar" v-if="scrollbar" slot="scrollbar"></div>
</swiper>
</template>
<script>
import {swiper, swiperSlide} from 'vue-awesome-swiper';
import MeLoading from '../loading/index';
import {
PULL_DOWN_HEIGHT,
PULL_DOWN_INIT_TEXT,
PULL_DOWN_START_TEXT,
PULL_DOWN_END_TEXT,
PULL_DOWN_ING_TEXT,
PULL_UP_HEIGHT,
PULL_UP_INIT_TEXT,
PULL_UP_START_TEXT,
PULL_UP_END_TEXT,
PULL_UP_ING_TEXT} from './config';
export default {
name: 'MeScroll',
components: {
MeLoading,
swiper,
swiperSlide
},
props: {
scrollbar: {
type: Boolean,
default: true
},
scrolldata: {
type: [Array, Object]
},
pullDown: {
type: Boolean,
default: false
},
pullUp: {
type: Boolean,
default: false
}
},
created() {
this.init();
},
watch: {
scrolldata() { // scrolldata发生变化时,执行方法
this.update();
}
},
methods: {
update() {
this.$refs.swiper && this.$refs.swiper.update(); // swiper更新方法
},
// 回到顶部的方法
scrollToTop(speed, runCallBack) {
this.$refs.swiper && this.$refs.swiper.swiper.slideTo(0, speed, runCallBack); // scrollTop是到第几个slide,因为只有一个,所以就等于回到顶部了
},
init() {
this.pulling = false;
this.pullDownText = PULL_DOWN_INIT_TEXT;
this.pullUpText = PULL_UP_INIT_TEXT;
this.swiperOption = {
direction: 'vertical',
slidesPerView: 'auto',
freeMode: true,
setWrapperSize: true,
scrollbar: {
el: this.scrollbar ? '.swiper-scrollbar' : null,
hide: true
},
on: {
sliderMove: this.scroll,
touchEnd: this.touchEnd,
transitionEnd: this.scrollEnd // 向上滑动时监听scrollEnd
}
};
},
scroll() {
const swiper = this.$refs.swiper.swiper;
this.$emit('scroll', swiper.translate, swiper);
if (this.pulling) {
return;
}
if (swiper.translate > 0) { // 下拉
if (!this.pullDown) {
return;
}
if (swiper.translate > PULL_DOWN_HEIGHT) {
this.$refs.loadingPullDown.setText(PULL_DOWN_START_TEXT);
} else {
this.$refs.loadingPullDown.setText(PULL_DOWN_INIT_TEXT);
}
} else if (swiper.isEnd) {
if (!this.pullUp) {
return;
}
// 视口高度+滚动条位置-dom对象的高度>50
const isPullUp = swiper.height + Math.abs(swiper.translate) - parseInt(swiper.$wrapperEl.css('height')) > PULL_UP_HEIGHT;
if (isPullUp) {
this.$refs.loadingPullUp.setText(PULL_UP_START_TEXT);
} else {
this.$refs.loadingPullUp.setText(PULL_UP_INIT_TEXT);
}
}
},
scrollEnd() {
this.$emit('scroll-end', this.$refs.swiper.swiper.translate, this.$refs.swiper.swiper, this.pulling); // 监听什么时候显示回到顶部的按钮
},
touchEnd() {
if (this.pulling) {
return;
}
const swiper = this.$refs.swiper.swiper;
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.loadingPullDown.setText(PULL_DOWN_ING_TEXT);
this.$emit('pull-down', this.pullDownEnd);
} else if (swiper.isEnd) {
const totalHeight = parseInt(swiper.$wrapperEl.css('height'));
const isPullUp = swiper.height + Math.abs(swiper.translate) - totalHeight > PULL_UP_HEIGHT;
if (isPullUp) { // 上拉
if (!this.pullUp) {
return;
}
this.pulling = true;
swiper.allowTouchMove = false; // 禁止触摸
swiper.setTransition(swiper.params.speed);
swiper.setTranslate(-(totalHeight + PULL_UP_HEIGHT - swiper.height));
swiper.params.virtualTranslate = true; // 定住不给回弹
this.$refs.loadingPullUp.setText(PULL_UP_ING_TEXT);
this.$emit('pull-up', this.pullUpEnd);
}
}
},
pullDownEnd() {
const swiper = this.$refs.swiper.swiper;
this.pulling = false;
this.$refs.loadingPullDown.setText(PULL_DOWN_END_TEXT);
swiper.params.virtualTranslate = false;
swiper.allowTouchMove = true;
swiper.setTransition(swiper.params.speed);
swiper.setTranslate(0);
// 下拉时隐藏header,回弹后显示header
setTimeout(() => {
this.$emit('pull-down-transition-end');
}, swiper.params.speed);
},
pullUpEnd() {
const swiper = this.$refs.swiper.swiper;
this.pulling = false;
this.$refs.loadingPullUp.setText(PULL_UP_END_TEXT);
swiper.params.virtualTranslate = false;
swiper.allowTouchMove = true;
}
}
};
</script>
<style lang="scss" scoped>
@import '~assets/scss/mixins';
.swiper-container {
overflow: hidden;
width: 100%;
height: 100%;
}
.swiper-slide {
height: auto;
}
.mine-scroll-pull-up,
.mine-scroll-pull-down{
position: absolute;
left: 0;
width: 100%;
}
.mine-scroll-pull-down{
bottom: 100%;
height: 80px;
}
.mine-scroll-pull-up {
top: 100%;
height: 30px;
}
</style><template>
<me-scroll :scrollbar = 'false'>
<ul class="tab">
<li
class="tab-item"
:class="{'tab-item-active': item.id === curId}"
v-for="(item, index) in items"
:key="index"
@click="switchTab(item.id)">
{{item.name}}
</li>
</ul>
</me-scroll>
</template>
<script>
import MeScroll from 'base/scroll';
import {categoryNames} from './config';
export default {
name: 'CategoryTab',
components: {MeScroll},
data() {
return {
curId: ''
};
},
created() {
this.init();
this.switchTab(this.items[0].id);
},
methods: {
init() {
this.items = categoryNames;
},
switchTab(id) {
if (this.curId === id) {
return;
}
this.curId = id;
this.$emit('switch-tab', id);
}
}
};
</script>
<style lang="scss" scoped>
@import "~assets/scss/mixins";
$tab-item-height: 46px;
.tab {
width: 100%;
background-color: #fff;
border-right: 1px solid $border-color;
&-item {
height: $tab-item-height;
@include ellipsis();
border-bottom: 1px solid $border-color;
font-size: $font-size-base;
color: #080808;
text-align: center;
line-height: $tab-item-height;
&:last-child {
border-bottom: none;
}
&-active {
color: $link-active-color;
font-weight: bold;
}
}
}
</style>
<template>
<div class="category">
<header class="g-header-container">
<category-header/>
</header>
<div class="g-content-container">
<div class="sidebar">
<category-tab @switch-tab="getCurrentId"></category-tab>
</div>
<div class="main"></div>
</div>
</div>
</template>
<script>
import CategoryHeader from './header';
import CategoryTab from './sidebar';
export default {
name: 'Category',
components: {
CategoryHeader,
CategoryTab
},
data() {
return {
curId: ''
};
},
methods: {
getCurrentId(id) {
this.curId = id;
}
}
};
</script>
<style lang="scss" scoped>
@import "~assets/scss/mixins";
.category {
overflow: hidden;
width: 100%;
height: 100%;
background-color: $bgc-theme;
}
.g-content-container {
display: flex;
}
.sidebar {
width: 80px;
height: 100%;
}
.main{
flex: 1;
height: 100%;
}
</style>
- 参与学习 人
- 提交作业 209 份
- 解答问题 3299 个
本路径是通过ES6基础知识、运用Zepto、Swiper、fullPag等移动端常用工具包、以及当下流行框架Vue,结合多个实战案例,还原真实开发场景,最终实现手机端购物商城网页开发。
了解课程

恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星