refactor: optimize the code
This commit is contained in:
parent
b18664a3a6
commit
bdb5651a65
@ -12,6 +12,10 @@ export function recommendedVideo(params?: any, data?: any) {
|
||||
return request({ url: '/video/recommended', method: 'get', params, data })
|
||||
}
|
||||
|
||||
export function recommendedLongVideo(params?: any, data?: any) {
|
||||
return request({ url: '/video/long/recommended/', method: 'get', params, data })
|
||||
}
|
||||
|
||||
export function myVideo(params?: any, data?: any) {
|
||||
return request({ url: '/video/my', method: 'get', params, data })
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@
|
||||
<div class="num">{{ _formatNumber(comments.length) }}条评论</div>
|
||||
<div class="right">
|
||||
<Icon icon="prime:arrow-up-right-and-arrow-down-left-from-center" @click.stop="_no" />
|
||||
<Icon icon="ic:round-close" @click.stop="cancel" />
|
||||
<Icon icon="ic:round-close" v-click="cancel" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -328,10 +328,8 @@ export default {
|
||||
@import '../assets/less/index';
|
||||
|
||||
.title {
|
||||
z-index: 2;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 40rem;
|
||||
padding: 0 15rem;
|
||||
background: white;
|
||||
@ -371,15 +369,12 @@ export default {
|
||||
.comment {
|
||||
color: #000;
|
||||
width: 100%;
|
||||
height: v-bind(height);
|
||||
background: #fff;
|
||||
z-index: 5;
|
||||
border-radius: 10rem 10rem 0 0;
|
||||
|
||||
.wrapper {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-top: 40rem;
|
||||
padding-bottom: 60rem;
|
||||
}
|
||||
|
||||
@ -601,7 +596,7 @@ export default {
|
||||
}
|
||||
|
||||
.auto-input {
|
||||
width: calc(100% - 180rem);
|
||||
width: calc(100% - 160rem);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -61,5 +61,3 @@ async function getData(refresh = false) {
|
||||
|
||||
onMounted(getData)
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
:show-heng-gang="false"
|
||||
:touch-moved="false"
|
||||
maskMode="light"
|
||||
height="370rem"
|
||||
height="320rem"
|
||||
mode="dark"
|
||||
>
|
||||
<div class="share">
|
||||
@ -227,6 +227,7 @@ export default {
|
||||
|
||||
.share {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: black;
|
||||
border-radius: 10px 10px 0 0;
|
||||
color: white;
|
||||
|
||||
@ -1,20 +1,11 @@
|
||||
<template>
|
||||
<!-- <transition name="from-bottom"> -->
|
||||
<transition
|
||||
@before-enter="beforeEnter"
|
||||
@enter="enter"
|
||||
@after-enter="afterEnter"
|
||||
@before-leave="beforeLeave"
|
||||
@leave="leave"
|
||||
@after-leave="afterLeave"
|
||||
:css="false"
|
||||
>
|
||||
<!-- <transition> -->
|
||||
<Transition name="test">
|
||||
<div
|
||||
ref="dialog"
|
||||
class="FromBottomDialog"
|
||||
v-if="modelValue"
|
||||
:class="[mode, showHengGang ? '' : 'no-heng-gang']"
|
||||
:style="{ 'max-height': height }"
|
||||
@touchstart="start"
|
||||
@touchmove="move"
|
||||
@touchend="end"
|
||||
@ -23,9 +14,11 @@
|
||||
<div class="heng-gang" :class="mode" v-if="showHengGang">
|
||||
<div class="content"></div>
|
||||
</div>
|
||||
<slot></slot>
|
||||
<div class="wrapper" ref="wrapper">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</Transition>
|
||||
</template>
|
||||
<script>
|
||||
import Dom, { _css } from '../../utils/dom'
|
||||
@ -106,8 +99,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
scroll: 0,
|
||||
startLocationY: 0,
|
||||
moveYDistance: 0,
|
||||
startY: 0,
|
||||
moveY: 0,
|
||||
startTime: 0,
|
||||
pagePosition: null
|
||||
}
|
||||
@ -115,76 +108,41 @@ export default {
|
||||
computed: {},
|
||||
created() {},
|
||||
methods: {
|
||||
beforeEnter(el) {
|
||||
_css(el, 'transition-duration', `250ms`)
|
||||
_css(el, 'transform', `translate3d(0,${this.height},0)`)
|
||||
},
|
||||
enter(el, done) {
|
||||
setTimeout(() => {
|
||||
_css(el, 'transform', `translate3d(0,0,0)`)
|
||||
}, 0)
|
||||
setTimeout(() => {
|
||||
// _css(el, 'transition-duration', `0ms`)
|
||||
_css(el, 'transform', `none`)
|
||||
done()
|
||||
}, 250)
|
||||
},
|
||||
afterEnter() {},
|
||||
beforeLeave(el) {
|
||||
_css(el, 'transition-duration', `250ms`)
|
||||
_css(el, 'transform', `translate3d(0,0,0)`)
|
||||
},
|
||||
leave(el, done) {
|
||||
//ref获取不到
|
||||
let maxHeight = new Dom('.FromBottomDialog').css('max-height')
|
||||
_css(el, 'transform', `translate3d(0,${maxHeight},0)`)
|
||||
setTimeout(done, 250)
|
||||
},
|
||||
afterLeave() {},
|
||||
|
||||
hide(val = false) {
|
||||
this.$emit('update:modelValue', val)
|
||||
this.$emit('cancel')
|
||||
},
|
||||
start(e) {
|
||||
if (this.$refs.dialog.scrollTop !== 0) return
|
||||
this.startLocationY = e.touches[0].pageY
|
||||
if (this.$refs.wrapper.scrollTop !== 0) return
|
||||
this.startY = e.touches[0].pageY
|
||||
this.startTime = Date.now()
|
||||
_css(this.$refs.dialog, 'transition-duration', `0ms`)
|
||||
},
|
||||
move(e) {
|
||||
if (this.$refs.dialog.scrollTop !== 0) return
|
||||
this.moveYDistance = e.touches[0].pageY - this.startLocationY
|
||||
if (this.moveYDistance > 0) {
|
||||
if (this.$refs.wrapper.scrollTop !== 0) return
|
||||
this.moveY = e.touches[0].pageY - this.startY
|
||||
if (this.moveY > 0) {
|
||||
bus.emit(EVENT_KEY.DIALOG_MOVE, {
|
||||
tag: this.tag,
|
||||
e: this.moveYDistance
|
||||
e: this.moveY
|
||||
})
|
||||
_css(this.$refs.dialog, 'transform', `translate3d(0,${this.moveYDistance}px,0)`)
|
||||
_css(this.$refs.dialog, 'transform', `translate3d(0,${this.moveY}px,0)`)
|
||||
}
|
||||
},
|
||||
end() {
|
||||
//点击
|
||||
if (Date.now() - this.startTime < 150 && Math.abs(this.moveYDistance) < 30) {
|
||||
return
|
||||
}
|
||||
//滑动
|
||||
if (this.$refs.dialog.scrollTop !== 0) return
|
||||
//如果是外部改变modelValue值的话,这里会没有ref
|
||||
if (!this.$refs.dialog) return
|
||||
if (Date.now() - this.startTime < 150 && Math.abs(this.moveY) < 30) return
|
||||
let clientHeight = this.$refs.dialog.clientHeight
|
||||
_css(this.$refs.dialog, 'transition-duration', `250ms`)
|
||||
if (Math.abs(this.moveYDistance) > clientHeight / 2) {
|
||||
_css(this.$refs.dialog, 'transform', `translate3d(0,${clientHeight}px,0)`)
|
||||
if (Math.abs(this.moveY) > clientHeight / 2) {
|
||||
_css(this.$refs.dialog, 'transform', `translate3d(0,100%,0)`)
|
||||
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: true })
|
||||
setTimeout(this.hide, 250)
|
||||
} else {
|
||||
_css(this.$refs.dialog, 'transform', `translate3d(0,0,0)`)
|
||||
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: false })
|
||||
setTimeout(() => {
|
||||
_css(this.$refs.dialog, 'transform', 'none')
|
||||
// _css(this.$refs.dialog, 'transition-duration', `0ms`)
|
||||
}, 250)
|
||||
}
|
||||
this.moveYDistance = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -193,17 +151,31 @@ export default {
|
||||
<style scoped lang="less">
|
||||
@import '../../assets/less/index';
|
||||
|
||||
.test-enter-active,
|
||||
.test-leave-active {
|
||||
transition-duration: 250ms !important;
|
||||
}
|
||||
|
||||
.test-enter-from,
|
||||
.test-leave-to {
|
||||
transform: translate3d(0, 101%, 0) !important;
|
||||
}
|
||||
|
||||
.FromBottomDialog {
|
||||
z-index: 9;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
padding-top: 24rem;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
box-sizing: border-box;
|
||||
border-radius: v-bind(borderRadius);
|
||||
transition: all 0.3s;
|
||||
border-radius: 15rem 15rem 0 0;
|
||||
transform: translate3d(0, 0, 0);
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
height: v-bind(height);
|
||||
max-height: v-bind(height);
|
||||
flex-direction: column;
|
||||
|
||||
&.dark {
|
||||
background: var(--main-bg);
|
||||
@ -231,6 +203,7 @@ export default {
|
||||
transform: translateY(-24rem);
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
touch-action: pan-y;
|
||||
|
||||
&.dark {
|
||||
background: var(--main-bg);
|
||||
@ -262,5 +235,10 @@ export default {
|
||||
width: 30rem;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -88,7 +88,7 @@ import { Icon } from '@iconify/vue'
|
||||
import { _css } from '@/utils/dom'
|
||||
|
||||
export default {
|
||||
name: 'BVideo',
|
||||
name: 'BaseVideo',
|
||||
components: {
|
||||
Loading,
|
||||
ItemToolbar,
|
||||
@ -178,7 +178,7 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
// console.log('video', this.localItem.id)
|
||||
// console.log('video', this.localItem.aweme_id)
|
||||
// console.log(this.commentVisible)
|
||||
this.height = document.body.clientHeight
|
||||
this.width = document.body.clientWidth
|
||||
@ -200,7 +200,7 @@ export default {
|
||||
video.addEventListener(
|
||||
e,
|
||||
() => {
|
||||
// console.log('eventTester', e, this.item.id)
|
||||
// console.log('eventTester', e, this.item.aweme_id)
|
||||
if (e === 'playing') this.loading = false
|
||||
if (e === 'waiting') {
|
||||
if (!this.paused && !this.ignoreWaiting) {
|
||||
@ -285,7 +285,7 @@ export default {
|
||||
}
|
||||
},
|
||||
onOpenComments(id) {
|
||||
if (id === this.item.id) {
|
||||
if (id === this.item.aweme_id) {
|
||||
_css(this.$refs.video, 'transition-duration', `300ms`)
|
||||
_css(this.$refs.video, 'height', 'calc(var(--vh, 1vh) * 30)')
|
||||
this.commentVisible = true
|
||||
@ -306,7 +306,7 @@ export default {
|
||||
this.pause()
|
||||
bus.emit(EVENT_KEY.NAV, {
|
||||
path: '/home/live',
|
||||
query: { id: this.item.id }
|
||||
query: { id: this.item.aweme_id }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -1,8 +1,9 @@
|
||||
<script setup>
|
||||
import BaseMusic from '../BaseMusic'
|
||||
import { _dateFormat, _formatNumber, _updateItem } from '@/utils'
|
||||
<script setup lang="ts">
|
||||
import BaseMusic from '../BaseMusic.vue'
|
||||
import { _dateFormat, _formatNumber, _stopPropagation, _updateItem } from '@/utils'
|
||||
import bus, { EVENT_KEY } from '@/utils/bus'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { useClick } from '@/utils/hooks/useClick'
|
||||
|
||||
const props = defineProps({
|
||||
item: {
|
||||
@ -38,14 +39,10 @@ function attention(e) {
|
||||
}
|
||||
|
||||
function showComments() {
|
||||
console.log('showComments', _dateFormat(Date.now()))
|
||||
// emit('showComments')
|
||||
bus.emit(EVENT_KEY.OPEN_COMMENTS, props.item.id)
|
||||
bus.emit(EVENT_KEY.OPEN_COMMENTS, props.item.aweme_id)
|
||||
}
|
||||
|
||||
function s() {
|
||||
console.log('ss', _dateFormat(Date.now()))
|
||||
}
|
||||
const vClick = useClick()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -55,45 +52,45 @@ function s() {
|
||||
class="avatar"
|
||||
:src="props.item.author.avatar_168x168.url_list[0]"
|
||||
alt=""
|
||||
@pointerup="bus.emit(EVENT_KEY.GO_USERINFO)"
|
||||
v-click="() => bus.emit(EVENT_KEY.GO_USERINFO)"
|
||||
/>
|
||||
<transition name="fade">
|
||||
<div v-if="!props.item.isAttention" @pointerup="attention" class="options">
|
||||
<div v-if="!props.item.isAttention" v-click="attention" class="options">
|
||||
<img class="no" src="../../assets/img/icon/add-light.png" alt="" />
|
||||
<img class="yes" src="../../assets/img/icon/ok-red.png" alt="" />
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="love mb2r" @pointerup="loved($event)">
|
||||
<div class="love mb2r" v-click="loved">
|
||||
<div>
|
||||
<img src="../../assets/img/icon/love.svg" class="love-image" v-if="!props.item.isLoved" />
|
||||
<img src="../../assets/img/icon/loved.svg" class="love-image" v-if="props.item.isLoved" />
|
||||
</div>
|
||||
<span>{{ _formatNumber(props.item.statistics.digg_count) }}</span>
|
||||
</div>
|
||||
<div class="message mb2r" @pointerup="showComments">
|
||||
<div class="message mb2r" v-click="showComments">
|
||||
<Icon icon="mage:message-dots-round-fill" class="icon" style="color: white" />
|
||||
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span>
|
||||
</div>
|
||||
<!--TODO -->
|
||||
<div
|
||||
class="message mb2r"
|
||||
@pointerup="_updateItem(props, 'isCollect', !props.item.isCollect, emit)"
|
||||
v-click="() => _updateItem(props, 'isCollect', !props.item.isCollect, emit)"
|
||||
>
|
||||
<Icon v-if="props.item.isCollect" icon="ic:round-star" class="icon" style="color: yellow" />
|
||||
<Icon v-else icon="ic:round-star" class="icon" style="color: white" />
|
||||
<span>{{ _formatNumber(props.item.statistics.comment_count) }}</span>
|
||||
</div>
|
||||
<div v-if="!props.isMy" class="share mb2r" @pointerup="bus.emit(EVENT_KEY.SHOW_SHARE)">
|
||||
<div v-if="!props.isMy" class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)">
|
||||
<img src="../../assets/img/icon/share-white-full.png" alt="" class="share-image" />
|
||||
<span>{{ _formatNumber(props.item.statistics.share_count) }}</span>
|
||||
</div>
|
||||
<div v-else class="share mb2r" @pointerup="bus.emit(EVENT_KEY.SHOW_SHARE)">
|
||||
<div v-else class="share mb2r" v-click="() => bus.emit(EVENT_KEY.SHOW_SHARE)">
|
||||
<img src="../../assets/img/icon/menu-white.png" alt="" class="share-image" />
|
||||
</div>
|
||||
<!-- <BaseMusic-->
|
||||
<!-- :cover="props.item.music.cover"-->
|
||||
<!-- @pointerup="$nav('/home/music')"-->
|
||||
<!-- v-click="$nav('/home/music')"-->
|
||||
<!-- /> -->
|
||||
<BaseMusic :item="props.item" />
|
||||
</div>
|
||||
|
||||
@ -335,7 +335,6 @@ function canNext(state, isNext) {
|
||||
<div
|
||||
class="slide-list flex-direction-column"
|
||||
ref="slideListEl"
|
||||
@click="null"
|
||||
@pointerdown.prevent="touchStart"
|
||||
@pointermove.prevent="touchMove"
|
||||
@pointerup.prevent="touchEnd"
|
||||
|
||||
11
src/main.ts
11
src/main.ts
@ -7,20 +7,21 @@ import router from './router'
|
||||
import mixin from './utils/mixin'
|
||||
import VueLazyload from '@jambonn/vue-lazyload'
|
||||
import { createPinia } from 'pinia'
|
||||
import { useClick } from '@/utils/hooks/useClick'
|
||||
|
||||
window.isMoved = false
|
||||
HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEventListener, {
|
||||
apply(target, ctx, args) {
|
||||
const eventName = args[0]
|
||||
const listener = args[1]
|
||||
// console.log('e', eventName, '')
|
||||
if (listener instanceof Function && eventName === 'click') {
|
||||
args[1] = new Proxy(listener, {
|
||||
apply(target, ctx, args) {
|
||||
console.log('点击', window.isMoved)
|
||||
apply(target1, ctx1, args1) {
|
||||
// console.log('e', args1)
|
||||
// console.log('click点击', window.isMoved)
|
||||
if (window.isMoved) return
|
||||
try {
|
||||
return target.apply(ctx, args)
|
||||
return target1.apply(ctx1, args1)
|
||||
} catch (e) {
|
||||
console.error(`[proxyPlayerEvent][${eventName}]`, listener, e)
|
||||
}
|
||||
@ -31,6 +32,7 @@ HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEven
|
||||
}
|
||||
})
|
||||
|
||||
const vClick = useClick()
|
||||
const pinia = createPinia()
|
||||
const emitter = mitt()
|
||||
const app = createApp(App)
|
||||
@ -46,6 +48,7 @@ app.use(VueLazyload, {
|
||||
app.use(pinia)
|
||||
app.use(router)
|
||||
app.mount('#app')
|
||||
app.directive('click', vClick)
|
||||
|
||||
//放到最后才可以使用pinia
|
||||
startMock()
|
||||
|
||||
@ -148,6 +148,20 @@ export async function startMock() {
|
||||
}
|
||||
]
|
||||
})
|
||||
mock.onGet(/video\/long\/recommended/).reply(async (config) => {
|
||||
const page = getPage2(config.params)
|
||||
return [
|
||||
200,
|
||||
{
|
||||
data: {
|
||||
total: 844,
|
||||
list: allRecommendVideos.slice(page.offset, page.limit)
|
||||
},
|
||||
code: 200,
|
||||
msg: ''
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
mock.onGet(/video\/comments/).reply(async (config) => {
|
||||
const videoIds = [
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { _checkImgUrl, _duration, _formatNumber, _stopPropagation } from '@/utils'
|
||||
import { recommendedVideo } from '@/api/videos'
|
||||
import { recommendedLongVideo, recommendedVideo } from '@/api/videos'
|
||||
import ScrollList from '@/components/ScrollList.vue'
|
||||
import { useNav } from '@/utils/hooks/useNav'
|
||||
|
||||
@ -79,7 +79,7 @@ const nav = useNav()
|
||||
|
||||
<template>
|
||||
<div class="long-video" @dragstart="(e) => _stopPropagation(e)">
|
||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedVideo">
|
||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedLongVideo">
|
||||
<template v-slot="{ list }">
|
||||
<div class="list">
|
||||
<div
|
||||
|
||||
@ -492,6 +492,9 @@ export default {
|
||||
_getUserDouyinId,
|
||||
_checkImgUrl,
|
||||
_formatNumber,
|
||||
$nav(path) {
|
||||
this.$router.push(path)
|
||||
},
|
||||
setLoadingFalse() {
|
||||
this.loadings.loading0 = false
|
||||
this.loadings.loading1 = false
|
||||
|
||||
@ -310,7 +310,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<div class="btn-wrapper">
|
||||
<div class="btn" :class="selectFriends ? 'primary' : ''">发起聊天</div>
|
||||
<div class="btn primary">发起群聊{{ selectFriends ? `(${selectFriends})` : '' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="joined-chat-wrapper" v-show="data.showJoinedChat">
|
||||
@ -615,21 +615,17 @@ async function loadRecommendData() {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 20rem;
|
||||
|
||||
.btn {
|
||||
margin-bottom: 20rem;
|
||||
width: calc(100% - 40rem);
|
||||
height: 40rem;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 14rem;
|
||||
justify-content: center;
|
||||
background: #3f445c;
|
||||
border-radius: 2rem;
|
||||
|
||||
&.primary {
|
||||
background: var(--primary-btn-color);
|
||||
}
|
||||
border-radius: 10rem;
|
||||
background: var(--primary-btn-color);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,53 +1,18 @@
|
||||
<template>
|
||||
<div class="body">
|
||||
test
|
||||
<canvas ref="canvasEl"></canvas>
|
||||
<!-- <video ref="videoEl" :src="v1" controls></video>-->
|
||||
<Slide4 :active="state.navIndex === 4 && state.baseIndex === 1" />
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { onMounted, ref } from 'vue'
|
||||
import { reactive } from 'vue'
|
||||
import Slide4 from '@/pages/home/slide/Slide4.vue'
|
||||
|
||||
defineOptions({
|
||||
name: 'Test'
|
||||
})
|
||||
const canvasEl = ref()
|
||||
const videoEl = ref()
|
||||
onMounted(() => {
|
||||
console.log(canvasEl.value, videoEl.value)
|
||||
let ctx = canvasEl.value.getContext('2d')
|
||||
videoEl.value.addEventListener('play', () => {
|
||||
console.log(videoEl.value.videoWidth)
|
||||
console.log(videoEl.value.videoHeight)
|
||||
// ctx.drawImage(videoEl.value, 0, 0, videoEl.value.videoWidth / 20, videoEl.value.videoHeight / 20);
|
||||
ctx.drawImage(videoEl.value, 0, 0, videoEl.value.naturalWidth, videoEl.value.naturalHeight)
|
||||
// ctx.drawImage(videoEl.value, 0, 0, 500, 500);
|
||||
})
|
||||
const state = reactive({
|
||||
navIndex: 4,
|
||||
baseIndex: 1
|
||||
})
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.body {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
height: calc(var(--vh, 1vh) * 100);
|
||||
width: 100vw;
|
||||
overflow: hidden;
|
||||
transform-origin: 0 0;
|
||||
color: white;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
video,
|
||||
canvas {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
background: black;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
<style scoped lang="less"></style>
|
||||
|
||||
@ -34,7 +34,7 @@ export default {
|
||||
this.eventMap = new Map()
|
||||
},
|
||||
emit(eventType, val?) {
|
||||
console.log('emit', eventType, val)
|
||||
// console.log('emit', eventType, val)
|
||||
const cbs = this.eventMap.get(eventType)
|
||||
if (cbs) {
|
||||
cbs.map((cb) => cb(val))
|
||||
|
||||
18
src/utils/hooks/useClick.ts
Normal file
18
src/utils/hooks/useClick.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import { _stopPropagation } from '@/utils'
|
||||
|
||||
//解决SlideVerticalInfinite组件,每次滑动之后,click事件总是要等到2秒之后点击会发触发的bug
|
||||
//具体原因未知
|
||||
export function useClick() {
|
||||
return {
|
||||
mounted: function (el: HTMLElement, binding: any) {
|
||||
el.addEventListener('pointerdown', (e) => _stopPropagation(e))
|
||||
el.addEventListener('pointerup', (e) => {
|
||||
_stopPropagation(e)
|
||||
binding.value?.()
|
||||
})
|
||||
},
|
||||
unmounted(el: HTMLDivElement) {
|
||||
el = null
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@ import BaseButton from '../components/BaseButton.vue'
|
||||
import CONST_VAR from './const_var'
|
||||
import Dom from './dom'
|
||||
import bus, { EVENT_KEY } from './bus'
|
||||
import { random } from '@/utils'
|
||||
import { _stopPropagation, random } from '@/utils'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import SlideHorizontal from '@/components/slide/SlideHorizontal.vue'
|
||||
|
||||
@ -104,11 +104,13 @@ export default {
|
||||
}
|
||||
},
|
||||
love: {
|
||||
beforeMount: function (el: HTMLDivElement, binding) {
|
||||
mounted: function (el: HTMLDivElement, binding) {
|
||||
let isDbClick = false
|
||||
let clickTimer = null
|
||||
let dbClickTimer = null
|
||||
let lastClickTime = null
|
||||
let isDown = false
|
||||
let isMove = false
|
||||
const checkTime = 200
|
||||
const dbCheckCancelTime = 500
|
||||
|
||||
@ -141,13 +143,22 @@ export default {
|
||||
dbClickTimer = setTimeout(() => (isDbClick = false), dbCheckCancelTime)
|
||||
} else {
|
||||
clickTimer = setTimeout(() => {
|
||||
console.log('单击', binding.value)
|
||||
// console.log('单击', binding.value)
|
||||
bus.emit(EVENT_KEY.SINGLE_CLICK, binding.value)
|
||||
}, checkTime)
|
||||
}
|
||||
lastClickTime = nowTime
|
||||
}
|
||||
el.addEventListener('click', check)
|
||||
|
||||
const up = (e) => {
|
||||
if (!isDown) return
|
||||
if (!isMove) check(e)
|
||||
isMove = isDown = false
|
||||
}
|
||||
|
||||
el.addEventListener('pointerdown', () => (isDown = true))
|
||||
el.addEventListener('pointermove', () => isDown && (isMove = true))
|
||||
el.addEventListener('pointerup', up)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ function canNext(state, isNext) {
|
||||
* @param state
|
||||
*/
|
||||
export function slideTouchStart(e, el, state) {
|
||||
// console.log('e', e, state.name)
|
||||
// console.log('start', state.name)
|
||||
if (!checkEvent(e)) return
|
||||
_css(el, 'transition-duration', `0ms`)
|
||||
//记录起点坐标,用于move事件计算移动距离
|
||||
@ -107,9 +107,9 @@ export function slideTouchMove(
|
||||
notNextCb = null,
|
||||
slideOtherDirectionCb = null
|
||||
) {
|
||||
console.log('move', state.name)
|
||||
if (!checkEvent(e)) return
|
||||
if (!state.isDown) return
|
||||
// console.log('move', state.name)
|
||||
|
||||
//计算移动距离
|
||||
state.move.x = e.touches[0].pageX - state.start.x
|
||||
@ -174,15 +174,15 @@ export function slideTouchMove(
|
||||
export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNextCb = null) {
|
||||
if (!checkEvent(e)) return
|
||||
if (!state.isDown) return
|
||||
|
||||
const isHorizontal = state.type === SlideType.HORIZONTAL
|
||||
const isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
||||
// console.log('end', state.name)
|
||||
|
||||
if (state.next) {
|
||||
const isHorizontal = state.type === SlideType.HORIZONTAL
|
||||
const isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
||||
//同move事件
|
||||
if (!canNextCb) canNextCb = canNext
|
||||
if (canNextCb(state, isNext)) {
|
||||
//能滑动,那就把事件捕获,不能给父组件处理
|
||||
//2024-04-25:换成pointer事件之后不能捕获了,需要让父组件重置自己的isDown,不然PC上move事件会一直触发
|
||||
// _stopPropagation(e)
|
||||
|
||||
//结合时间、距离来判断是否成功滑动
|
||||
|
||||
Loading…
Reference in New Issue
Block a user