vue 2によるアップロード機能の実現
本論文の例では、Vue 2のアップロードを実現するための具体的なコードを共有します。
私たちのプロジェクトの中でスウィートを使ったからです。多くはスライドスイッチですが、またアップロードしなければなりませんので、多くのUIフレームを使っています。全部違ったバグが現れました。しょうがないです。最後に一つ書きました。コードは以下の通りです。
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。
私たちのプロジェクトの中でスウィートを使ったからです。多くはスライドスイッチですが、またアップロードしなければなりませんので、多くのUIフレームを使っています。全部違ったバグが現れました。しょうがないです。最後に一つ書きました。コードは以下の通りです。
<template>
<div class="loadmore">
<slot></slot>
<slot name="bottom">
</slot>
</div>
</template>
<style>
.loadmore{
width:100%;
}
</style>
<script>
export default {
name: 'loadmore',
props: {
maxDistance: {
type: Number,
default: 0
},
autoFill: {
type: Boolean,
default: true
},
distanceIndex: {
type: Number,
default: 2
},
bottomPullText: {
type: String,
default: ' '
},
bottomDropText: {
type: String,
default: ' '
},
bottomLoadingText: {
type: String,
default: ' ...'
},
bottomDistance: {
type: Number,
default: 70
},
bottomMethod: {
type: Function
},
bottomAllLoaded: {
type: Boolean,
default: false
},
},
data() {
return {
// div
translate: 0,
//
scrollEventTarget: null,
containerFilled: false,
bottomText: '',
// class
bottomDropped: false,
// scrollTop
bottomReached: false,
// down--- ;up---
direction: '',
startY: 0,
startScrollTop: 0,
// clientY
currentY: 0,
topStatus: '',
// '' pull:
bottomStatus: '',
};
},
watch: {
//
bottomStatus(val) {
this.$emit('bottom-status-change', val);
switch (val) {
case 'pull':
this.bottomText = this.bottomPullText;
break;
case 'drop':
this.bottomText = this.bottomDropText;
break;
case 'loading':
this.bottomText = this.bottomLoadingText;
break;
}
}
},
methods: {
onBottomLoaded() {
this.bottomStatus = 'pull';
this.bottomDropped = false;
this.$nextTick(() => {
if (this.scrollEventTarget === window) {
document.body.scrollTop += 50;
} else {
this.scrollEventTarget.scrollTop += 50;
}
this.translate = 0;
});
//
if (!this.bottomAllLoaded && !this.containerFilled) {
this.fillContainer();
}
},
getScrollEventTarget(element) {
let currentNode = element;
while (currentNode && currentNode.tagName !== 'HTML' &&
currentNode.tagName !== 'BODY' && currentNode.nodeType === 1) {
let overflowY = document.defaultView.getComputedStyle(currentNode).overflowY;
if (overflowY === 'scroll' || overflowY === 'auto') {
return currentNode;
}
currentNode = currentNode.parentNode;
}
return window;
},
// scrollTop
getScrollTop(element) {
if (element === window) {
return Math.max(window.pageYOffset || 0, document.documentElement.scrollTop);
} else {
return element.scrollTop;
}
},
bindTouchEvents() {
this.$el.addEventListener('touchstart', this.handleTouchStart);
this.$el.addEventListener('touchmove', this.handleTouchMove);
this.$el.addEventListener('touchend', this.handleTouchEnd);
},
init() {
this.bottomStatus = 'pull';
//
this.scrollEventTarget = this.getScrollEventTarget(this.$el);
if (typeof this.bottomMethod === 'function') {
// autoFill
this.fillContainer();
//
this.bindTouchEvents();
}
},
// autoFill
fillContainer() {
if (this.autoFill) {
this.$nextTick(() => {
if (this.scrollEventTarget === window) {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
document.documentElement.getBoundingClientRect().bottom;
} else {
this.containerFilled = this.$el.getBoundingClientRect().bottom >=
this.scrollEventTarget.getBoundingClientRect().bottom;
}
if (!this.containerFilled) {
this.bottomStatus = 'loading';
this.bottomMethod();
}
});
}
},
// scrollTop
checkBottomReached() {
if (this.scrollEventTarget === window) {
return document.body.scrollTop + document.documentElement.clientHeight >= document.body.scrollHeight;
} else {
// getBoundingClientRect , , 。 right ,bottom 。
return this.$el.getBoundingClientRect().bottom <= this.scrollEventTarget.getBoundingClientRect().bottom + 1;
}
},
// ontouchstart
handleTouchStart(event) {
// y
this.startY = event.touches[0].clientY;
this.startScrollTop = this.getScrollTop(this.scrollEventTarget);
this.bottomReached = false;
if (this.bottomStatus !== 'loading') {
this.bottomStatus = 'pull';
this.bottomDropped = false;
}
},
// ontouchmove
handleTouchMove(event) {
if (this.startY < this.$el.getBoundingClientRect().top && this.startY > this.$el.getBoundingClientRect().bottom) {
// , scroll
return;
}
// clientY
this.currentY = event.touches[0].clientY;
// distance distanceIndex---
let distance = (this.currentY - this.startY) / this.distanceIndex;
// distance direction down--- ;up---
this.direction = distance > 0 ? 'down' : 'up';
if (this.direction === 'up') {
// scrollTop
this.bottomReached = this.bottomReached || this.checkBottomReached();
}
if (typeof this.bottomMethod === 'function' && this.direction === 'up' &&
this.bottomReached && this.bottomStatus !== 'loading' && !this.bottomAllLoaded) {
// , , , ajax,
event.preventDefault();
event.stopPropagation();
if (this.maxDistance > 0) {
this.translate = Math.abs(distance) <= this.maxDistance
? this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance : this.translate;
} else {
this.translate = this.getScrollTop(this.scrollEventTarget) - this.startScrollTop + distance;
}
if (this.translate > 0) {
this.translate = 0;
}
this.bottomStatus = -this.translate >= this.bottomDistance ? 'drop' : 'pull';
}
},
// ontouchend
handleTouchEnd() {
if (this.direction === 'up' && this.bottomReached && this.translate < 0) {
this.bottomDropped = true;
this.bottomReached = false;
if (this.bottomStatus === 'drop') {
this.translate = '-50';
this.bottomStatus = 'loading';
this.bottomMethod();
} else {
this.translate = '0';
this.bottomStatus = 'pull';
}
}
this.direction = '';
}
},
mounted() {
this.init();
}
};
</script>
どのページが必要ですか?どのページに導入すればいいですか?彼を紹介したいページの書き方は以下の通りです。
<template>
<section class="finan">
<!-- -->
<load-more
:bottom-method="loadBottom"
:bottom-all-loaded="allLoaded"
:bottomPullText='bottomText'
:auto-fill="false"
@bottom-status-change="handleBottomChange"
ref="loadmore">
<div>
</div>
<div v-show="loading" slot="bottom" class="loading"> div gif
<img src="./../../assets/main/uploading.gif">
</div>
</load-more>
</section>
</template>
このページのdata里とmethodsは以下のように設定されています。
export default {
name: 'FinancialGroup',
props:{
},
data () {
return {
//
scrollHeight: 0,
scrollTop: 0,
containerHeight: 0,
loading: false,
allLoaded: false,
bottomText: ' ...',
bottomStatus: '',
pageNo: 1,
totalCount: '',
}
},
methods: {
/* */
_scroll: function(ev) {
ev = ev || event;
this.scrollHeight = this.$refs.innerScroll.scrollHeight;
this.scrollTop = this.$refs.innerScroll.scrollTop;
this.containerHeight = this.$refs.innerScroll.offsetHeight;
},
loadBottom: function() {
this.loading = true;
this.pageNo += 1; //
if (this.pageNo == this.totalGetCount) {
// allLoaded = true
this.loading = false;
this.allLoaded = true;
}
api.commonApi( , ) api axios vue2+vuex+axios
.then(res => {
setTimeout(() => {
setTimeout
this.$nextTick(() => {
this.loading = false;
})
}, 1000)
});
},
handleBottomChange(status) {
this.bottomStatus = status;
},
}
これで完成です。以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。