优化slide

This commit is contained in:
zyronon 2022-03-25 00:43:13 +08:00
parent 5e5f42085e
commit 4531a0d240
7 changed files with 156 additions and 4316 deletions

4269
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,24 +7,24 @@
"serve": "vite preview" "serve": "vite preview"
}, },
"dependencies": { "dependencies": {
"@jambonn/vue-lazyload": "1.0.8", "@jambonn/vue-lazyload": "1.0.9",
"axios": "0.21.1", "axios": "0.26.1",
"core-js": "3.6.5", "core-js": "3.21.1",
"dayjs": "1.10.6", "dayjs": "1.11.0",
"lodash": "4.17.21", "lodash": "4.17.21",
"mitt": "2.1.0", "mitt": "3.0.0",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinyin": "2.9.0", "pinyin": "2.11.1",
"vue": "3.2.16", "vue": "3.2.31",
"vue-router": "4.0.8", "vue-router": "4.0.14",
"vue-switches": "2.0.1", "vue-switches": "2.0.1",
"vuex": "4.0.1" "vuex": "4.0.2"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "1.9.3", "@vitejs/plugin-vue": "2.2.4",
"@vitejs/plugin-vue-jsx": "1.2.0", "@vitejs/plugin-vue-jsx": "1.3.8",
"less": "^4.1.2", "less": "^4.1.2",
"mobile-select": "1.1.2", "mobile-select": "1.1.2",
"vite": "2.8.5" "vite": "2.8.6"
} }
} }

View File

@ -1,20 +1,24 @@
<template> <template>
<div class="indicator-home"> <div class="indicator-home">
<transition name="fade">
<div class="mask" v-if="open" @click="open = false"></div>
</transition>
<div class="notice"><span>下拉刷新内容</span></div> <div class="notice"><span>下拉刷新内容</span></div>
<div class="toolbar" ref="toolbar"> <div class="toolbar" ref="toolbar">
<div class="left" @click="$nav('/home/live')">直播</div> <div class="left" @click="$nav('/home/live')">直播</div>
<div class="tab-ctn"> <div class="tab-ctn">
<div class="tabs" ref="tabs"> <div class="tabs" ref="tabs">
<div class="tab" <div class="tab" :class="tabOneClass"
@click.stop="changeIndex(0)"> @click.stop="change(0)">
<span>同城</span> <span>同城</span>
<img src="../../assets/img/icon/arrow-up-white.png" alt="">
</div> </div>
<div class="tab" <div class="tab" :class="{active:index === 1}"
@click.stop="changeIndex(1)"> @click.stop="change(1)">
<span>关注</span> <span>关注</span>
</div> </div>
<div class="tab" <div class="tab" :class="{active:index === 2}"
@click.stop="changeIndex(2)"><span>推荐</span> @click.stop="change(2)"><span>推荐</span>
</div> </div>
</div> </div>
<div class="indicator" ref="indicator"></div> <div class="indicator" ref="indicator"></div>
@ -23,6 +27,14 @@
@click="$nav('/home/search')" @click="$nav('/home/search')"
style="margin-top: .5rem;"> style="margin-top: .5rem;">
</div> </div>
<div class="toggle-type" :class="{open}">
<div class="l-button active">
<span>同城</span>
<img src="../../assets/img/icon/switch.png" alt="">
</div>
<div class="l-button">学习</div>
</div>
<Loading class="loading" style="width: 4rem;" :is-full-screen="false"/> <Loading class="loading" style="width: 4rem;" :is-full-screen="false"/>
</div> </div>
</template> </template>
@ -51,20 +63,32 @@ export default {
return { return {
indicatorRef: null, indicatorRef: null,
lefts: [], lefts: [],
indicatorSpace: 0 indicatorSpace: 0,
open: false
} }
}, },
computed: {}, computed: {
watch: {}, tabOneClass() {
return {active: this.index === 0, open: this.open}
}
},
watch: {
// index(newVal) {
// this.end()
// }
},
created() { created() {
}, },
mounted() { mounted() {
this.initTabs() this.initTabs()
bus.on(this.name + '-moved', this.move) bus.on(this.name + '-move', this.move)
bus.on(this.name + '-end', this.end) bus.on(this.name + '-end', this.end)
}, },
methods: { methods: {
changeIndex(index) { change(index) {
if (this.index === 0 && index === 0) {
this.open = !this.open
}
this.$emit('update:index', index) this.$emit('update:index', index)
this.$setCss(this.indicatorRef, 'transition-duration', `300ms`) this.$setCss(this.indicatorRef, 'transition-duration', `300ms`)
this.$setCss(this.indicatorRef, 'left', this.lefts[index] + 'px') this.$setCss(this.indicatorRef, 'left', this.lefts[index] + 'px')
@ -84,36 +108,36 @@ export default {
this.$setCss(this.indicatorRef, 'left', this.lefts[this.index] + 'px') this.$setCss(this.indicatorRef, 'left', this.lefts[this.index] + 'px')
}, },
move(e) { move(e) {
console.log('move', e) this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
this.$setCss(this.indicatorRef, 'left', this.$setCss(this.indicatorRef, 'left',
this.lefts[this.index] - this.lefts[this.index] -
e.x.distance / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px') e.x.distance / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
}, },
end(index) { end(index) {
console.log(index)
this.$setCss(this.indicatorRef, 'transition-duration', `300ms`) this.$setCss(this.indicatorRef, 'transition-duration', `300ms`)
this.$setCss(this.indicatorRef, 'left', this.lefts[this.index] + 'px') this.$setCss(this.indicatorRef, 'left', this.lefts[index] + 'px')
setTimeout(() => { setTimeout(() => {
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`) this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
}, 300) }, 300)
} }
} },
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/assets/less/index"; @import "@/assets/less/index";
@height: 6rem;
.indicator-home { .indicator-home {
position: fixed; position: fixed;
font-size: 1.6rem; font-size: 1.6rem;
top: 0; top: 0;
left: 0; left: 0;
height: 60px;
z-index: 2; z-index: 2;
width: 100%; width: 100%;
color: white; color: white;
height: @height;
.notice { .notice {
opacity: 0; opacity: 0;
@ -156,7 +180,21 @@ export default {
.tab { .tab {
transition: color .3s; transition: color .3s;
color: gray; color: rgb(156, 158, 165);
img {
@width: 1rem;
width: @width;
height: @width;
margin-left: .4rem;
transition: all .3s;
}
&.open {
img {
transform: rotate(180deg);
}
}
&.active { &.active {
color: white; color: white;
@ -169,13 +207,70 @@ export default {
//transition: left .3s; //transition: left .3s;
position: absolute; position: absolute;
bottom: -0.8rem; bottom: -0.8rem;
height: .3rem; height: .2rem;
width: 2rem; width: 2rem;
background: #fff; background: #fff;
border-radius: .5rem; border-radius: .5rem;
} }
} }
} }
.toggle-type {
@height: 10rem;
position: absolute;
height: @height;
//padding-top: @height;
padding-left: 1rem;
padding-right: 1rem;
padding-bottom: 1rem;
width: 100%;
background: @main-bg;
display: flex;
justify-content: space-between;
align-items: flex-end;
box-sizing: border-box;
font-size: 1.2rem;
top: -@height;
transition: all .3s;
opacity: 0;
&.open {
top: 0;
opacity: 1;
}
.l-button {
width: 49%;
height: 2.8rem;
background: rgb(33, 36, 45);
display: flex;
align-items: center;
justify-content: center;
border-radius: 2rem;
color: rgb(157, 161, 170);
&.active {
background: rgb(57, 57, 65);
color: white;
}
img {
@width: .9rem;
width: @width;
height: @width;
margin-left: .8rem;
}
}
}
.mask {
top: 0;
position: absolute;
width: 100vw;
height: 100vh;
background: #00000066;
}
} }
</style> </style>

View File

@ -1,12 +1,12 @@
<template> <template>
<div id="Slide" @click="checkDbClick"> <div id="Slide" @click="checkDbClick">
<slide-horizontal> <SlideHorizontal>
<div class="item"> <div class="item">
<IndicatorHome <IndicatorHome
name="main" name="main"
v-model:index="index" v-model:index="index"
/> />
<slide-horizontal <SlideHorizontal
name="main" name="main"
v-model:index="index" v-model:index="index"
style="height: calc(100% - 5rem);" style="height: calc(100% - 5rem);"
@ -73,19 +73,19 @@
<div class="item">r333333333333333333333333333333333333333333333333333333</div> <div class="item">r333333333333333333333333333333333333333333333333333333</div>
</SlideVertical> </SlideVertical>
</div> </div>
</slide-horizontal> </SlideHorizontal>
<Footer v-bind:init-tab="1"/> <Footer v-bind:init-tab="1"/>
</div> </div>
<div class="item"> <div class="item">
<p v-for="i in 100">2</p> <p v-for="i in 100">2</p>
</div> </div>
</slide-horizontal> </SlideHorizontal>
</div> </div>
</template> </template>
<script> <script>
import SlideHorizontal from './slide-horizontal' import SlideHorizontal from './SlideHorizontal'
import SlideVertical from './slide-vertical' import SlideVertical from './SlideVertical'
import BVideo from "../../components/BVideo"; import BVideo from "../../components/BVideo";
import resource from "../../assets/data/resource"; import resource from "../../assets/data/resource";
import Dom from "../../utils/dom"; import Dom from "../../utils/dom";
@ -121,6 +121,7 @@ export default {
...mapState(['friends']), ...mapState(['friends']),
}, },
created() { created() {
console.log(this.$router)
this.getData() this.getData()
}, },
mounted() { mounted() {

View File

@ -2,17 +2,21 @@
import bus from "../../utils/bus"; import bus from "../../utils/bus";
export default { export default {
props:{ props: {
name: { name: {
type: String, type: String,
default: () => '' default: () => ''
}, },
index: {
type: Number,
default: () => 0
},
}, },
data() { data() {
return { return {
wrapper: null, wrapper: null,
total: 0, total: 0,
index: 0, lIndex: 0,
wrapperWidth: 0, wrapperWidth: 0,
wrapperHeight: 0, wrapperHeight: 0,
moveX: 0, moveX: 0,
@ -30,6 +34,14 @@ export default {
this.wrapperWidth = this.$getCss(this.wrapper, 'width') this.wrapperWidth = this.$getCss(this.wrapper, 'width')
this.wrapperHeight = this.$getCss(this.wrapper, 'height') this.wrapperHeight = this.$getCss(this.wrapper, 'height')
}, },
watch: {
index(newVal) {
this.lIndex = newVal
this.$setCss(this.wrapper, 'transition-duration', `300ms`)
this.$setCss(this.wrapper, 'transform',
`translate3d(${this.getDistance()}px, 0, 0)`)
}
},
methods: { methods: {
touchStart(e) { touchStart(e) {
this.$setCss(this.wrapper, 'transition-duration', `0ms`) this.$setCss(this.wrapper, 'transition-duration', `0ms`)
@ -41,13 +53,13 @@ export default {
this.moveY = e.touches[0].pageY - this.startY this.moveY = e.touches[0].pageY - this.startY
let isRight = this.moveX < 0 let isRight = this.moveX < 0
if ((this.index === 0 && !isRight) || (this.index === this.total - 1 && isRight)) return if ((this.lIndex === 0 && !isRight) || (this.lIndex === this.total - 1 && isRight)) return
this.checkDirection(e) this.checkDirection(e)
if (this.next) { if (this.next) {
bus.emit(this.name + '-moved', { bus.emit(this.name + '-move', {
x: {distance: this.moveX, isRight}, x: {distance: this.moveX, isRight},
}) })
this.$stopPropagation(e) this.$stopPropagation(e)
@ -76,22 +88,23 @@ export default {
touchEnd(e) { touchEnd(e) {
let isRight = this.moveX < 0 let isRight = this.moveX < 0
let next = true let next = true
if ((this.index === 0 && !isRight) || (this.index === this.total - 1 && isRight)) next = false if ((this.lIndex === 0 && !isRight) || (this.lIndex === this.total - 1 && isRight)) next = false
if (Math.abs(this.moveX) > (this.wrapperWidth / 4) && next) { if (Math.abs(this.moveX) > (this.wrapperWidth / 4) && next) {
if (isRight) { if (isRight) {
this.index++ this.lIndex++
} else { } else {
this.index-- this.lIndex--
} }
} }
this.$setCss(this.wrapper, 'transition-duration', `300ms`) this.$setCss(this.wrapper, 'transition-duration', `300ms`)
this.$setCss(this.wrapper, 'transform', this.$setCss(this.wrapper, 'transform',
`translate3d(${this.getDistance()}px, 0, 0)`) `translate3d(${this.getDistance()}px, 0, 0)`)
this.$attrs['onUpdate:index'] && this.$emit('update:index', this.index) this.$emit('update:index', this.lIndex)
this.reset() this.reset()
bus.emit(this.name + '-end', this.lIndex)
}, },
reset() { reset() {
this.moveX = 0 this.moveX = 0
@ -99,7 +112,7 @@ export default {
this.needCheck = true this.needCheck = true
}, },
getDistance() { getDistance() {
return -this.index * this.wrapperWidth return -this.lIndex * this.wrapperWidth
}, },
}, },

View File

@ -72,7 +72,7 @@ import Help from "../pages/login/Help";
import Uploader from "../pages/me/Uploader"; import Uploader from "../pages/me/Uploader";
import TestSlide from "../pages/test/TestSlide"; import TestSlide from "../pages/test/TestSlide";
import TestOne from "../pages/test/TestOne"; import TestOne from "../pages/test/TestOne";
import Slide from "../pages/slide/slide"; import Slide from "../pages/slide/Slide";
const routes = [ const routes = [
{ {