Browse Source

优化

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

7
src/components/slide/BVideo.vue

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

39
src/components/slide/SlideAlbum.vue

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

9
src/pages/slide/IndicatorHome.vue

@ -131,6 +131,11 @@ export default { @@ -131,6 +131,11 @@ export default {
})
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: {
toggleType(type) {
if (type !== this.type) {
@ -158,14 +163,14 @@ export default { @@ -158,14 +163,14 @@ export default {
this.lefts.push(
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, 'left', this.lefts[this.index] + 'px')
},
move(e) {
this.$setCss(this.indicatorRef, 'transition-duration', `0ms`)
this.$setCss(this.indicatorRef, 'left',
this.lefts[this.index] +
this.lefts[this.index] -
e / (this.$store.state.bodyWidth / this.indicatorSpace) + 'px')
},
end(index) {

80
src/pages/slideHooks/VInfinite.vue

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

250
src/pages/slideHooks/index.vue

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

5
src/utils/bus.js

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

Loading…
Cancel
Save