gree_leran/components/VideoView/VideoView.vue

238 lines
5.6 KiB
Vue

<template>
<div class="container">
<div class="video-box">
<video class="video" ref="videoStatus" @play="propsPlay" :src="Videos.src" controls></video>
<div class="info-bar">
<div class="title-and-stats">
<span class="title">{{ Videos.titleName }}</span>
<div class="stats">
<span class="date">{{ info.createTime }}</span>
</div>
</div>
<div class="action-buttons">
<up-icon v-if="info.isLike" @click="toLike" name="heart-fill" color="#ff0004" size="28"></up-icon>
<up-icon v-else name="heart" @click="toLike" color="#ff0004" size="28"></up-icon>
<up-icon v-if="info.isCollection" @click="toCollection" name="star-fill" color="#ffd700" size="28"></up-icon>
<up-icon v-else name="star" @click="toCollection" color="#ffd700" size="28"></up-icon>
</div>
</div>
<div class="description-bar">
<div :class="{'description': true, 'expanded': isExpanded}">
<rich-text :nodes="info.description"></rich-text>
</div>
<div class="expand-button" @click="toggleExpand">
<span class="expand-text">{{ isExpanded ? '收起' : '展开描述' }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, reactive, defineProps, defineEmits, onMounted } from 'vue';
const emit = defineEmits(['onplay', 'ClickCollection', 'ClickLike']);
// Props
const props = defineProps({
VideoId: {
type: Number,
default: null
},
Videos: {
type: Object,
default: () => ({
id: "",
src: "https://prod-streaming-video-msn-com.akamaized.net/a8c412fa-f696-4ff2-9c76-e8ed9cdffe0f/604a87fc-e7bc-463e-8d56-cde7e661d690.mp4",
titleName: '标题名',
description: '详细描述',
createTime: "日期",
isLike: false,
isCollection: false,
likeCount: 0,
viewCount: 0,
})
}
});
// Local state
const videoContent = ref(null);
const isExpanded = ref(false);
const info = reactive({
id: null,
src: '',
titleName: '',
description: '',
createTime: '',
isLike: false,
isCollection: false,
likeCount: 0,
viewCount: 0,
});
// Methods
const propsPlay = (e) => {
const videoContext = videoContent.value;
const videoStatus = ref(null);
videoStatus.value = e.target;
// Emit event to parent
console.log("播放视频");
emit('onplay', {
e,
videoStatus,
videoContext
});
};
const toLike = () => {
info.isLike = !info.isLike;
info.isLike ? info.likeCount++ : info.likeCount--;
console.log("id",info.id);
emit('ClickLike', info.id, info.isLike);
};
const toCollection = () => {
info.isCollection = !info.isCollection;
emit('ClickCollection', info.id, info.isCollection);
};
const toggleExpand = () => {
isExpanded.value = !isExpanded.value;
};
// Lifecycle hook
onMounted(() => {
videoContent.value = uni.createVideoContext('video', this);
console.log("是否传入id",props.Videos.id);
info.id = props.Videos.id;
info.src = props.Videos.src;
info.titleName = props.Videos.titleName;
info.description = props.Videos.description;
info.createTime = props.Videos.createTime;
info.isLike = props.Videos.isLike;
info.isCollection = props.Videos.isCollection;
info.likeCount = props.Videos.likeCount|0;
info.viewCount = props.Videos.viewCount;
});
</script>
<style scoped lang="scss">
$videoBoxradius: 10px;
$backColor: #fff;
$primaryColor: #ff0004;
$secondaryColor: #ffd700;
$textColor: #000;
$borderColor: rgba(0, 0, 0, 0.1);
.container {
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
.video-box {
overflow: hidden;
border-radius: $videoBoxradius;
background-color: $backColor;
width: 100%;
max-width: 800px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
transition: transform 0.3s ease-in-out;
&:hover {
transform: scale(1.02);
}
.video {
width: 100%;
border-bottom: 1px solid $borderColor;
border-radius: $videoBoxradius $videoBoxradius 0 0;
}
.info-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
color: $textColor;
background-color: #f9f9f9;
border-top: 1px solid $borderColor;
.title-and-stats {
display: flex;
flex-direction: column;
.title {
font-size: 18px;
font-weight: bold;
}
.stats {
display: flex;
gap: 10px;
font-size: 14px;
color: #666;
}
}
.action-buttons {
display: flex;
gap: 10px;
up-icon {
cursor: pointer;
transition: transform 0.3s ease;
&:hover {
transform: scale(1.2);
}
}
}
}
.description-bar {
padding: 10px;
background-color: #f9f9f9;
border-top: 1px solid $borderColor;
.description {
overflow: hidden;
max-height: 0;
transition: max-height 0.3s ease-in-out;
&.expanded {
max-height: 200px;
}
rich-text {
display: block;
margin-top: 10px;
font-size: 14px;
color: $textColor;
}
}
.expand-button {
margin-top: 10px;
color: $primaryColor;
cursor: pointer;
font-size: 14px;
display: flex;
align-items: center;
transition: color 0.3s ease-in-out;
&:hover {
color: darken($primaryColor, 10%);
}
.expand-text {
font-size: 14px;
margin-left: 5px;
}
}
}
}
}
</style>