Browse Source

优化

pull/29/head
zyronon 3 years ago
parent
commit
32fd4fd3c6
  1. 401
      src/pages/slide/Slide.vue
  2. 136
      src/pages/slide/SlideHorizontal.vue
  3. 129
      src/pages/slide/SlideVertical.vue
  4. 307
      src/pages/slide/SlideVerticalInfinite.vue
  5. 2
      src/pages/slideHooks/IndicatorHome.vue
  6. 13
      src/pages/slideHooks/VInfinite.vue
  7. 215
      src/pages/slideHooks/index.vue
  8. 2
      src/router/routes.js

401
src/pages/slide/Slide.vue

@ -1,401 +0,0 @@ @@ -1,401 +0,0 @@
<template>
<div id="home-index" v-love="'home-index'">
<SlideHorizontal>
<div class="slide-item">
<IndicatorHome
v-hide="isUp"
:loading="loading"
name="main"
v-model:index="baseIndex"
/>
<SlideHorizontal
name="main"
v-model:index="baseIndex"
style="height: calc(100% - 50rem);"
>
<div class="slide-item">
<div class="nav-one" :class="{close:closeOne}">
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>美食</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>休闲娱乐</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>游玩</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>丽人/美发</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>住宿</span>
</div>
</div>
<SlideVerticalInfinite
name="main"
:style="marginTop"
ref="virtualList"
:list="videos"
:prefix="videoPrefix[0]"
:renderSlide="render"
v-model:index="videoIndex"
@end="end"
@load-more="loadMore"
/>
</div>
</SlideHorizontal>
<Footer v-bind:init-tab="1"/>
</div>
<div class="slide-item">
<p v-for="i in 100">2</p>
</div>
</SlideHorizontal>
<Comment v-model="isUp"/>
<Share v-model="isSharing"
ref="share"
page-id="home-index"
@dislike="dislike"
:videoId="videos[videoIndex]?.id"
:canDownload="videos[videoIndex]?.canDownload"
@play-feedback="showPlayFeedback = true"
@showShareDuoshan="delayShowDialog(e => this.showShareDuoshan = true)"
@shareToFriend="delayShowDialog(e => this.shareToFriend = true)"
@showDouyinCode="showDouyinCode = true"
@showShare2WeChatZone="shareType = 2"
@share2WeChat="shareType = 3"
@share2QQZone="shareType = 4"
@share2QQ="shareType = 5"
@share2Webo="shareType = 8"
@download="shareType = 9"
/>
</div>
</template>
<script lang="jsx">
import SlideHorizontal from './SlideHorizontal'
import SlideVertical from './SlideVertical'
import BVideo from "../../components/slide/BVideo";
import resource from "../../assets/data/resource";
import Dom from "../../utils/dom";
import Footer from "../../components/Footer";
import Loading from "../../components/Loading";
import {mapState} from "vuex";
import IndicatorHome from "./IndicatorHome";
import SlideVerticalInfinite from "./SlideVerticalInfinite";
import Comment from "../../components/Comment";
import enums from "../../utils/enums";
import bus from "../../utils/bus";
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
import SlideColumnList from "../../components/slide/SlideColumnList";
import SlideRowList from "../../components/slide/SlideRowList";
import Video1 from "../../components/Video";
import Share from "../../components/Share";
import Uploader from "../me/Uploader";
import PlayFeedback from "../home/components/PlayFeedback";
import Duoshan from "../home/components/Duoshan";
import ShareTo from "../home/components/ShareTo";
import DouyinCode from "../../components/DouyinCode";
import FollowSetting from "../home/components/FollowSetting";
import FollowSetting2 from "../home/components/FollowSetting2";
import BlockDialog from "../message/components/BlockDialog";
import Search from "../../components/Search";
import ConfirmDialog from "../../components/dialog/ConfirmDialog";
import ShareToFriend from "../home/components/ShareToFriend";
export default {
name: "slide",
components: {
SlideHorizontal,
SlideVertical,
SlideVerticalInfinite,
BVideo,
Footer,
IndicatorHome,
FromBottomDialog,
SlideColumnList,
SlideRowList,
Video1,
Comment,
Share,
Uploader,
PlayFeedback,
Duoshan,
ShareTo,
DouyinCode,
FollowSetting,
FollowSetting2,
BlockDialog,
Search,
ConfirmDialog,
ShareToFriend
},
data() {
return {
baseIndex: 0,
videoIndex: 0,
closeOne: true,
videoPrefix: ['one', 'two', 'three'],
loading: false,
videos: [],
totalSize: 52,
pageSize: 10,
pageNo: 0,
isUp: false,
isCommenting: false,
isSharing: false,
canMove: true,
shareType: -1,
showPlayFeedback: false,
showShareDuoshan: false,
showShareDialog: false,
showShare2WeChatZone: false,
showDouyinCode: false,
showFollowSetting: false,
showFollowSetting2: false,
showBlockDialog: false,
showChangeNote: false,
shareToFriend: false,
render: (item, itemIndex, play, prefix) => {
return (
<div class="slide-item" data-index={itemIndex}>
<BVideo
isPlay={play}
item={item}
prefix={prefix}
index={itemIndex}
onShowComments={e => this.isCommenting = true}
onShowShare={e => this.isSharing = true}
onGoUserInfo={e => this.baseActiveIndex = 1}
onGoMusic={e => this.$nav('/home/music')}
v-model={[this.videos[itemIndex], 'video']}
/>
</div>
)
}
}
},
computed: {
...mapState([
'friends',
'bodyHeight',
'bodyWidth'
]),
marginTop() {
if (!this.isUp) return {'transition-duration': '300ms',}
return {
transform: `translate3d(0,-${((this.bodyHeight - 50) / 2) - (this.$refs.bvideo.videoScreenHeight / 2)}px,0)`,
'transition-duration': '300ms',
}
}
},
created() {
this.getData()
bus.on('singleClick', () => {
new Dom(`.v-${this.videoPrefix[this.baseIndex]}-${this.videoIndex}-video`).trigger('singleClick')
})
bus.on(this.videoPrefix[this.baseIndex] + '-loading', () => {
console.log('loading')
this.getData(true)
})
},
mounted() {
},
methods: {
delayShowDialog(cb) {
setTimeout(() => {
cb()
}, 400)
},
dislike() {
this.$refs.virtualList.dislike(this.videos[10])
this.videos[this.videoIndex] = this.videos[10]
this.$notice('操作成功,将减少此类视频的推荐')
},
loadMore() {
// return
if (!this.loading) {
this.pageNo++
this.getData()
}
},
t() {
this.isUp = !this.isUp
},
changeIndex() {
this.closeOne = !this.closeOne
},
async getData(refresh = false) {
if (this.loading) return
this.loading = true
let res = await this.$api.videos.recommended({pageNo: this.pageNo, pageSize: this.pageSize})
// console.log(res)
this.loading = false
if (res.code === this.SUCCESS) {
this.totalSize = res.data.total
if (refresh) {
this.videos = []
}
this.videos = this.videos.concat(res.data.list)
if (refresh) {
this.$refs.virtualList.refresh(this.videos)
}
} else {
this.pageNo--
}
},
end() {
this.$notice('暂时没有更多了')
}
}
}
</script>
<style lang="less">
#home-index {
height: 100vh;
width: 100vw;
color: white;
}
.slide {
height: 100%;
width: 100%;
overflow: hidden;
.slide-wrapper {
height: 100%;
width: 100%;
display: flex;
position: relative;
//transform: translateX(1rem);
}
.slide-item {
width: 100%;
min-width: 100%;
height: 100%;
min-height: 100%;
overflow: hidden;
position: relative;
}
}
.nav-one {
height: 140rem;
box-sizing: border-box;
background: linear-gradient(to right, rgb(36, 34, 84), rgb(7, 5, 16));
transition: all .3s;
padding: 2rem;
display: flex;
align-items: flex-end;
justify-content: space-between;
.nav-item {
@width: 35rem;
display: flex;
align-items: center;
flex-direction: column;
img {
width: @width;
height: @width;
margin-bottom: 5rem;
}
}
&.close {
margin-top: -140rem;
}
}
@space-width: 15rem;
@icon-width: 52rem;
.nav-two {
height: 180rem;
display: flex;
flex-direction: column;
justify-content: flex-end;
box-sizing: border-box;
padding: @space-width;
transition: .3s;
.title {
width: 100%;
display: flex;
justify-content: space-between;
box-sizing: border-box;
margin-bottom: 15rem;
.right {
color: gray;
display: flex;
align-items: center;
}
img {
width: 10rem;
height: 10rem;
margin-left: 4rem;
}
}
.users {
display: flex;
width: 100%;
overflow: hidden;
.user {
width: @icon-width;
position: relative;
margin-right: @space-width;
font-size: 10rem;
display: flex;
flex-direction: column;
align-items: center;
.avatar {
width: @icon-width;
height: @icon-width;
border-radius: 50%;
}
span {
margin-top: 8rem;
text-align: center;
width: @icon-width;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.tag {
background: rgb(239, 46, 137);
border-radius: 2rem;
padding: 0 2rem;
bottom: 18rem;
position: absolute;
font-size: 10rem;
}
}
}
&.close {
margin-top: -180rem;
}
}
</style>

136
src/pages/slide/SlideHorizontal.vue

@ -1,136 +0,0 @@ @@ -1,136 +0,0 @@
<script lang="jsx">
import bus from "../../utils/bus";
import {mapState} from "vuex";
export default {
props: {
name: {
type: String,
default: () => ''
},
index: {
type: Number,
default: () => 0
},
},
data() {
return {
wrapper: null,
childs: 0,
lIndex: 0,
wrapperWidth: 0,
wrapperHeight: 0,
moveX: 0,
moveY: 0,
startX: 0,
startY: 0,
needCheck: true,
next: false,
startTime: null
}
},
computed: {
...mapState(['judgeValue'])
},
mounted() {
this.wrapper = this.$refs.wrapper
this.childs = this.wrapper.children.length
this.wrapperWidth = this.$getCss(this.wrapper, 'width')
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: {
touchStart(e) {
this.$setCss(this.wrapper, 'transition-duration', `0ms`)
this.startX = e.touches[0].pageX
this.startY = e.touches[0].pageY
this.startTime = Date.now()
},
touchMove(e) {
this.moveX = e.touches[0].pageX - this.startX
this.moveY = e.touches[0].pageY - this.startY
let isRight = this.moveX < 0
if ((this.lIndex === 0 && !isRight) || (this.lIndex === this.childs - 1 && isRight)) return
this.checkDirection(e)
if (this.next) {
bus.emit(this.name + '-moveX', this.moveX)
this.$stopPropagation(e)
this.$setCss(this.wrapper, 'transform',
`translate3d(${this.getDistance()
+ this.moveX
+ (isRight ? this.judgeValue : -this.judgeValue)
}px, 0, 0)`)
}
},
checkDirection(e) {
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)
this.next = angle > 1;
// console.log(angle)
return this.needCheck = false
}
return this.needCheck = true
},
touchEnd(e) {
let isRight = this.moveX < 0
if ((this.lIndex === 0 && !isRight) || (this.lIndex === this.childs - 1 && isRight)) this.next = false
let endTime = Date.now()
let gapTime = endTime - this.startTime
if (Math.abs(this.moveX) < 20) gapTime = 1000
if (Math.abs(this.moveX) > (this.wrapperWidth / 4)) gapTime = 100
if (gapTime < 150 && this.next) {
if (isRight) {
this.lIndex++
} else {
this.lIndex--
}
}
this.reset()
},
reset() {
this.$setCss(this.wrapper, 'transition-duration', `300ms`)
this.$setCss(this.wrapper, 'transform',
`translate3d(${this.getDistance()}px, 0, 0)`)
this.moveX = 0
this.next = false
this.needCheck = true
this.startTime = null
this.$emit('update:index', this.lIndex)
bus.emit(this.name + '-end', this.lIndex)
},
getDistance() {
return -this.lIndex * this.wrapperWidth
},
},
render(createElement, context) {
return (
<div className="slide">
<div className="slide-wrapper"
ref="wrapper"
ontouchstart={this.touchStart.bind(this)}
ontouchmove={this.touchMove.bind(this)}
ontouchend={this.touchEnd.bind(this)}
>
{this.$slots.default()}
</div>
</div>
)
}
}
</script>

129
src/pages/slide/SlideVertical.vue

@ -1,129 +0,0 @@ @@ -1,129 +0,0 @@
<script lang="jsx">
import bus from "../../utils/bus";
import {mapState} from "vuex";
export default {
props: {
name: {
type: String,
default: () => ''
},
},
data() {
return {
wrapper: null,
total: 0,
index: 0,
wrapperWidth: 0,
wrapperHeight: 0,
moveX: 0,
moveY: 0,
startX: 0,
startY: 0,
needCheck: true,
next: false,
startTime: null
}
},
computed: {
...mapState(['judgeValue', 'homeRefresh'])
},
mounted() {
this.wrapper = this.$refs.wrapper
this.total = this.wrapper.children.length
this.wrapperWidth = this.$getCss(this.wrapper, 'width')
this.wrapperHeight = this.$getCss(this.wrapper, 'height')
},
methods: {
touchStart(e) {
this.$setCss(this.wrapper, 'transition-duration', `0ms`)
this.startX = e.touches[0].pageX
this.startY = e.touches[0].pageY
this.startTime = Date.now()
},
touchMove(e) {
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
if (this.next) {
this.$stopPropagation(e)
this.$setCss(this.wrapper, 'transform',
`translate3d(0,${this.getDistance()
+ this.moveY
+ (isDown ? this.judgeValue : -this.judgeValue)
}px, 0)`)
}
},
checkDirection(e) {
if (this.needCheck) {
// this.$stopPropagation(e)
} else {
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)
this.next = angle <= 1;
// console.log(angle)
return this.needCheck = false
}
return this.needCheck = true
},
touchEnd(e) {
let isDown = this.moveY < 0
if (this.index === 0 && !isDown && this.moveY > (this.homeRefresh + this.judgeValue)) {
bus.emit(this.name + '-loading')
}
if ((this.index === 0 && !isDown) || (this.index === this.total - 1 && isDown)) this.next = false
let endTime = Date.now()
let gapTime = endTime - this.startTime
if (Math.abs(this.moveY) < 20) gapTime = 1000
if (Math.abs(this.moveY) > (this.wrapperHeight / 4)) gapTime = 100
if (gapTime < 150 && this.next) {
if (isDown) {
this.index++
} else {
this.index--
}
}
this.$setCss(this.wrapper, 'transition-duration', `300ms`)
this.$setCss(this.wrapper, 'transform',
`translate3d(0,${this.getDistance()}px, 0)`)
this.reset()
},
reset() {
this.moveX = 0
this.next = false
this.startTime = null
this.needCheck = true
bus.emit(this.name + '-end', this.index)
},
getDistance() {
return -this.index * this.wrapperHeight
},
},
render(createElement, context) {
return (
<div className="slide">
<div className="slide-wrapper"
style="flex-direction: column;"
ref="wrapper"
ontouchstart={this.touchStart.bind(this)}
ontouchmove={this.touchMove.bind(this)}
ontouchend={this.touchEnd.bind(this)}
>
{this.$slots.default()}
</div>
</div>
)
}
}
</script>

307
src/pages/slide/SlideVerticalInfinite.vue

@ -1,307 +0,0 @@ @@ -1,307 +0,0 @@
<script lang="jsx">
import bus from "../../utils/bus";
import {mapState} from "vuex";
import * as Vue from "vue";
import Dom from "../../utils/dom";
export default {
props: {
name: {
type: String,
default: () => ''
},
prefix: {
type: String,
default: () => ''
},
renderSlide: {
type: Function,
default: () => {
return null
}
},
list: {
type: Array,
default: () => {
return []
}
},
virtualTotal: {
type: Number,
default: () => 5
},
index: {
type: Number,
default: () => 0
},
},
data() {
return {
wrapper: null,
childs: 0,
lIndex: 0,
wrapperWidth: 0,
wrapperHeight: 0,
moveX: 0,
moveY: 0,
startX: 0,
startY: 0,
needCheck: true,
next: false,
startTime: null,
appInsMap: new Map()
}
},
computed: {
...mapState(['judgeValue', 'homeRefresh'])
},
watch: {
lIndex(newVal, oldVal) {
new Dom(this.wrapper).find(`.v-${this.prefix}-${newVal}-video`).trigger('play')
setTimeout(() => {
new Dom(this.wrapper).find(`.v-${this.prefix}-${oldVal}-video`).trigger('stop')
}, 200)
if (newVal >= this.list.length - 3) {
this.$emit('load-more')
}
},
list(newVal, oldVal) {
// console.log('watch', newVal.length, oldVal.length)
if (oldVal.length === 0) {
this.insertContent()
} else {
let end = oldVal.length + 3
let top = $(this.wrapper).find(".slide-item:last").css('top')
newVal.slice(oldVal.length, end).map((item, index) => {
let el = this.getInsEl(item, oldVal.length + index)
//top
//2022-3-27slide-itemtop
//top
// top
$(el).css('top', top)
this.wrapper.appendChild(el)
})
this.childs = this.wrapper.children.length
// console.log(this.childs)
}
}
},
mounted() {
this.lIndex = this.index
this.checkChildren()
this.insertContent()
},
methods: {
refresh(list) {
$(this.wrapper).empty()
list && this.insertContent(list)
},
dislike(item) {
let currentItem = $(this.wrapper).find(`.slide-item[data-index=${this.lIndex}]`)
let replaceItem = this.getInsEl(item, this.lIndex, true)
new Dom(replaceItem).css('top', currentItem.css('top'))
currentItem.replaceWith(replaceItem)
},
checkChildren() {
this.wrapper = this.$refs.wrapper
this.wrapperWidth = this.$getCss(this.wrapper, 'width')
this.wrapperHeight = this.$getCss(this.wrapper, 'height')
},
//使this.list,vuevideosthis.list
insertContent(list = this.list) {
let start = 0
let that = this
if (this.lIndex >= (this.virtualTotal - 1) / 2) {
start = this.lIndex - (this.virtualTotal - 1) / 2
}
let end = start + 5
if (end >= list.length) {
end = list.length
start = end - 5
}
if (start < 0) start = 0
// console.log('start', start)
// console.log('end', end)
list.slice(start, end).map(
(item, index) => {
//0jqtrigger play
let el = this.getInsEl(item, start + index, start + index === this.lIndex)
this.wrapper.appendChild(el)
}
)
this.$setCss(this.wrapper, 'transform', `translate3d(0px,
${-this.lIndex * this.wrapperHeight}px, 0px)`)
if (this.lIndex > 2 && list.length > 5) {
$(this.wrapper).find(".slide-item").each(function () {
if ((list.length - that.lIndex) > 2) {
$(this).css('top', (that.lIndex - 2) * that.wrapperHeight)
} else {
$(this).css('top', start * that.wrapperHeight)
}
})
}
this.childs = this.wrapper.children.length
},
getInsEl(item, index, play = false) {
// console.log('index',index,play)
let slideVNode = this.renderSlide(item, index, play, this.prefix)
const app = Vue.createApp({
render() {
return slideVNode
}
})
const parent = document.createElement('div')
const ins = app.mount(parent)
this.appInsMap.set(index, app)
// this.appInsMap.set(index, ins)
return ins.$el
},
touchStart(e) {
this.$setCss(this.wrapper, 'transition-duration', `0ms`)
this.startX = e.touches[0].pageX
this.startY = e.touches[0].pageY
this.startTime = Date.now()
},
//TODO 2022-3-28:
touchMove(e) {
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.lIndex === 0 && !isDown && this.next) {
bus.emit(this.name + '-moveY', this.moveY)
}
if ((this.lIndex === 0 && !isDown) || (this.lIndex === this.list.length - 1 && isDown)) return
if (this.next) {
this.$stopPropagation(e)
this.$setCss(this.wrapper, 'transform',
`translate3d(0,${this.getDistance()
+ this.moveY
+ (isDown ? this.judgeValue : -this.judgeValue)
}px, 0)`)
}
},
checkDirection(e) {
if (this.needCheck) {
// this.$stopPropagation(e)
} else {
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)
this.next = angle <= 1;
// console.log(angle)
return this.needCheck = false
}
return this.needCheck = true
},
touchEnd(e) {
let isDown = this.moveY < 0
if (this.lIndex === 0 && !isDown && this.moveY > (this.homeRefresh + this.judgeValue)) {
bus.emit(this.prefix + '-loading')
}
if ((this.lIndex === 0 && !isDown) || (this.lIndex === this.list.length - 1 && isDown)) this.next = false
let endTime = Date.now()
let gapTime = endTime - this.startTime
if (Math.abs(this.moveY) < 20) gapTime = 1000
if (Math.abs(this.moveY) > (this.wrapperHeight / 3)) gapTime = 100
if (gapTime < 150 && this.next) {
if (isDown) {
this.lIndex++
} else {
this.lIndex--
}
let that = this
if (isDown) {
let addItemIndex = this.lIndex + 2
let res = $(that.wrapper).find(`.slide-item[data-index=${addItemIndex}]`)
if (this.childs < this.virtualTotal) {
if (res.length === 0) {
this.wrapper.appendChild(this.getInsEl(this.list[addItemIndex], addItemIndex))
}
}
if (this.childs === this.virtualTotal
&& this.lIndex >= (this.virtualTotal + 1) / 2
&& this.lIndex <= this.list.length - 3
) {
if (res.length === 0) {
this.wrapper.appendChild(this.getInsEl(this.list[addItemIndex], addItemIndex))
this.appInsMap.get($(that.wrapper).find(".slide-item:first").data('index')).unmount()
// $(that.wrapper).find(".base-slide-item:first").remove()
$(that.wrapper).find(".slide-item").each(function () {
$(this).css('top', (that.lIndex - 2) * that.wrapperHeight)
})
}
}
if (this.childs > this.virtualTotal) {
$(that.wrapper).find(".slide-item").each(function () {
let index = $(this).data('index')
if (index < (that.lIndex - 2)) {
that.appInsMap.get(index).unmount()
}
$(this).css('top', (that.lIndex - 2) * that.wrapperHeight)
})
}
} else {
let addItemIndex = this.lIndex - 2
let res = $(that.wrapper).find(`.slide-item[data-index=${addItemIndex}]`)
if (this.lIndex > 1 && this.lIndex <= this.list.length - 4) {
if (res.length === 0) {
this.wrapper.prepend(this.getInsEl(this.list[addItemIndex], addItemIndex))
this.appInsMap.get($(that.wrapper).find(".slide-item:last").data('index')).unmount()
// $(that.wrapper).find(".base-slide-item:last").remove()
$(that.wrapper).find(".slide-item").each(function () {
$(this).css('top', (that.lIndex - 2) * that.wrapperHeight)
})
}
}
if (this.childs > this.virtualTotal) {
this.appInsMap.get($(that.wrapper).find(".slide-item:last").data('index')).unmount()
}
}
this.childs = this.wrapper.children.length
}
this.reset()
},
reset() {
this.$setCss(this.wrapper, 'transition-duration', `300ms`)
this.$setCss(this.wrapper, 'transform',
`translate3d(0,${this.getDistance()}px, 0)`)
this.moveX = 0
this.next = false
this.startTime = null
this.needCheck = true
this.$emit('update:index', this.lIndex)
bus.emit(this.name + '-end', this.lIndex)
},
getDistance() {
return -this.lIndex * this.wrapperHeight
},
},
render(createElement, context) {
return (
<div className="slide">
<div className="slide-wrapper"
style="flex-direction: column;"
ref="wrapper"
ontouchstart={this.touchStart.bind(this)}
ontouchmove={this.touchMove.bind(this)}
ontouchend={this.touchEnd.bind(this)}
>
{this.$slots.default && this.$slots.default()}
</div>
</div>
)
}
}
</script>

2
src/pages/slide/IndicatorHome.vue → src/pages/slideHooks/IndicatorHome.vue

@ -46,7 +46,7 @@ @@ -46,7 +46,7 @@
</div>
</template>
<script>
import Loading from "../../components/Loading";
import Loading from "../../components/Loading.vue";
import bus from "../../utils/bus";
import {mapState} from "vuex";

13
src/pages/slideHooks/VInfinite.vue

@ -7,6 +7,7 @@ import SlideItem from './SlideItem' @@ -7,6 +7,7 @@ import SlideItem from './SlideItem'
import bus from "../../utils/bus";
import {useStore} from 'vuex'
import Utils from "../../utils";
import Dom from "@/utils/dom";
const props = defineProps({
index: {
@ -87,7 +88,16 @@ watch( @@ -87,7 +88,16 @@ watch(
})
}
}
},
}
)
watch(
()=>props.index,
()=>{
// new Dom(this.wrapper).find(`.v-${this.prefix}-${newVal}-video`).trigger('play')
// setTimeout(() => {
// new Dom(this.wrapper).find(`.v-${this.prefix}-${oldVal}-video`).trigger('stop')
// }, 200)
}
)
onMounted(() => {
@ -149,6 +159,7 @@ function touchStart(e) { @@ -149,6 +159,7 @@ function touchStart(e) {
slideTouchStart(e, wrapperEl.value, state)
}
//TODO 2022-3-28:
function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue.value, canNext, null, SlideType.VERTICAL)
}

215
src/pages/slideHooks/index.vue

@ -1,63 +1,64 @@ @@ -1,63 +1,64 @@
<template>
<div class="test-slide-wrapper">
<IndicatorHome
v-if="!state.fullScreen"
v-hide="state.isUp"
:loading="state.loading"
name="main"
v-model:index="state.navIndex"
/>
<div class="sub-type"
:class="state.subTypeIsTop?'top':''"
ref="subTypeRef">
<div class="local">
<div class="card" @touchmove.capture="stop">
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>美食</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>休闲娱乐</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>游玩</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>丽人/美发</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>住宿</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>游玩</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>丽人/美发</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>住宿</span>
<H v-model:index="state.baseIndex">
<SlideItem>
<IndicatorHome
v-if="!state.fullScreen"
v-hide="state.isUp"
:loading="state.loading"
name="main"
v-model:index="state.navIndex"
/>
<div class="sub-type"
:class="state.subTypeIsTop?'top':''"
ref="subTypeRef">
<div class="local">
<div class="card" @touchmove.capture="stop">
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>美食</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>休闲娱乐</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>游玩</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>丽人/美发</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>住宿</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>游玩</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>丽人/美发</span>
</div>
<div class="nav-item">
<img src="../../assets/img/icon/msg-icon9.webp" alt="">
<span>住宿</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="sub-type-notice"
v-if="state.subType===-1"
@click="showSubType">附近吃喝玩乐
</div>
<div class="slide-content" id="slideHook"
@touchstart="pageClick"
v-love="'slideHook'">
<H v-model:index="state.baseIndex">
<SlideItem>
<H class="h"
<div class="sub-type-notice"
v-if="state.subType===-1"
@click="showSubType">附近吃喝玩乐
</div>
<div class="slide-content"
@touchstart="pageClick">
<H class="first-horizontal-item"
name="main"
id="slideHook"
v-love="'slideHook'"
v-model:index="state.navIndex">
<SlideItem class=" gray">
<div class="big">热点</div>
@ -87,23 +88,33 @@ @@ -87,23 +88,33 @@
</VInfinite>
</SlideItem>
</H>
<div>
<span>{{ state.baseIndex }}</span>
<button @click="state.baseIndex++"></button>
<button @click="state.baseIndex--"></button>
</div>
<div>
<span>{{ state.navIndex }}</span>
<button @click="state.navIndex++"></button>
<button @click="state.navIndex--"></button>
</div>
<Footer v-bind:init-tab="1"/>
</SlideItem>
<SlideItem class=" gray">
<div class="big" v-for="i in 100">主页</div>
</SlideItem>
</H>
</div>
</div>
<div>
<span>{{ state.baseIndex }}</span>
<button @click="state.baseIndex++"></button>
<button @click="state.baseIndex--"></button>
</div>
<div>
<span>{{ state.navIndex }}</span>
<button @click="state.navIndex++"></button>
<button @click="state.navIndex--"></button>
</div>
<Footer v-bind:init-tab="1"/>
</SlideItem>
<SlideItem class=" gray">
<!-- <div class="big" v-for="i in 100">主页</div>-->
<Uploader
ref="uploader"
:isOnThisPage="state.baseIndex === 1"
:author="state.recommendVideos[state.itemIndex]?.author"
@toggleCanMove="e => state.canMove = e"
@back="state.baseIndex = 0"
@showFollowSetting="state.showFollowSetting = true"
@showFollowSetting2="state.showFollowSetting2 = true"
/>
</SlideItem>
</H>
<Comment page-id="slideHook" v-model="state.commentVisible"
@close="closeComments"
/>
@ -125,6 +136,39 @@ @@ -125,6 +136,39 @@
@share2Webo="state.shareType = 8"
@download="state.shareType = 9"
/>
<PlayFeedback v-model="state.showPlayFeedback"/>
<DouyinCode v-model="state.showDouyinCode"/>
<Duoshan v-model="state.showShareDuoshan"/>
<ShareTo v-model:type="state.shareType"
:videoId="state.recommendVideos[state.itemIndex]?.id"
:canDownload="state.recommendVideos[state.itemIndex]?.canDownload"
/>
<FollowSetting
@showChangeNote="delayShowDialog( e => state.showChangeNote = true)"
@showBlockDialog="delayShowDialog(e => state.showBlockDialog = true)"
@showShare="delayShowDialog( e => state.isSharing = true)"
v-model="state.showFollowSetting"/>
<FollowSetting2
@cancelFollow="$refs.uploader.cancelFollow()"
v-model="state.showFollowSetting2"/>
<BlockDialog v-model="state.showBlockDialog"/>
<ConfirmDialog
title="设置备注名"
ok-text="确认"
v-model:visible="state.showChangeNote"
>
<Search mode="light" v-model="state.test" :isShowSearchIcon="false"/>
</ConfirmDialog>
<ShareToFriend v-model="state.shareToFriend"/>
</div>
</template>
@ -137,13 +181,27 @@ import SlideUser from "../../components/slide/SlideUser"; @@ -137,13 +181,27 @@ import SlideUser from "../../components/slide/SlideUser";
import BVideo from "../../components/slide/BVideo";
import Comment from "../../components/Comment";
import Share from "../../components/Share";
import IndicatorHome from "../slide/IndicatorHome";
import IndicatorHome from "./IndicatorHome.vue";
import {computed, onMounted, onUnmounted, reactive, ref} from "vue";
import bus, {EVENT_KEY} from "../../utils/bus";
import {useNav} from "../../utils/hooks/useNav";
import {useNav} from "@/utils/hooks/useNav";
import Utils from "@/utils";
import api from "@/api";
import {useStore} from "vuex";
import PlayFeedback from "@/pages/home/components/PlayFeedback";
import FromBottomDialog from "../../components/dialog/FromBottomDialog";
import Duoshan from "@/pages/home/components/Duoshan";
import ShareTo from "@/pages/home/components/ShareTo";
import DouyinCode from "../../components/DouyinCode";
import Uploader from "../me/Uploader";
import FollowSetting from "@/pages/home/components/FollowSetting";
import BlockDialog from "../message/components/BlockDialog";
import Search from "../../components/Search";
import ConfirmDialog from "../../components/dialog/ConfirmDialog";
import FollowSetting2 from "@/pages/home/components/FollowSetting2";
import Dom from "../../utils/dom";
import ShareToFriend from "@/pages/home/components/ShareToFriend";
import resource from "@/assets/data/resource";
const nav = useNav()
@ -161,6 +219,7 @@ const state = reactive({ @@ -161,6 +219,7 @@ const state = reactive({
baseIndex: 0,
navIndex: 4,
itemIndex: 0,
test: '',
recommendVideos: [
// {
// type: 'img',
@ -205,6 +264,10 @@ const state = reactive({ @@ -205,6 +264,10 @@ const state = reactive({
})
async function getData(refresh = false) {
// if (process.env.NODE_ENV !== 'development') {
// state.totalSize = 11
// return state.recommendVideos = resource.videos
// }
if (state.loading) return
state.loading = true
let res = await api.videos.recommended({pageNo: refresh ? 0 : state.pageNo, pageSize: state.pageSize})
@ -323,6 +386,7 @@ function render(item, itemIndex, play, position) { @@ -323,6 +386,7 @@ function render(item, itemIndex, play, position) {
isPlay={false}
item={item}
position={{...position, itemIndex}}
onGoMusic={e => nav('/home/music')}
onShowShare={e => state.isSharing = true}
onGoUserInfo={e => state.baseIndex = 1}
/>
@ -402,6 +466,7 @@ function render(item, itemIndex, play, position) { @@ -402,6 +466,7 @@ function render(item, itemIndex, play, position) {
font-size: 14rem;
width: 100%;
height: 100%;
overflow: hidden;
.big {
font-weight: bold;
@ -415,7 +480,7 @@ function render(item, itemIndex, play, position) { @@ -415,7 +480,7 @@ function render(item, itemIndex, play, position) {
}
}
.h {
.first-horizontal-item {
width: 90vw;
height: 80vh;
//height: calc(100vh - @footer-height);

2
src/router/routes.js

@ -64,11 +64,9 @@ import VerificationCode from "../pages/login/VerificationCode"; @@ -64,11 +64,9 @@ import VerificationCode from "../pages/login/VerificationCode";
import RetrievePassword from "../pages/login/RetrievePassword";
import Help from "../pages/login/Help";
import Uploader from "../pages/me/Uploader";
import Slide from "../pages/slide/Slide";
const routes = [
{path: '/', redirect: '/test'},
{path: '/slide', component: Slide},
{path: '/test', component: Test},
{path: '/test4', component: Test4},
{path: '/home', component: Index2},

Loading…
Cancel
Save