Browse Source

优化

pull/29/head
zyronon 3 years ago
parent
commit
e0990c78e3
  1. 7
      src/components/slide/BVideo.vue
  2. 37
      src/components/slide/SlideAlbum.vue
  3. 9
      src/pages/slide/IndicatorHome.vue
  4. 78
      src/pages/slideHooks/VInfinite.vue
  5. 62
      src/pages/slideHooks/index.vue
  6. 5
      src/utils/bus.js

7
src/components/slide/BVideo.vue

@ -222,7 +222,7 @@ export default {
// eventTester("durationchange", ''); // // eventTester("durationchange", ''); //
// eventTester("volumechange", ''); // // eventTester("volumechange", ''); //
console.log('mounted') // console.log('mounted')
// bus.off('singleClickBroadcast') // bus.off('singleClickBroadcast')
bus.on(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click) bus.on(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click)
bus.on(EVENT_KEY.DIALOG_MOVE, this.onDialogMove) bus.on(EVENT_KEY.DIALOG_MOVE, this.onDialogMove)
@ -233,13 +233,14 @@ export default {
bus.on(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType) bus.on(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType)
}, },
unmounted() { unmounted() {
console.log('unmounted') // console.log('unmounted')
bus.off(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click) bus.off(EVENT_KEY.SINGLE_CLICK_BROADCAST, this.click)
bus.off(EVENT_KEY.DIALOG_MOVE, this.onDialogMove) bus.off(EVENT_KEY.DIALOG_MOVE, this.onDialogMove)
bus.off(EVENT_KEY.DIALOG_END, this.onDialogEnd) bus.off(EVENT_KEY.DIALOG_END, this.onDialogEnd)
bus.off(EVENT_KEY.OPEN_COMMENTS, this.onOpenComments) bus.off(EVENT_KEY.OPEN_COMMENTS, this.onOpenComments)
bus.off(EVENT_KEY.CLOSE_COMMENTS, this.onCloseComments) bus.off(EVENT_KEY.CLOSE_COMMENTS, this.onCloseComments)
bus.off(EVENT_KEY.OPEN_SUB_TYPE, this.onCloseSubType) bus.off(EVENT_KEY.OPEN_SUB_TYPE, this.onOpenSubType)
bus.off(EVENT_KEY.CLOSE_SUB_TYPE, this.onCloseSubType)
}, },
methods: { methods: {
onOpenSubType({index, height}) { onOpenSubType({index, height}) {

37
src/components/slide/SlideAlbum.vue

@ -6,21 +6,20 @@
@touchstart.passive="touchStart" @touchstart.passive="touchStart"
@touchmove="touchMove" @touchmove="touchMove"
@touchend="touchEnd"> @touchend="touchEnd">
<div class="img-slide-item" v-for="img in props.modelValue.imgs"> <div class="img-slide-item" v-for="img in props.item.imgs">
<img :ref="e=>setItemRef(e,'itemRefs')" <img :ref="e=>setItemRef(e,'itemRefs')"
:src="img"> :src="img">
</div> </div>
</div> </div>
</div> </div>
<template v-if=" state.operationStatus === SlideAlbumOperationStatus.Normal"> <template v-if=" state.operationStatus === SlideAlbumOperationStatus.Normal">
<ItemToolbar :item="props.modelValue" <ItemToolbar v-model:item="state.localItem"
:index="0" :position="position"
prefix="sadfa" v-bind="$attrs"
/> />
<ItemDesc <ItemDesc
:item="props.modelValue" v-model:item="state.localItem"
:index="0" :position="position"
prefix="sadfa"
/> />
</template> </template>
<!--不知为啥touch事件在下部20px的空间内不触发加上click事件不好了 --> <!--不知为啥touch事件在下部20px的空间内不触发加上click事件不好了 -->
@ -31,7 +30,7 @@
@touchmove="progressBarTouchMove" @touchmove="progressBarTouchMove"
@touchend="progressBarTouchMEnd" @touchend="progressBarTouchMEnd"
> >
<div class="bar" v-for="(img,index) in modelValue.imgs"> <div class="bar" v-for="(img,index) in item.imgs">
<div class="progress" <div class="progress"
:style="getProgressWidth(index)"></div> :style="getProgressWidth(index)"></div>
</div> </div>
@ -41,12 +40,12 @@
<div class="preview-wrapper"> <div class="preview-wrapper">
<img :src="img" <img :src="img"
:class="{'preview-img':index === state.localIndex}" :class="{'preview-img':index === state.localIndex}"
v-for="(img,index) in props.modelValue.imgs" v-for="(img,index) in props.item.imgs"
:ref="e=>setItemRef(e,'previewImgs')" :ref="e=>setItemRef(e,'previewImgs')"
> >
</div> </div>
<div class="indicator"> <div class="indicator">
<span class="index">{{ state.localIndex + 1 }}</span>&nbsp;/&nbsp;{{ props.modelValue.imgs.length }} <span class="index">{{ state.localIndex + 1 }}</span>&nbsp;/&nbsp;{{ props.item.imgs.length }}
</div> </div>
</div> </div>
</Teleport> </Teleport>
@ -67,7 +66,7 @@
import enums from "../../utils/enums"; import enums from "../../utils/enums";
import Utils from '../../utils' import Utils from '../../utils'
import {mat4} from 'gl-matrix' import {mat4} from 'gl-matrix'
import {onMounted, onBeforeUpdate, reactive, ref, watch, computed} from "vue"; import {onMounted, onBeforeUpdate, reactive, ref, watch, computed, provide} from "vue";
import { import {
getSlideDistance, getSlideDistance,
slideInit, slideInit,
@ -97,8 +96,11 @@ let ov = new Float32Array([
]); ]);
let origin = cloneDeep(ov) let origin = cloneDeep(ov)
const rectMap = new Map() const rectMap = new Map()
// provide('isPlaying', computed(() => this.isPlaying))
provide('isPlaying', false)
const props = defineProps({ const props = defineProps({
modelValue: { item: {
type: Object, type: Object,
default() { default() {
return { return {
@ -197,7 +199,13 @@ const props = defineProps({
} }
} }
} }
},
position: {
type: Object,
default: () => {
return {}
} }
},
}) })
const judgeValue = 20 const judgeValue = 20
const wrapperEl = ref(null) const wrapperEl = ref(null)
@ -228,6 +236,7 @@ const state = reactive({
status: 'play',//stop,custom status: 'play',//stop,custom
progress: 0, progress: 0,
cycleFn: null, cycleFn: null,
localItem: props.item,
}) })
onMounted(() => { onMounted(() => {
@ -236,7 +245,7 @@ onMounted(() => {
state.cycleFn = () => { state.cycleFn = () => {
return return
if (state.status !== 'play') return cancelAnimationFrame(state.cycleFn) if (state.status !== 'play') return cancelAnimationFrame(state.cycleFn)
if (state.progress < props.modelValue.imgs.length * 100) { if (state.progress < props.item.imgs.length * 100) {
state.progress += .4 state.progress += .4
state.localIndex = parseInt(state.progress / 100) state.localIndex = parseInt(state.progress / 100)
if (wrapperEl.value) { if (wrapperEl.value) {
@ -455,7 +464,7 @@ function setItemRef(el, key) {
} }
function canNext(isNext, e) { function canNext(isNext, e) {
let res = !((state.localIndex === 0 && !isNext) || (state.localIndex === props.modelValue.imgs.length - 1 && isNext)); let res = !((state.localIndex === 0 && !isNext) || (state.localIndex === props.item.imgs.length - 1 && isNext));
if (!res && state.operationStatus === SlideAlbumOperationStatus.Detail && e) { if (!res && state.operationStatus === SlideAlbumOperationStatus.Detail && e) {
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
} }

9
src/pages/slide/IndicatorHome.vue

@ -131,6 +131,11 @@ export default {
}) })
bus.on(this.name + '-end', this.end) bus.on(this.name + '-end', this.end)
}, },
unmounted() {
bus.off(this.name + '-moveX', this.move)
bus.off(this.name + '-moveY',)
bus.off(this.name + '-end', this.end)
},
methods: { methods: {
toggleType(type) { toggleType(type) {
if (type !== this.type) { if (type !== this.type) {
@ -158,14 +163,14 @@ export default {
this.lefts.push( this.lefts.push(
item.getBoundingClientRect().x - tabs.children[0].getBoundingClientRect().x + (tabWidth * 0.5 - indicatorWidth / 2)) item.getBoundingClientRect().x - tabs.children[0].getBoundingClientRect().x + (tabWidth * 0.5 - indicatorWidth / 2))
} }
this.indicatorSpace = this.lefts[1] - this.lefts[this.index] this.indicatorSpace = this.lefts[1] - this.lefts[0]
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[this.index] + 'px')
}, },
move(e) { move(e) {
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`) 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 / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px') e / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
}, },
end(index) { end(index) {

78
src/pages/slideHooks/VInfinite.vue

@ -6,6 +6,7 @@ import {SlideType} from "../../utils/const_var";
import SlideItem from './SlideItem' import SlideItem from './SlideItem'
import bus from "../../utils/bus"; import bus from "../../utils/bus";
import {useStore} from 'vuex' import {useStore} from 'vuex'
import Utils from "../../utils";
const props = defineProps({ const props = defineProps({
index: { index: {
@ -41,10 +42,10 @@ const props = defineProps({
default: () => '' default: () => ''
}, },
}) })
const emit = defineEmits(['update:index']) const emit = defineEmits(['update:index', 'loadMore'])
const appInsMap = new Map() const appInsMap = new Map()
const slideItemClassName = 'slide-item2' const itemClassName = 'slide-item2'
const wrapperEl = ref(null) const wrapperEl = ref(null)
const state = reactive({ const state = reactive({
name: props.name, name: props.name,
@ -60,14 +61,33 @@ const homeRefresh = computed(() => store.state.homeRefresh)
const judgeValue = computed(() => store.state.judgeValue) const judgeValue = computed(() => store.state.judgeValue)
watch( watch(
() => props.index, () => props.list,
(newVal) => { (newVal, oldVal) => {
if (state.localIndex !== newVal) { // console.log('watch', newVal.length, oldVal.length, props.list)
state.localIndex = newVal //
GM.$setCss(wrapperEl.value, 'transition-duration', `300ms`) if (newVal.length <= oldVal.length) {
GM.$setCss(wrapperEl.value, 'transform', `translate3d(0,${getSlideDistance(state, SlideType.VERTICAL)}px, 0)`) insertContent()
} else {
if (oldVal.length === 0) {
insertContent()
} else {
let end = oldVal.length + 3
if (end >= newVal) end = newVal
let top = $(wrapperEl.value).find(`.${itemClassName}:last`).css('top')
newVal.slice(oldVal.length, end).map((item, index) => {
let el = getInsEl(item, oldVal.length + index)
//top
//2022-3-27slide-itemtop
//top
// top
$(el).css('top', top)
wrapperEl.value.appendChild(el)
state.wrapper.childrenLength++
})
} }
} }
},
) )
onMounted(() => { onMounted(() => {
@ -77,15 +97,16 @@ onMounted(() => {
//使this.list,vuevideosthis.list //使this.list,vuevideosthis.list
function insertContent(list = props.list) { function insertContent(list = props.list) {
$(wrapperEl.value).empty()
let half = (props.virtualTotal - 1) / 2
let start = 0 let start = 0
if (state.localIndex >= half) {
if (state.localIndex >= (props.virtualTotal - 1) / 2) { start = state.localIndex - half
start = state.localIndex - (props.virtualTotal - 1) / 2
} }
let end = start + 5 let end = start + props.virtualTotal
if (end >= list.length) { if (end >= list.length) {
end = list.length end = list.length
start = end - 5 start = end - props.virtualTotal
} }
if (start < 0) start = 0 if (start < 0) start = 0
list.slice(start, end).map( list.slice(start, end).map(
@ -95,11 +116,10 @@ function insertContent(list = props.list) {
wrapperEl.value.appendChild(el) wrapperEl.value.appendChild(el)
} }
) )
GM.$setCss(wrapperEl.value, 'transform', `translate3d(0px, GM.$setCss(wrapperEl.value, 'transform', `translate3d(0px,${getSlideDistance(state, SlideType.VERTICAL)}px, 0px)`)
${-state.localIndex * state.wrapper.height}px, 0px)`)
if (state.localIndex > 2 && list.length > 5) { if (state.localIndex > 2 && list.length > 5) {
$(wrapperEl.value).find(`.${slideItemClassName}`).each(function () { $(wrapperEl.value).find(`.${itemClassName}`).each(function () {
if ((list.length - state.localIndex) > 2) { if ((list.length - state.localIndex) > 2) {
$(this).css('top', (state.localIndex - 2) * state.wrapper.height) $(this).css('top', (state.localIndex - 2) * state.wrapper.height)
} else { } else {
@ -125,7 +145,6 @@ function getInsEl(item, index, play = false) {
return ins.$el return ins.$el
} }
function touchStart(e) { function touchStart(e) {
slideTouchStart(e, wrapperEl.value, state) slideTouchStart(e, wrapperEl.value, state)
} }
@ -137,13 +156,16 @@ function touchMove(e) {
function touchEnd(e) { function touchEnd(e) {
let isNext = state.move.y < 0 let isNext = state.move.y < 0
if (state.localIndex === 0 && !isNext && state.move.y > (homeRefresh.value + judgeValue.value)) { if (state.localIndex === 0 && !isNext && state.move.y > (homeRefresh.value + judgeValue.value)) {
console.log('loading') emit('refresh')
// bus.emit(props.prefix + '-loading')
} }
slideTouchEnd(e, state, canNext, (isNext) => { slideTouchEnd(e, state, canNext, (isNext) => {
if (isNext) { if (isNext) {
let half = (props.virtualTotal + 1) / 2
if (state.localIndex > props.list.length - props.virtualTotal && state.localIndex >= half) {
emit('loadMore')
}
let addItemIndex = state.localIndex + 2 let addItemIndex = state.localIndex + 2
let res = $(wrapperEl.value).find(`.${slideItemClassName}[data-index=${addItemIndex}]`) let res = $(wrapperEl.value).find(`.${itemClassName}[data-index=${addItemIndex}]`)
if (state.wrapper.childrenLength < props.virtualTotal) { if (state.wrapper.childrenLength < props.virtualTotal) {
if (res.length === 0) { if (res.length === 0) {
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex)) wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
@ -155,15 +177,15 @@ function touchEnd(e) {
) { ) {
if (res.length === 0) { if (res.length === 0) {
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex)) wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
appInsMap.get($(wrapperEl.value).find(`.${slideItemClassName}:first`).data('index')).unmount() appInsMap.get($(wrapperEl.value).find(`.${itemClassName}:first`).data('index')).unmount()
// $(wrapperEl.value).find(".base-slide-item:first").remove() // $(wrapperEl.value).find(".base-slide-item:first").remove()
$(wrapperEl.value).find(`.${slideItemClassName}`).each(function () { $(wrapperEl.value).find(`.${itemClassName}`).each(function () {
$(this).css('top', (state.localIndex - 2) * state.wrapper.height) $(this).css('top', (state.localIndex - 2) * state.wrapper.height)
}) })
} }
} }
if (state.wrapper.childrenLength > props.virtualTotal) { if (state.wrapper.childrenLength > props.virtualTotal) {
$(wrapperEl.value).find(`.${slideItemClassName}`).each(function () { $(wrapperEl.value).find(`.${itemClassName}`).each(function () {
let index = $(this).data('index') let index = $(this).data('index')
if (index < (state.localIndex - 2)) { if (index < (state.localIndex - 2)) {
appInsMap.get(index).unmount() appInsMap.get(index).unmount()
@ -173,21 +195,21 @@ function touchEnd(e) {
} }
} else { } else {
let addItemIndex = state.localIndex - 2 let addItemIndex = state.localIndex - 2
let res = $(wrapperEl.value).find(`.${slideItemClassName}[data-index=${addItemIndex}]`) let res = $(wrapperEl.value).find(`.${itemClassName}[data-index=${addItemIndex}]`)
if (state.localIndex > 1 && state.localIndex <= props.list.length - 4) { if (state.localIndex > 1 && state.localIndex <= props.list.length - 4) {
if (res.length === 0) { if (res.length === 0) {
wrapperEl.value.prepend(getInsEl(props.list[addItemIndex], addItemIndex)) wrapperEl.value.prepend(getInsEl(props.list[addItemIndex], addItemIndex))
appInsMap.get($(wrapperEl.value).find(`.${slideItemClassName}:last`).data('index')).unmount() appInsMap.get($(wrapperEl.value).find(`.${itemClassName}:last`).data('index')).unmount()
// $(wrapperEl.value).find(".base-slide-item:last").remove() // $(wrapperEl.value).find(".base-slide-item:last").remove()
$(wrapperEl.value).find(`.${slideItemClassName}`).each(function () { $(wrapperEl.value).find(`.${itemClassName}`).each(function () {
$(this).css('top', (state.localIndex - 2) * state.wrapper.height) $(this).css('top', (state.localIndex - 2) * state.wrapper.height)
}) })
} }
} }
if (state.wrapper.childrenLength > props.virtualTotal) { if (state.wrapper.childrenLength > props.virtualTotal) {
appInsMap.get($(wrapperEl.value).find(`.${slideItemClassName}:last`).data('index')).unmount() appInsMap.get($(wrapperEl.value).find(`.${itemClassName}:last`).data('index')).unmount()
} }
} }
@ -198,7 +220,7 @@ function touchEnd(e) {
function canNext(isNext) { function canNext(isNext) {
return !((state.localIndex === 0 && !isNext) || (state.localIndex === state.wrapper.childrenLength - 1 && isNext)); return !((state.localIndex === 0 && !isNext) || (state.localIndex === props.list.length - 1 && isNext));
} }
</script> </script>

62
src/pages/slideHooks/index.vue

@ -1,9 +1,5 @@
<template> <template>
<div class="test-slide-wrapper" id="slideHook" <div class="test-slide-wrapper">
@click="pageClick"
v-love="'slideHook'">
<H v-model:index="state.baseIndex">
<SlideItem>
<IndicatorHome <IndicatorHome
v-if="!state.fullScreen" v-if="!state.fullScreen"
v-hide="state.isUp" v-hide="state.isUp"
@ -55,6 +51,11 @@
v-if="state.subType===-1" v-if="state.subType===-1"
@click="showSubType">附近吃喝玩乐 @click="showSubType">附近吃喝玩乐
</div> </div>
<div class="slide-content" id="slideHook"
@touchstart="pageClick"
v-love="'slideHook'">
<H v-model:index="state.baseIndex">
<SlideItem>
<H class="h" <H class="h"
name="main" name="main"
v-model:index="state.navIndex"> v-model:index="state.navIndex">
@ -80,6 +81,8 @@
baseIndex:0, baseIndex:0,
navIndex:5, navIndex:5,
}" }"
@loadMore="loadMore"
@refresh="refresh"
> >
</VInfinite> </VInfinite>
</SlideItem> </SlideItem>
@ -104,6 +107,7 @@
<Comment page-id="slideHook" v-model="state.commentVisible" <Comment page-id="slideHook" v-model="state.commentVisible"
@close="closeComments" @close="closeComments"
/> />
</div>
</template> </template>
<script setup lang="jsx"> <script setup lang="jsx">
@ -120,10 +124,11 @@ import {onMounted, onUnmounted, provide, reactive, ref} from "vue";
import bus, {EVENT_KEY} from "../../utils/bus"; import bus, {EVENT_KEY} from "../../utils/bus";
import {useNav} from "../../utils/hooks/useNav"; import {useNav} from "../../utils/hooks/useNav";
import Utils from "@/utils"; import Utils from "@/utils";
import {shuffle} from "lodash";
const nav = useNav() const nav = useNav()
const videos = resource.videos.slice(0, 16).map(v => { const videos = resource.videos.slice().map(v => {
v.type = 'recommend-video' v.type = 'recommend-video'
return v return v
}) })
@ -132,7 +137,6 @@ function stop(e) {
e.stopPropagation() e.stopPropagation()
} }
const subTypeRef = ref(null) const subTypeRef = ref(null)
const state = reactive({ const state = reactive({
baseIndex: 0, baseIndex: 0,
@ -143,11 +147,11 @@ const state = reactive({
// type: 'img', // type: 'img',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` // src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// }, // },
// { {
// type: 'imgs', type: 'imgs',
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
// }, },
...videos // ...videos
], ],
isSharing: false, isSharing: false,
@ -175,6 +179,32 @@ const state = reactive({
subTypeIsTop: false, subTypeIsTop: false,
}) })
function loadMore() {
if (state.loading) return
state.loading = true
console.log('loadMore')
setTimeout(() => {
state.recommendVideos = state.recommendVideos.concat(shuffle(resource.videos).slice(0, 10).map(v => {
v.type = 'recommend-video'
return v
}))
state.loading = false
}, 500)
}
function refresh() {
if (state.loading) return
state.loading = true
console.log('refresh')
setTimeout(() => {
state.recommendVideos = shuffle(resource.videos).slice(0, 5).map(v => {
v.type = 'recommend-video'
return v
})
state.loading = false
}, 500)
}
function showSubType(e) { function showSubType(e) {
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
console.log('subTypeRef',) console.log('subTypeRef',)
@ -189,6 +219,7 @@ function showSubType(e) {
} }
function pageClick(e) { function pageClick(e) {
// console.log('pageClick')
if (state.subType !== -1) { if (state.subType !== -1) {
state.subType = -1 state.subType = -1
state.subTypeIsTop = false state.subTypeIsTop = false
@ -233,6 +264,7 @@ function closeComments() {
} }
function render(item, itemIndex, play, position) { function render(item, itemIndex, play, position) {
console.log(item)
let node let node
if (item.type === 'img') { if (item.type === 'img') {
node = <img src={item.src} style="height:100%;"/> node = <img src={item.src} style="height:100%;"/>
@ -358,6 +390,12 @@ function render(item, itemIndex, play, position) {
font-weight: bold; font-weight: bold;
font-size: 100rem; font-size: 100rem;
} }
.slide-content {
width: 100%;
height: 100%;
}
} }
.h { .h {

5
src/utils/bus.js

@ -8,10 +8,13 @@ export default {
cbs = [cb] cbs = [cb]
} }
if (cbs.length > 10) { if (cbs.length > 10) {
console.error('eventMap', this.eventMap) // console.error('eventMap', this.eventMap)
} }
this.eventMap.set(eventType, cbs) this.eventMap.set(eventType, cbs)
}, },
once(eventType, cb) {
this.eventMap.set(eventType, [cb])
},
off(eventType, fn) { off(eventType, fn) {
let cbs = this.eventMap.has(eventType); let cbs = this.eventMap.has(eventType);
if (cbs) { if (cbs) {

Loading…
Cancel
Save