效果图:
安装
npm i axios
npm i vue3-video-play
npm i element-plus
开始使用
注意:该项目设置了vue和vue-router的自动导入,所以组件无需引入。
接口地址
搜索:http://api.pingcc.cn/video/search/title/关键字/当前页/页数大小
例:http://api.pingcc.cn/video/search/title/刀剑神域/1/10
视频地址:http://api.pingcc.cn/videoChapter/search/视频id
main.ts
import { createApp } from 'vue'
import App from './App.vue'
import vue3videoPlay from 'vue3-video-play' // 引入组件
import 'vue3-video-play/dist/style.css' // 引入css
import router from './router'
const app = createApp(App)
app.use(vue3videoPlay)
app.use(router)
app.mount('#app')
layout/index.vue
<template>
<div class="common-layout">
<el-container>
<el-container class="mainbg">
<el-header>
<div>
<el-input v-model="kw" placeholder="Please input"
style="background-color:#ffffff14 !important;width: 300px;" @keyup.enter="toResule" />
</div>
</el-header>
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</div>
</template>
<script setup lang='ts'>
const router = useRouter();
const kw = ref('')
const toResule = () => {
router.push({ name: 'search', query: { keyworks: kw.value } })
}
</script>
<style scoped lang='scss'>
.mainbg {
background-color: #1A1C1F;
height: 100vh;
}
.el-input__wrapper {
background-color: transparent !important;
}
.asidebg {
background-color: #16161a;
height: 100vh;
}
</style>
search.vue
<template>
<el-carousel :interval="4000" type="card" height="250px">
<el-carousel-item v-for="(item, index) in Result" :key="index">
<el-image style="width: 100%; height: 100%" :src="item.cover" fit="cover" />
</el-carousel-item>
</el-carousel>
<el-row>
<el-col v-for="(o, index) in Result" :key="index" :span="4">
<el-card :body-style="{ padding: '0px' }" style="margin: 10px;"
@click="router.push({ name: 'info', query: { infoid: o.videoId } })">
<img :src="o.cover" class="image" />
<div style="padding: 14px">
<span style="color:#000;">{{ o.title }}</span>
<p class="p_descs">{{ o.descs }}</p>
<div class="bottom">
<time class="time">{{ o.releaseTime }}</time>
</div>
</div>
</el-card>
</el-col>
</el-row>
<!-- <div>动漫</div> -->
</template>
<script setup lang='ts'>
import axios from 'axios'
const route = useRoute()
const router = useRouter()
interface info {
cover: string,
title: string,
descs: string,
releaseTime: string,
videoId: string
}
const Result = ref<info[]>([])
onMounted(() => {
axios.get(`http://api.pingcc.cn/video/search/title/刀剑神域/1/10`).then(res => {
Result.value = res.data.data
// console.log(res.data);
})
})
const toresult = () => {
axios.get(`http://api.pingcc.cn/video/search/title/${route.query.keyworks}/1/10`).then(res => {
Result.value = res.data.data
// console.log(res.data);
})
}
watch(() => route.query.keyworks, () => {
toresult()
})
</script>
<style scoped lang='scss'>
.p_descs {
height: 100px;
font-size: 10px;
color: rgb(147 147 147);
overflow: hidden;
/* 超出的部分隐藏起来 */
// white-space: nowrap;
/* 不显示的地方用省略号...代替 */
text-overflow: ellipsis;
/* 支持 IE */
}
.time {
font-size: 12px;
color: #999;
}
.bottom {
margin-top: 13px;
line-height: 12px;
display: flex;
justify-content: space-between;
align-items: center;
}
.button {
padding: 0;
min-height: auto;
}
.image {
width: 100%;
height: 400px;
display: block;
}
</style>
info.vue
<template>
<!-- 信息 -->
<div class="box">
<div class="cover">
<el-image style="width: 100%" :src="mp.cover" fit="cover" />
</div>
<div class="descs">
<el-descriptions :column="2" size="large">
<el-descriptions-item label="名称">{{ mp.title }}</el-descriptions-item>
<el-descriptions-item label="导演">{{ mp.director }}</el-descriptions-item>
<el-descriptions-item label="地区">{{ mp.region }}</el-descriptions-item>
<el-descriptions-item label="上映时间">{{ mp.updateTime }}</el-descriptions-item>
<el-descriptions-item label="类型">{{ mp.videoType }}</el-descriptions-item>
<el-descriptions-item label="演员">{{ mp.actor }}</el-descriptions-item>
<el-descriptions-item label="简介">{{ mp.descs }}</el-descriptions-item>
</el-descriptions>
</div>
<div style="clear:both;"></div>
</div>
<!-- 选集 -->
<div class="a_alog">
<el-row class="mb-4">
<button @click="router.push({ name: 'play', query: { videiourl: item.chapterPath } })"
v-for="(item, index) in mp.chapterList" :key="index" class="alog" href="javascript;;">{{ item.title
}}</button>
</el-row>
</div>
</template>
<script setup lang='ts'>
import axios from 'axios'
const router = useRouter()
const route = useRoute();
const mp = ref<any>([])
onMounted(() => {
axios.get(`http://api.pingcc.cn/videoChapter/search/${route.query.infoid}`).then(res => {
mp.value = res.data.data
})
})
</script>
<style lang='scss'>
.a_alog {
width: 1200px;
margin: 0 auto;
}
.alog {
width: 180px;
padding: 10px;
margin: 10px;
border: 1px solid #fff;
}
a {
text-decoration: none;
}
.box {
display: flex;
align-items: center;
width: 1200px;
margin: 0 auto;
border-radius: 10px;
span {
color: #fff !important;
}
.cover {
width: 300px;
float: left;
margin-right: 50px;
}
.descs {
width: 850px;
float: right;
}
}
.el-descriptions__body {
background-color: transparent !important;
}
</style>
play.vue
<template>
<div class="sp">
<vue3VideoPlay width="1200px" :title="title" :src="options.src" :type="options.type" :autoPlay="false" />
</div>
</template>
<script setup lang='ts'>
const route = useRoute()
const title = ref('')
const options = reactive({
src: route.query.videiourl, //视频源
type: 'm3u8', //视频类型
title: ''
})
</script>
<style scoped lang='scss'>
.sp{
width: 1200px;
margin: 0 auto;
}
</style>