优化首页刷新组件
This commit is contained in:
parent
83ecae3676
commit
03bda164b6
Binary file not shown.
|
Before Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.7 KiB |
@ -3,24 +3,29 @@
|
||||
<transition name="fade">
|
||||
<div class="mask" v-if="open" @click="open = false"></div>
|
||||
</transition>
|
||||
<div class="notice"><span>下拉刷新内容</span></div>
|
||||
<div class="toolbar" ref="toolbar">
|
||||
<div class="left" @click="$nav('/home/live')">直播</div>
|
||||
<div class="notice" :style="noticeStyle"><span>下拉刷新内容</span></div>
|
||||
<div class="toolbar" ref="toolbar" :style="toolbarStyle">
|
||||
<img src="../../assets/img/icon/scan.png"
|
||||
class="search"
|
||||
@click="$nav('/home/live')"
|
||||
style="margin-top: .5rem;">
|
||||
<div class="tab-ctn">
|
||||
<div class="tabs" ref="tabs">
|
||||
<div class="tab" :class="tabOneClass" @click.stop="change(0)">
|
||||
<span>同城</span>
|
||||
<img v-show="index === 0" src="../../assets/img/icon/arrow-up-white.png" alt="">
|
||||
<img v-show="index === 0" src="../../assets/img/icon/arrow-up-white.png" class="tab1-img">
|
||||
</div>
|
||||
<div class="tab" :class="{active:index === 1}" @click.stop="change(1)">
|
||||
<span>关注</span>
|
||||
<img src="../../assets/img/icon/live.webp" class="tab2-img">
|
||||
</div>
|
||||
<div class="tab" :class="{active:index === 2}" @click.stop="change(2)"><span>推荐</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="indicator" ref="indicator"></div>
|
||||
</div>
|
||||
<img src="../../assets/img/icon/search-gray.png" alt=""
|
||||
<img v-hide="!loading" src="../../assets/img/icon/search-light.png"
|
||||
class="search"
|
||||
@click="$nav('/home/search')"
|
||||
style="margin-top: .5rem;">
|
||||
</div>
|
||||
@ -33,12 +38,13 @@
|
||||
<div class="l-button" :class="{active:type === 2}" @click="toggleType(2)">热点</div>
|
||||
</div>
|
||||
|
||||
<Loading class="loading" style="width: 4rem;" :is-full-screen="false"/>
|
||||
<Loading :style="loadingStyle" class="loading" style="width: 4rem;" :is-full-screen="false"/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import Loading from "../../components/Loading";
|
||||
import bus from "../../utils/bus";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "IndicatorHome",
|
||||
@ -63,25 +69,72 @@ export default {
|
||||
lefts: [],
|
||||
indicatorSpace: 0,
|
||||
open: false,
|
||||
type: 1
|
||||
loading: false,
|
||||
type: 1,
|
||||
moveY: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['judgeValue', 'homeRefresh']),
|
||||
tabOneClass() {
|
||||
return {active: this.index === 0, open: this.open}
|
||||
},
|
||||
transform() {
|
||||
return `translate3d(0, ${this.moveY - this.judgeValue > this.homeRefresh ? this.homeRefresh : this.moveY - this.judgeValue}px, 0)`
|
||||
},
|
||||
toolbarStyle() {
|
||||
if (this.loading) {
|
||||
return {opacity: 1, 'transition-duration': '300ms', transform: `translate3d(0, 0, 0)`,}
|
||||
}
|
||||
if (this.moveY) {
|
||||
return {
|
||||
opacity: 1 - (this.moveY - this.judgeValue) / (this.homeRefresh / 2),
|
||||
transform: this.transform
|
||||
}
|
||||
}
|
||||
return {opacity: 1, 'transition-duration': '300ms', transform: `translate3d(0, 0, 0)`,}
|
||||
},
|
||||
noticeStyle() {
|
||||
if (this.loading) {
|
||||
return {opacity: 0,}
|
||||
}
|
||||
if (this.moveY) {
|
||||
return {
|
||||
opacity: (this.moveY - this.judgeValue) / (this.homeRefresh / 2) - .5,
|
||||
transform: this.transform
|
||||
}
|
||||
}
|
||||
return {opacity: 0,}
|
||||
},
|
||||
loadingStyle() {
|
||||
if (this.loading) {
|
||||
return {opacity: 1, 'transition-duration': '300ms',}
|
||||
}
|
||||
if (this.moveY) {
|
||||
return {
|
||||
opacity: (this.moveY - this.judgeValue) / (this.homeRefresh / 2) - .5,
|
||||
transform: this.transform
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
// index(newVal) {
|
||||
// this.end()
|
||||
// }
|
||||
},
|
||||
created() {
|
||||
},
|
||||
mounted() {
|
||||
this.initTabs()
|
||||
bus.on(this.name + '-move', this.move)
|
||||
bus.on(this.name + '-moveX', this.move)
|
||||
bus.on(this.name + '-moveY', e => {
|
||||
// console.log('moveY', e)
|
||||
this.moveY = e
|
||||
})
|
||||
bus.on(this.name + '-end', this.end)
|
||||
bus.on(this.name + '-loading', () => {
|
||||
console.log('loading')
|
||||
this.loading = true
|
||||
setTimeout(() => {
|
||||
this.loading = false
|
||||
}, 3000)
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
toggleType(type) {
|
||||
@ -118,9 +171,10 @@ export default {
|
||||
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
|
||||
this.$setCss(this.indicatorRef, 'left',
|
||||
this.lefts[this.index] -
|
||||
e.x.distance / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
|
||||
e / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
|
||||
},
|
||||
end(index) {
|
||||
this.moveY = 0
|
||||
this.$setCss(this.indicatorRef, 'transition-duration', `300ms`)
|
||||
this.$setCss(this.indicatorRef, 'left', this.lefts[index] + 'px')
|
||||
setTimeout(() => {
|
||||
@ -190,7 +244,7 @@ export default {
|
||||
color: rgb(156, 158, 165);
|
||||
position: relative;
|
||||
|
||||
img {
|
||||
.tab1-img {
|
||||
position: absolute;
|
||||
@width: 1rem;
|
||||
width: @width;
|
||||
@ -200,8 +254,15 @@ export default {
|
||||
margin-top: .7rem;
|
||||
}
|
||||
|
||||
.tab2-img {
|
||||
position: absolute;
|
||||
height: 1.5rem;
|
||||
left: 2.4rem;
|
||||
top: -.5rem;
|
||||
}
|
||||
|
||||
&.open {
|
||||
img {
|
||||
.tab1-img {
|
||||
transform: rotate(180deg);
|
||||
}
|
||||
}
|
||||
@ -223,6 +284,10 @@ export default {
|
||||
border-radius: .5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.search {
|
||||
width: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle-type {
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
<span>住宿</span>
|
||||
</div>
|
||||
</div>
|
||||
<SlideVertical>
|
||||
<div class="item" style="background: tan">
|
||||
<p style="padding: 1rem;" v-for="i in 50">
|
||||
<SlideVertical name="main">
|
||||
<div class="item">
|
||||
<p style="padding: 1rem;" v-for="i in 5">
|
||||
r2222222222222222222222222222222222222222222222222222222
|
||||
</p>
|
||||
</div>
|
||||
@ -60,14 +60,14 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<SlideVertical>
|
||||
<SlideVertical name="main">
|
||||
<div class="item">r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1</div>
|
||||
<div class="item">r2222222222222222222222222222222222222222222222222222222</div>
|
||||
<div class="item">r333333333333333333333333333333333333333333333333333333</div>
|
||||
</SlideVertical>
|
||||
</div>
|
||||
<div class="item">
|
||||
<SlideVertical>
|
||||
<SlideVertical name="main">
|
||||
<div class="item">r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1r1</div>
|
||||
<div class="item">r2222222222222222222222222222222222222222222222222222222</div>
|
||||
<div class="item">r333333333333333333333333333333333333333333333333333333</div>
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
<script lang="jsx">
|
||||
import bus from "../../utils/bus";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@ -25,9 +26,11 @@ export default {
|
||||
startY: 0,
|
||||
needCheck: true,
|
||||
next: false,
|
||||
judgeValue: 20
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['judgeValue'])
|
||||
},
|
||||
mounted() {
|
||||
this.wrapper = this.$refs.wrapper
|
||||
this.total = this.wrapper.children.length
|
||||
@ -59,9 +62,7 @@ export default {
|
||||
this.checkDirection(e)
|
||||
|
||||
if (this.next) {
|
||||
bus.emit(this.name + '-move', {
|
||||
x: {distance: this.moveX, isRight},
|
||||
})
|
||||
bus.emit(this.name + '-moveX', this.moveX)
|
||||
this.$stopPropagation(e)
|
||||
this.$setCss(this.wrapper, 'transform',
|
||||
`translate3d(${this.getDistance()
|
||||
@ -74,12 +75,7 @@ export default {
|
||||
if (!this.needCheck) return
|
||||
if (Math.abs(this.moveX) > this.judgeValue || Math.abs(this.moveY) > this.judgeValue) {
|
||||
let angle = (Math.abs(this.moveX) * 10) / (Math.abs(this.moveY) * 10)
|
||||
if (angle > 1) {
|
||||
this.next = true
|
||||
// console.log('横划')
|
||||
} else {
|
||||
// console.log('竖划')
|
||||
}
|
||||
this.next = angle > 1;
|
||||
// console.log(angle)
|
||||
return this.needCheck = false
|
||||
}
|
||||
@ -104,12 +100,12 @@ export default {
|
||||
this.$emit('update:index', this.lIndex)
|
||||
|
||||
this.reset()
|
||||
bus.emit(this.name + '-end', this.lIndex)
|
||||
},
|
||||
reset() {
|
||||
this.moveX = 0
|
||||
this.next = false
|
||||
this.needCheck = true
|
||||
bus.emit(this.name + '-end', this.lIndex)
|
||||
},
|
||||
getDistance() {
|
||||
return -this.lIndex * this.wrapperWidth
|
||||
|
||||
@ -1,5 +1,14 @@
|
||||
<script lang="jsx">
|
||||
import bus from "../../utils/bus";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
props: {
|
||||
name: {
|
||||
type: String,
|
||||
default: () => ''
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
wrapper: null,
|
||||
@ -13,9 +22,11 @@ export default {
|
||||
startY: 0,
|
||||
needCheck: true,
|
||||
next: false,
|
||||
judgeValue: 20
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['judgeValue','homeRefresh'])
|
||||
},
|
||||
mounted() {
|
||||
this.wrapper = this.$refs.wrapper
|
||||
this.total = this.wrapper.children.length
|
||||
@ -29,14 +40,18 @@ export default {
|
||||
this.startY = e.touches[0].pageY
|
||||
},
|
||||
touchMove(e) {
|
||||
console.log('move',e.touches[0].pageY)
|
||||
this.moveX = e.touches[0].pageX - this.startX
|
||||
this.moveY = e.touches[0].pageY - this.startY
|
||||
|
||||
let isDown = this.moveY < 0
|
||||
this.checkDirection(e)
|
||||
|
||||
if (this.index === 0 && !isDown && this.next) {
|
||||
bus.emit(this.name + '-moveY', this.moveY)
|
||||
}
|
||||
|
||||
if ((this.index === 0 && !isDown) || (this.index === this.total - 1 && isDown)) return
|
||||
|
||||
this.checkDirection(e)
|
||||
|
||||
if (this.next) {
|
||||
this.$stopPropagation(e)
|
||||
@ -55,12 +70,7 @@ export default {
|
||||
}
|
||||
if (Math.abs(this.moveX) > this.judgeValue || Math.abs(this.moveY) > this.judgeValue) {
|
||||
let angle = (Math.abs(this.moveX) * 10) / (Math.abs(this.moveY) * 10)
|
||||
if (angle > 1) {
|
||||
// console.log('横划')
|
||||
} else {
|
||||
this.next = true
|
||||
// console.log('竖划')
|
||||
}
|
||||
this.next = angle <= 1;
|
||||
// console.log(angle)
|
||||
return this.needCheck = false
|
||||
}
|
||||
@ -68,6 +78,9 @@ export default {
|
||||
},
|
||||
touchEnd(e) {
|
||||
let isDown = this.moveY < 0
|
||||
if (this.index === 0 && !isDown && this.moveY > (this.homeRefresh + this.judgeValue)) {
|
||||
bus.emit(this.name + '-loading')
|
||||
}
|
||||
let next = true
|
||||
if ((this.index === 0 && !isDown) || (this.index === this.total - 1 && isDown)) next = false
|
||||
|
||||
@ -88,12 +101,12 @@ export default {
|
||||
this.moveX = 0
|
||||
this.next = false
|
||||
this.needCheck = true
|
||||
bus.emit(this.name + '-end', this.index)
|
||||
},
|
||||
getDistance() {
|
||||
return -this.index * this.wrapperHeight
|
||||
},
|
||||
},
|
||||
|
||||
render(createElement, context) {
|
||||
return (
|
||||
<div className="slide">
|
||||
|
||||
@ -42,7 +42,9 @@ const store = Vuex.createStore({
|
||||
"is_private": 1
|
||||
},
|
||||
friends: resource.users,
|
||||
excludeRoutes: []
|
||||
excludeRoutes: [],
|
||||
judgeValue: 20,
|
||||
homeRefresh: 60,
|
||||
},
|
||||
mutations: {
|
||||
setUserinfo(store, val) {
|
||||
|
||||
@ -93,6 +93,22 @@ export default {
|
||||
el.addEventListener("touchend", cancel);
|
||||
el.addEventListener("touchcancel", cancel);
|
||||
}
|
||||
},
|
||||
hide: {
|
||||
beforeMount: function (el, binding, vNode) {
|
||||
if (binding.value) {
|
||||
el.style.opacity = 1
|
||||
} else {
|
||||
el.style.opacity = 0
|
||||
}
|
||||
},
|
||||
updated: function (el, binding, vNode) {
|
||||
if (binding.value) {
|
||||
el.style.opacity = 1
|
||||
} else {
|
||||
el.style.opacity = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user