176 lines
3.6 KiB
Vue
176 lines
3.6 KiB
Vue
<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,
|
|
}
|
|
})
|
|
// 子触发父
|
|
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', {
|
|
videoId: item.id,
|
|
isMine: props.isMine,
|
|
})
|
|
})
|
|
// videoUrl.value = item.format_videoUrl
|
|
// 进入全屏
|
|
// requestFullScreen()
|
|
}
|
|
// 菜单模式
|
|
else if (props.mode == 'menu') {
|
|
videoUrl.value = item.format_videoUrl
|
|
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)">
|
|
<image :src="item.coverUrl" mode="aspectFill" />
|
|
|
|
<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> |