jiuyiUniapp/jiuyi2/components/index/videoMenu.vue

181 lines
3.7 KiB
Vue
Raw Normal View History

2024-12-18 15:46:27 +08:00
<script setup>
/**
* 视频菜单组件
*
*/
import {
ref,
reactive,
onMounted
} from 'vue'
import video from '../../api/video';
import util from '../../common/js/util';
// 传参
const props = defineProps({
// 列表数据
list: {
type: Array,
},
// 模式 list列表展示 点击播放视频 menu菜单模式 点击触发回调事件 checkbox多选
mode: {
type: String,
default: 'list',
},
// 多选模式下的 选择数量限制 0为不限制
limit: {
type: Number,
default: 0,
},
// 是否我自己 0不是 1是
isMine: {
type: [String, Number],
default: 0,
},
// 是否显示统计 0不显示 1显示
statistic: {
type: [String, Number],
default: 0,
},
2024-12-18 15:46:27 +08:00
})
// 子触发父
const emit = defineEmits(['item'])
// 已选择的视频id
const ids = defineModel('ids')
// 视频上下文对象
const videoContext = ref(null)
// 视频播放路径
const videoUrl = ref('')
onMounted(() => {
// 创建视频上下文对象
videoContext.value = uni.createVideoContext('video')
})
// 进入全屏
function requestFullScreen() {
videoContext.value.requestFullScreen()
}
// 暂停
function pause() {
// 暂停当前视频
videoContext.value.pause()
}
/**
* 点击视频播放
* @param {Object} item
*/
function handleVideo(item) {
// 列表模式
if (props.mode == 'list') {
uni.navigateTo({
url: util.setUrl('/pages/index/videoDetail', {
2025-01-19 13:55:21 +08:00
videoId: item.id,
2024-12-18 15:46:27 +08:00
isMine: props.isMine,
statistic: props.statistic,
2024-12-18 15:46:27 +08:00
})
})
// videoUrl.value = item.format_videoUrl
// 进入全屏
// requestFullScreen()
}
// 菜单模式
else if (props.mode == 'menu') {
emit('item', item)
}
// 多选模式
else if (props.mode == 'checkbox') {
const findIndex = ids.value.findIndex(node => node == item.videoId)
if (findIndex >= 0) ids.value.splice(findIndex, 1)
else {
// 如果有限制 且 数量到达上限
if (props.limit != 0 && props.limit <= ids.value.length) return
ids.value.push(item.videoId)
}
}
}
/**
* 视频进入退出全屏
* @param {Object} ev
*/
function videoFullscreenchange(ev) {
// 根据全屏状态决定是否播放盒暂停
if (ev.detail.fullScreen) videoContext.value.play()
else pause()
}
defineExpose({
videoContext,
pause,
requestFullScreen,
})
</script>
<template>
<view>
<!-- 视频菜单 -->
<view class="list">
<view class="item pr" v-for="(item,index) in list" :key="index" @click="handleVideo(item)">
2025-01-13 21:59:03 +08:00
<image :src="item.coverUrl" mode="aspectFill" />
2024-12-18 15:46:27 +08:00
<view class="window pfull"></view>
<!-- 选项 -->
<view class="amount pa r0 t0 df ptb10 plr10" v-if="mode == 'checkbox'">
<uni-icons type="circle-filled" size="50rpx" color="#20D200" v-if="ids.includes(item.videoId)" />
<uni-icons type="circle" color="#fff" size="50rpx" v-else />
</view>
<view class="amount pa l0 r0 b0 df ptb10 plr10" v-if="item.play">
<image class="wh24" src="/static/amount.png" mode="aspectFit" />
<view class="txt f1 ml10 cfff f20">{{item.play}}</view>
</view>
</view>
</view>
<view class="nomore mtb50" v-if="!list[0]">暂无视频</view>
<!-- 视频播放 -->
<video class="videoContext" :src="videoUrl" id="video" @fullscreenchange="videoFullscreenchange" />
</view>
</template>
<style lang="scss" scoped>
//
.list {
display: grid;
grid-template-columns: repeat(3, 1fr);
grid-gap: 5rpx;
.item {
height: 360rpx;
image {
width: 100%;
height: 100%;
}
}
.window {
background-color: rgba(0, 0, 0, .1);
}
// 播放量
.amount {
.txt {
opacity: .5;
}
}
}
// 视频上下文对象
.videoContext {
position: absolute;
width: 0;
height: 0;
}
</style>