236 lines
5.6 KiB
Vue
236 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="views">{{ info.viewCount }} 次观看</span> -->
|
||
|
<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>
|
||
|
<!-- {{info.likeCount!=0?info.likeCount:""}} -->
|
||
|
<!-- 收藏按钮 -->
|
||
|
<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>
|
||
|
<button class="expand-button" @click="toggleExpand">
|
||
|
{{ isExpanded ? '收起' : '展开' }}
|
||
|
</button>
|
||
|
</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;
|
||
|
}
|
||
|
|
||
|
.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: 100px;
|
||
|
transition: max-height 0.3s ease-in-out;
|
||
|
|
||
|
&.expanded {
|
||
|
max-height: none;
|
||
|
}
|
||
|
|
||
|
rich-text {
|
||
|
display: block;
|
||
|
margin-top: 10px;
|
||
|
font-size: 14px;
|
||
|
color: $textColor;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
.expand-button {
|
||
|
margin-top: 10px;
|
||
|
background: none;
|
||
|
border: none;
|
||
|
color: $primaryColor;
|
||
|
cursor: pointer;
|
||
|
font-size: 14px;
|
||
|
padding: 0;
|
||
|
outline: none;
|
||
|
transition: color 0.3s ease-in-out;
|
||
|
|
||
|
&:hover {
|
||
|
color: darken($primaryColor, 10%);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
</style>
|