image
image.png

搜索

第一件事就是搜索,
serch搜索,里面有一个input和button。input和button一样有一个serch为的是点击或者回车开始搜索
focus是为了下次点进去可以节省删除键query直接点击时候自动删除
model肯定是为了获取你要输入的值query

点击搜索,axios.get('...' + this.query),目的是点击后api地址加上你输入的名称拿到返回值,来个then进行遍历

API:https://autumnfish.cn/search?keywords=
类型:get
说明
query搜索你输入的文本
musicList用于遍历使用,把数据返回值赋值在这里。再用它遍历出去
<template>
    <div id="app">
        <div class="serch">
            <input type="text" 
                @keyup.enter="serch()" 
                @focus="query = ''" 
                v-model="query" />
            <button @click="serch">搜索</button>
        </div>
        <div class="musLeft">
            <ol>
                <li v-for="item in musicList">
                    <a href="">
                        {{item.name}}
                    </a>
                </li>
            </ol>
        </div>
    </div>
</template>

<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                query: '',
                musicList: []
            }
        },
        methods: {
            serch() {
                axios.get('https://autumnfish.cn/search?keywords=' + this.query).then(res => {
                    console.log(res)
                    this.musicList = res.data.result.songs
                }).catch(err => {
                    console.log(err)
                })
            }
        }
    }
</script>

<style lang="less" scoped="scoped">
    * {
        margin: 0;
        padding: 0;
    }

    .serch {
        display: flex;
        width: 100%;
        max-width: 880px;
        margin: auto;
        margin-top: 20px;

        input {
            flex: 1;
            border: none;
            box-shadow: 0 0 15px #cbcbcb;
        }

        button {
            padding: 7px 20px;
            border: none;
            background: #000;
            color: #fff;
        }
    }


    .musLeft {
        width: 200px;
        height: calc(100vh - 85px);
        box-shadow: inset 0 0 15px #dcdcdc;
        margin: 15px;
        overflow-y: scroll;

        ol {
            list-style: none;
            padding-left: 10px;

            li {
                margin: 10px 0;

                &:nth-child(1) {
                    display: table-column;
                }

                a {
                    text-decoration: none;
                    color: #1f6879;
                }

                abbr {
                    float: right;
                    margin-right: 20px;
                }
            }
        }
    }
</style>

点击播放

就在上一节的位置更改一样东西,就是你点击的li链接.
他的外层成了一个事件,prevent是为了拦截系统a的默认值
这个xplay的点击需要 带一个值,就是遍历的时候item.name的附近就有一个item.id
这个id就是为了生成一个音乐播放链接让你点击后就播放
播放时候:src获取自动播放

API:https://autumnfish.cn/song/url?id=
类型:get
<div class="musLeft">
    <ol>
        <li v-for="item in musicList">
            <a href="" @click.prevent="xplay(item.id)">
                {{item.name}}
            </a>
        </li>
    </ol>
</div>
<div class="musRight">
    <audio :src="musicUrl" controls autoplay loop></audio>
</div>


<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                query: '',
                musicList: [],
                musicUrl: '',
            }
        },
        methods: {
            serch() { ... },
            xplay(id) 
            {
                axios.get('https://autumnfish.cn/song/url?id=' + id).then(res => {
                    this.musicUrl = res.data.data[0].url
                })            
            }
        }
    }
</script>

封面

加一个fmImg,这里有播放旋转用的
transform: rotate(360deg);

API:https://autumnfish.cn/song/detail?ids=
类型:get
<div class="musLeft">
    <ol>
        <li v-for="item in musicList">
            <a href="" @click.prevent="xplay(item.id)">
                {{item.name}}
            </a>
        </li>
    </ol>
</div>
<div class="musRight">
    <div class="fmImg">
        <img :src="Img" style="width: 300px; border-radius: 500px;" alt="">
    </div>

    <audio :src="musicUrl" controls autoplay loop></audio>
</div>


<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                query: '',
                musicList: [],
                musicUrl: '',
            }
        },
        methods: {
            serch() { ... },
            xplay(id) 
            {
                axios.get(...).then(res => { ... }) //获取播放的api
                
                axios.get('https://autumnfish.cn/song/detail?ids=' + id).then(res => {
                    this.Img = res.data.songs[0].al.picUrl
                })
            }
        }
    }
</script>

MV的显示

首先这个mv的流程,
第一步:在abbr的位置加一个点击弹出事件pmv(item.mvid),并且获取这个mv的id
第二部:pmv(id) { axios... } 添加接口
第三部:里面有两件事,一点击isShow就为真,那么这个窗口就显示了。另一个就是mv链接获取了这个url

axios.get('https://autumnfish.cn/mv/url?id=' + id).then(res => {

this.isShow = true
this.mvlink = res.data.data.url

})

第四部:一点击背景暗黑就返回false,并且把这个MV的链接清空!不然关了还有声音
hide()
{

this.isShow =false
this.mvlink = ''

}

<div class="musBox">
    <div class="musLeft uicss-cn">
        <ol>
            <li v-for="item in musicList">
                <a href="" @click.prevent="xplay(item.id)">{{item.name}}</a>
                <abbr 
                    v-if="item.mvid!=0" 
                    @click="pmv(item.mvid)">
                    <img src="../public/mv.png" alt="">
                </abbr>
            </li>
        </ol>
    </div>
    <div class="musRight">
    ...
    </div>
</div>
<div v-show="isShow" class="mvbox">
    <video :src="mvlink" controls="controls"></video>
    <div @click="hide"></div>
</div>


<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                query: '',
                musicList: [],
                musicUrl: '',
                Img: '',
                                //新增的这两个
                isShow: false,
                mvlink: ''
            }
        },
        methods: {
            serch() { ... },
            xplay(id) { ... },
            pmv(id) 
            {
                axios.get('https://autumnfish.cn/mv/url?id=' + id).then(res => {
                    this.isShow = true
                    this.mvlink = res.data.data.url
                })
            },
            hide()
            {
                this.isShow =false
                this.mvlink = ''
            }
        }
    }
</script>

完整的全部代码

<template>
    <div id="app">
        <div class="bg" :style="{background:`url(${Img})`}"></div>
        <div class="serch">
            <input type="text" @keyup.enter="serch()" @focus="query = ''" v-model="query" />
            <button @click="serch">搜索</button>
        </div>
        <div class="musBox">
            <div class="musLeft uicss-cn">
                <ol>
                    <li v-for="item in musicList">
                        <a href="" @click.prevent="xplay(item.id)">
                            {{item.name}}
                        </a>
                        <abbr v-if="item.mvid!=0" @click="pmv(item.mvid)"><img src="../public/mv.png" alt=""></abbr>
                    </li>
                </ol>
            </div>
            <div class="musRight">

                <div class="fmImg">
                    <img :src="Img" alt="">
                </div>

                <audio :src="musicUrl" controls autoplay loop></audio>
            </div>
        </div>
        <div v-show="isShow" class="mvbox">
            <video :src="mvlink" controls="controls"></video>
            <div @click="hide"></div>
        </div>
    </div>
</template>

<script>
    import axios from 'axios'
    export default {
        data() {
            return {
                query: '',
                musicList: [],
                musicUrl: '',
                Img: '',
                isShow: false,
                mvlink: ''
            }
        },
        methods: {
            serch() {
                axios.get('https://autumnfish.cn/search?keywords=' + this.query).then(res => {
                    console.log(res)
                    this.musicList = res.data.result.songs
                }).catch(err => {
                    console.log(err)
                })
            },
            xplay(id) {
                axios.get('https://autumnfish.cn/song/url?id=' + id).then(res => {
                    this.musicUrl = res.data.data[0].url
                })

                axios.get('https://autumnfish.cn/song/detail?ids=' + id).then(res => {
                    this.Img = res.data.songs[0].al.picUrl
                })
            },
            pmv(id) 
            {
                axios.get('https://autumnfish.cn/mv/url?id=' + id).then(res => {
                    this.isShow = true
                    this.mvlink = res.data.data.url
                })
            },
            hide()
            {
                this.isShow =false
                this.mvlink = ''
            }
        }
    }
</script>

<style lang="less" scoped="scoped">
    * {
        margin: 0;
        padding: 0;
    }

    .bg {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: -1;
        filter: blur(25px);
    }

    .uicss-cn {
        overflow-y: scroll;
        scrollbar-face-color: #888;
        /*滚动长条*/
        scrollbar-shadow-color: #888;
        /*滚动长条  边框*/
        scrollbar-highlight-color: #000;
        /*xxxxxxxxxxx*/
        scrollbar-track-color: #ccc;
        /*背景图*/
        scrollbar-arrow-color: #ccc;
        /*箭头*/
        overflow: -moz-scrollbars-button(#000) !important;
    }

    /*IE用的滑轮*/

    .uicss-cn::-webkit-scrollbar {
        max-width: 10px;
        height: 0
    }

    .uicss-cn::-webkit-scrollbar-button {
        background-color: none
    }

    /*上下按钮*/
    .uicss-cn::-webkit-scrollbar-track {
        background: #ccc
    }

    /*背景颜色*/
    .uicss-cn::-webkit-scrollbar-thumb {
        background: #888;
    }

    /*滑动按钮*/
    .uicss-cn::-webkit-scrollbar-corner {
        background: #82AFFF;
    }

    /*上下的中点交接处*/
    .uicss-cn::-webkit-scrollbar-resizer {
        background: #FF0BEE;
    }

    .serch {
        display: flex;
        width: 100%;
        max-width: 880px;
        margin: auto;
        margin-top: 15px;

        input {
            flex: 1;
            border: none;
            box-shadow: 0 0 15px #cbcbcb;
            text-indent: 16px;
            background: rgba(255, 255, 255, 0.62);
        }

        button {
            padding: 7px 20px;
            border: none;
            background: #000;
            color: #fff;
        }
    }

    .musBox {
        display: flex;

        .musLeft {
            width: 200px;
            height: calc(100vh - 85px);
            margin: 15px;
            overflow-y: scroll;
            background: #0000004f;

            ol {
                list-style: none;
                padding-left: 10px;

                li {
                    margin: 10px 0;

                    &:nth-child(1) {
                        display: table-column;
                    }

                    a {
                        text-decoration: none;
                        color: #fff;
                    }

                    abbr {
                        float: right;
                        margin-right: 20px;
                        img{
                            height: 10px;
                        }
                    }
                }
            }
        }

        .musRight {
            flex: 1;
            display: flex;
            align-content: space-between;
            justify-content: space-around;
            flex-direction: column;

            .fmImg {
                flex: 3;
                display: flex;
                justify-content: center;
                align-items: center;
                img{
                    width: 300px;
                        border-radius: 500px;
                        border: 1px solid rgba(0, 0, 0, 0.29);
                }
            }

            audio {
                width: 100%;
                bottom: 0;
                align-self: flex-end;
                margin-bottom: 16px;
                background: #f1f3f4;
            }
        }
    }
    
    .mvbox {
        position: fixed;
        top: 0;
        width: 100%;
        overflow: hidden;
        height: 100%;
    
        video {
            height: 50vh;
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }
        div{
            width: 100%;
            height: 100%;
            overflow: hidden;
            background: rgba(0, 0, 0, 0.6);
        }
    }
</style>

本地打开, 添加一个vue.config.js
里面写

module.exports = {
   publicPath:  './',
}

这样本地就可以完美的使用了


赵不悔
96 声望4 粉丝

我以为租来的人生也能幸福…要不是幸福终究有个期限,我也就信了。


引用和评论

0 条评论