vue3视频上划下划

58 阅读4分钟
<template>
    <div>
        <div class="tu">
            <span class="ziti" @click="servquy"><van-icon name="search" /></span>
            <div class="scop">
                <div @touchstart="onTouchStart" @touchmove.prevent="onTouchMove" @touchend="onTouchEnd" ref="viewbox">
                    <div class="my-video" style="height: 100vh" v-for="item, index in arr" :key="index" ref="biewsd" @click="add(index)">
                        <video data-v-202854af="" :src="item.Video.videoPath" class="video" :muted="a"
                             ref="video" autoplay preload="metadata"></video>
                        <div data-v-202854af="" class="side-bar">
                            <div data-v-202854af="" class="avatar">
                                <img data-v-202854af="" :src="'http://43.138.15.137:3000' + item.Video.userAvatar"
                                    alt="" width="40" height="40">
                            </div>
                            <div data-v-202854af="" class="like iconfont icon-aixin_shixin" @click="likes(item, index)"
                                ref="samant">
                                <span data-v-202854af="" class="likenum">{{ item.WSLCNum.likeNum }}</span>
                            </div>
                            <div data-v-202854af="" class="comment " @click="pingluns(item, index)"><van-icon
                                    name="chat-o" /><span data-v-202854af="" class="commentnum">{{
                                        item.WSLCNum.commentNum }}</span></div>
                            <div data-v-202854af="" class="share " @click="deng"><van-icon name="share-o" /><span
                                    data-v-202854af="" class="sharenum">{{ item.WSLCNum.shareNum }}</span></div>
                        </div>
                        <div class="text">
                            <div>南京市</div>
                            <div class="name">{{ item.Video.userNickname }}</div>
                            <div class="desc">
                                {{ item.Video.videoDesc }}
                            </div>
                        </div>
                        <div class="  zanting     iconfont icon-zantingtubiao1" style="display: none;"></div>
                        
                    </div>

                </div>
            </div>
        </div>
        <div class="kai" v-show="plays">
            <div style="margin-left: 18px;">因浏览器影响,需要手动开启声音</div>
            <div class="left" @click="bofang">x</div>
        </div>
        <dibu></dibu>
        <Transition name="router">
            <AsyncLogin v-if="ishow" @nikan="hui"></AsyncLogin>
        </Transition>
        <Transition name="routede">
            <Asyncpinglun v-if="xian" @guan="guanbi" :info="pages" :spid="videoIds"></Asyncpinglun>
        </Transition>
    </div>
</template>
<script setup>

import { getpinglunviewoAPI } from '../api/pinglun.js'
import dibu from '../components/dibu.vue'
import { getviewolikeAPI } from '../api/like'
import { getviewoAPI } from '../api/yinpin'
import loding from '../components/jiazai.vue'
import { gethlogotAPI } from '../api/zhuxiao.js'
import { onMounted, ref, computed, defineAsyncComponent, reactive } from 'vue'
// import{ref} from 'vue'
const AsyncLogin = defineAsyncComponent({
    loader: () => (new Promise((resolve, reject) =>
        resolve(import('../components/login.vue'))

    ))
})
const Asyncpinglun = defineAsyncComponent({
    loader: () => (new Promise((resolve, reject) => setTimeout(() => {
        resolve(import('../components/pinglun.vue'))

    }, 2000))),
    loadingComponent: loding,
    delay: 200,
})
import { useRouter } from 'vue-router'
import { getCurrentInstance } from 'vue'
const internalInstance = getCurrentInstance()
// 定义变量
let router = useRouter()
let arr = ref([])
let startY = ref(0)
let video = ref(null)
let viewbox = ref(null)
let videoNum = ref(true)
let moveY = ref(0)
let indexs = ref(0)
let viewheight = ref(0)
let ishow = ref(false)
let samant = ref(null)
let xian = ref(false)
let pages = ref([])
let videoIds = ref('') 
let divheight = ref(0)
let biewsd = ref(null)
let a = ref(true)
async function busd() {
    let view = await getviewoAPI()
    view.data.data.map((item) => {
        if (JSON.parse(item).Video !== undefined) {
            arr.value.push(JSON.parse(item))
        }
    })
    console.log(arr.value);
}
busd()
function add(index) {
    if (videoNum.value) {
        video.value[index].pause()
        biewsd.value[index].children[3].style.display = 'block'
    } else {
        video.value[index].play()
        biewsd.value[index].children[3].style.display = 'none'
    }
    videoNum.value = !videoNum.value
}
function onTouchStart(e) {
    moveY.value = 0
    startY.value = e.changedTouches[0].pageY
}
function onTouchMove(e) {
    moveY.value = e.changedTouches[0].pageY - startY.value
    viewbox.value.style = `transition-duration: 0ms; transform: translate(0px,${translatex.value + moveY.value}px) scale(1) translateZ(0px);px);`
}
let translatex = computed(() => {
    return -(viewheight.value * indexs.value);
})
function onTouchEnd(e) {
    if (moveY.value >= 150 && indexs.value !== 0) {
        indexs.value--;
    } else if (moveY.value <= -150) {
        indexs.value++;
        // 
    }
    if (indexs.value == arr.value.length - 1) {
        busd()
    }
    viewbox.value.style = ` transition-duration: 500ms; transform: translate(0px,${translatex.value}px) scale(1) translateZ(0px);px);`
    video.value.map(item => {
        item.pause()
    })
    video.value[indexs.value].play()

}
onMounted(() => {
    window.addEventListener('resize', () => {
        viewheight.value = window.innerWidth;
        document.querySelectorAll('.my-video').forEach((item) => {
            item.style = `height: ${viewheight.value || window.innerWidth}px;`
        })
    })
    viewheight.value = window.innerHeight
    console.log(viewheight.value);
})
function servquy() {
    router.push('/servace')
}
async function likes(item, index) {
    let relike = await getviewolikeAPI({ userId: item.Video.userId, videoId: item.Video.videoId })
    console.log(relike);
    // console.log(samant.value[index]);

    if (relike.data.data == '喜欢成功') {
        internalInstance.appContext.config.globalProperties.$message({ type: 'success', text: '喜欢成功' })
        samant.value[index].style = 'color:red;'
        item.WSLCNum.likeNum++


    } else {
        internalInstance.appContext.config.globalProperties.$message({ type: 'success', text: '取消喜欢成功' })
        samant.value[index].style = 'color:#e8e8e9;'
        item.WSLCNum.likeNum--
    }
}
function deng() {
    ishow.value = true
}
function hui() {
    ishow.value = false
}
function guanbi() {
    xian.value = false
}
async function pingluns(item) {
    let result = await getpinglunviewoAPI({ videoId: item.Video.videoId })
    xian.value = true
    pages.value = result.data.data.reverse()
    console.log(pages.value);
    videoIds.value = item.Video.videoId
}
router.beforeEach((to, from, next) => {
    if (to.path === '/homes' || to.path === '/user' || to.path === '/guanzhu' || to.path === '/xiaoxi') {
        const userId = localStorage.getItem('userId')
        if (userId) {
            next()
        } else {
            ishow.value = true
            next('/')
        }
    } else {
        next()
    }
})
let plays = ref(true)
function bofang() {
    plays.value = false
    // video.value[index].play()
    a.value = false
    // video.value[indexs.value].pause()
}
</script>
<style scoped lang=scss>
.kai {
    position: fixed;
    top: 260px;
    left: 50px;
    bottom: 0;
    right: 0;
    width: 260px;
    height: 30px;
    background-color: rgba(0, 0, 0, 0.5);
    color: white;
    display: flex;
    line-height: 30px;
    border-radius: 30px;
    // background-color: beige;
}

.left {
    margin-left: 20px;
    font-size: 20px;
}

.zanting {
    position: absolute;
    top: 297px;
    left: 161px;
    font-size: 70px;
    z-index: 1000;
    color: #ccc;
}

.xian {
    position: fixed;
    top: 0;
    left: 0;
    bottom: 0;
    right: 0;
    z-index: -3000;
    transition: all 1s linear;
}

.router-enter-active {
    animation: jin 1s;
}

.router-leave-active {
    animation: chu 1s;
}

@keyframes jin {
    from {
        transform: translateY(100%);
    }

    to {
        transform: translateY(0);
    }

}

@keyframes chu {
    from {
        transform: translateY(0);
    }

    to {
        transform: translateY(100%);
    }

}

.routede-enter-active {
    animation: jin 1s;
}

.routede-leave-active {
    animation: chu 1s;
}

@keyframes jin {
    from {
        transform: translateY(100%);
    }

    to {
        transform: translateY(0);
    }

}

@keyframes chu {
    from {
        transform: translateY(0);
    }

    to {
        transform: translateY(100%);
    }

}

.tu {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: black;
    overflow: hidden;
}

.ziti {
    position: fixed;
    right: 10px;
    top: 10px;
    padding: 10px;
    font-size: 24px;
    z-index: 222;
    color: white;
}

.scope {
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
}

.my-video {
    position: relative;

    video {
        display: block;
        width: 100%;
        height: 100%;
    }

    .side-bar {
        position: absolute;
        right: 10px;
        bottom: 74px;
        display: -webkit-box;
        display: -ms-flexbox;
        display: flex;
        -webkit-box-orient: vertical;
        -webkit-box-direction: normal;
        -ms-flex-direction: column;
        flex-direction: column;
        height: 250px;
        -webkit-box-pack: justify;
        -ms-flex-pack: justify;
        justify-content: space-between;

        .avatar[data-v-202854af] {
            position: relative;
            border-radius: 50%;
            background: none;
            border: 1px solid #e8e8e9;

            img[data-v-202854af] {
                border-radius: 50%;
            }
        }

        .comment .commentnum[data-v-202854af] {
            font-size: 10px;
            position: absolute;
            bottom: -5px;
            left: 50%;
            -webkit-transform: translateX(-50%) translateY(100%);
            transform: translateX(-50%) translateY(100%);
            color: #e8e8e9;
        }

        .like[data-v-202854af] {
            position: relative;

            .icon-heart-fill:before {
                content: "\E849";
            }

            .likenum[data-v-202854af] {
                font-size: 10px;
                position: absolute;
                bottom: -5px;
                left: 50%;
                -webkit-transform: translateX(-50%) translateY(100%);
                transform: translateX(-50%) translateY(100%);
                color: #e8e8e9;
            }

        }

        .comment[data-v-202854af] {
            position: relative;
        }

        >div[data-v-202854af] {
            width: 40px;
            height: 40px;
            font-size: 40px;
            color: #e8e8e9;
            -webkit-transition: color 0.3s;
            transition: color 0.3s;
        }

        .share[data-v-202854af] {
            position: relative;
        }

        .share .sharenum[data-v-202854af] {
            font-size: 10px;
            position: absolute;
            bottom: -5px;
            left: 50%;
            -webkit-transform: translateX(-50%) translateY(100%);
            transform: translateX(-50%) translateY(100%);
            color: #e8e8e9;
        }


    }

    .text {
        position: absolute;
        left: 10px;
        bottom: 70px;
        width: 70%;
        color: white;

        .name[data-v-202854af] {
            color: #fff;
            margin-bottom: 10px;
            margin-top: 10px;
        }

        .desc[data-v-202854af] {
            font-size: 16px;
            color: #e8e8e9;
            line-height: 20px;
        }
    }

}
</style>

搜索视频列表跳转
<template>
    <div class="dise">
        {{ arracs.length }}
        <div class="play-list">
            <div class="back iconfont icon-dayuhao3" @click="huitui"></div>
            <div class="wrap" style="height: 667px; width: 375px;">
                <div :style="{ transform: `translateY(${-100 * dels + 'vh'}` }" @touchstart="onTouchStart"
                    @touchmove.prevent="onTouchMove" @touchend="onTouchEnd" ref="viewbox">
                    <div class="my-video" style="height: 100vh" v-for="item, index in arracs" :key="index">
                        <video :src="item.Video.videoPath" class="video" @click="add(index)" ref="video" autoplay></video>
                        <div class="side-bar">
                            <div class="avatar"><img :src="'http://43.138.15.137:3000' + item.Video.userAvatar" alt=""
                                    width="40" height="40"></div>
                            <div class="like iconfont icon-aixin_shixin"><span class="likenum">{{ item.WSLCNum.likeNum
                                    }}</span></div>
                            <div class="comment "><van-icon name="chat-o" /><span class="commentnum">{{
                                item.WSLCNum.commentNum }}</span></div>
                            <div class="share iconfont "><van-icon name="share-o" /><span class="sharenum">{{
                                item.WSLCNum.shareNum }}</span>
                            </div>
                        </div>
                        <div class="input-bar"><input placeholder="  有爱评论,说点儿好听的~" type="text" class="input"><span
                                class="iconfont icon-at"></span><span class="iconfont icon-check"></span></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>
<script setup>import { ref, defineProps, defineAsyncComponent, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
let router = useRouter()
let { dels, arracs } = defineProps(['dels', 'arracs'])
function huitui() {
    router.go(-1)
}
// let redfr = ref(0)
// redfr.value = dels
let videoNum = ref(0)
let startY = ref(0)
let video = ref(null)
let viewbox = ref(null)
let moveY = ref(0)
let indexs = ref(0)
indexs.value = dels
let viewheight = ref(0)
let add = (index) => {
    videoNum.value++
    if (videoNum.value % 2 == 0) {
        video.value[index].pause()
    } else {
        video.value[index].play()
    }2n
}
function onTouchStart(e) {
    moveY.value = 0
    startY.value = e.changedTouches[0].pageY
}
function onTouchMove(e) {
    moveY.value = e.changedTouches[0].pageY - startY.value
    // console.log(moveY.value);
    viewbox.value.style = `transition-duration: 0ms; transform: translate(0px,${translatex.value + moveY.value}px) scale(1) translateZ(0px);px);`
}
let translatex = computed(() => {
    return -(viewheight.value * indexs.value);
})
function onTouchEnd(e) {
    // if (moveY.value == 0) return
    if (moveY.value >= 150 && indexs.value !== 0) {
        indexs.value--;

    } else if (moveY.value <= -150 && indexs.value !== arracs.length - 1) {
        indexs.value++;
    }
    viewbox.value.style = ` transition-duration: 500ms; transform: translate(0px,${translatex.value}px) scale(1) translateZ(0px);px);`
    video.value.map(item => {
        item.pause()
    })
    video.value[indexs.value].play()
}
onMounted(() => {
    window.addEventListener('resize', () => {
        viewheight.value = window.innerWidth;
        document.querySelectorAll('.my-video').forEach((item) => {
            item.style = `height: ${viewheight.value || window.innerWidth}px;`
        })
    })
    viewheight.value = window.innerHeight
})
</script>
<style scoped>
.dise {
    position: fixed;
    z-index: 3000;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;

}

.play-list {
    position: fixed;
    /* z-index: 3000; */
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    background: #161622;
    color: white;
}

.back {
    position: absolute;
    left: 10px;
    top: 10px;
    padding: 8px;
    z-index: 33;
}

.wrap {
    position: relative;
}

.my-video {
    position: relative;
}

.my-video .video {
    display: block;
    width: 100%;
    height: 100%;
}

.my-video .side-bar {
    position: absolute;
    right: 10px;
    bottom: 74px;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-orient: vertical;
    -webkit-box-direction: normal;
    -ms-flex-direction: column;
    flex-direction: column;
    height: 250px;
    -webkit-box-pack: justify;
    -ms-flex-pack: justify;
    justify-content: space-between;
}

.my-video .side-bar .avatar {
    position: relative;
    border-radius: 50%;
    background: none;
    border: 1px solid #e8e8e9;
}

.my-video .side-bar .avatar img {
    border-radius: 50%;
}

.my-video .side-bar>div {
    width: 40px;
    height: 40px;
    font-size: 40px;
    color: #e8e8e9;
    -webkit-transition: color 0.3s;
    transition: color 0.3s;
}

.my-video .side-bar .like {
    position: relative;
}

.my-video .side-bar>div {
    width: 40px;
    height: 40px;
    font-size: 40px;
    color: #e8e8e9;
    -webkit-transition: color 0.3s;
    transition: color 0.3s;
}

.my-video .side-bar .like .likenum {
    font-size: 10px;
    position: absolute;
    bottom: -5px;
    left: 50%;
    -webkit-transform: translateX(-50%) translateY(100%);
    transform: translateX(-50%) translateY(100%);
    color: #e8e8e9;
}

.my-video .side-bar .comment {
    position: relative;
}

.my-video .side-bar>div {
    width: 40px;
    height: 40px;
    font-size: 40px;
    color: #e8e8e9;
    -webkit-transition: color 0.3s;
    transition: color 0.3s;
}

.my-video .side-bar .comment .commentnum {
    font-size: 10px;
    position: absolute;
    bottom: -5px;
    left: 50%;
    -webkit-transform: translateX(-50%) translateY(100%);
    transform: translateX(-50%) translateY(100%);
    color: #e8e8e9;
}

.my-video .side-bar .share {
    position: relative;
}

.my-video .side-bar>div {
    width: 40px;
    height: 40px;
    font-size: 40px;
    color: #e8e8e9;
    -webkit-transition: color 0.3s;
    transition: color 0.3s;
}

.my-video .side-bar .share .sharenum {
    font-size: 10px;
    position: absolute;
    bottom: -5px;
    left: 50%;
    -webkit-transform: translateX(-50%) translateY(100%);
    transform: translateX(-50%) translateY(100%);
    color: #e8e8e9;
}

.my-video .text-wrap {
    position: absolute;
    left: 10px;
    bottom: 54px;
    width: 70%;
}

.my-video .text-wrap .name {
    color: #fff;
    margin-bottom: 10px;
    margin-top: 10px;
}

.my-video .text-wrap .desc {
    font-size: 14px;
    color: #e8e8e9;
    line-height: 20px;
}

.my-video .input-bar {
    border-top: 0.5px solid rgba(41, 40, 37, 0.8);
    width: 100%;
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    height: 44px;
    position: absolute;
    bottom: 0;
    background: rgba(26, 27, 32, 0);
}

.my-video .input-bar .input {
    background: rgba(26, 27, 32, 0);
    -webkit-box-flex: 1;
    -ms-flex: 1;
    flex: 1;
    font-size: 14px;
    color: #e8e8e9;
    padding-left: 10px;
}

.my-video .input-bar .iconfont {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    width: 44px;
}

.my-video .input-bar .iconfont {
    display: -webkit-box;
    display: -ms-flexbox;
    display: flex;
    -webkit-box-pack: center;
    -ms-flex-pack: center;
    justify-content: center;
    -webkit-box-align: center;
    -ms-flex-align: center;
    align-items: center;
    width: 44px;
}
</style>