Vue3.2简单制作一个动漫网站

1,190 阅读1分钟

效果图: image.png

安装

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>