Xây dựng ứng dụng nghe nhạc với Vue.js

Mục lục

  • Ghi chú học Vue 01 - Nền tảng Vue
  • Ghi chú học Vue 02 - Thành phần Vue
  • Ghi chú học Vue 03 - Axios
  • Ghi chú học Vue 04 - Định tuyến Vue
  • Ghi chú học Vue 05 - Ví dụ H5 ứng dụng âm nhạc
  • Ghi chú học Vue 06 - Vuex
  • Ghi chú học Vue 07 - Ví dụ cửa hàng Web

Ứng dụng Vue

25. Ứng dụng Vue - Danh sách nhạc

Ví dụ: src/route.js

import Vue from 'vue'
import VueRouter from "vue-router"
import TrangChu from "../pages/trangChu" 
import ThanhDieuHuong from "../pages/thanhDieuHuong" 
import NhacHot from "../pages/danhSachNhac/NhacHot"
import NhacMoi from "../pages/danhSachNhac/NhacMoi"
import NhacKing from "../pages/danhSachNhac/NhacKing"

Vue.use(VueRouter);

export default new VueRouter({
    routes: [
        { path: '/', name: 'TrangChu', component: TrangChu, redirect: 'NhacHot', 
            children: [
                 { path: 'hot', name: 'NhacHot', component: NhacHot},
                 { path: 'new', name: 'NhacMoi', component: NhacMoi},
                 { path: 'king', name: 'NhacKing', component: NhacKing},
         ]},
    ]
});

src/main.js

import Vue from 'vue'
import App from './App'
import Axios from 'axios'
import router from './router'

Vue.prototype.$axios = Axios;  
Vue.prototype.HOST = '/api'

Vue.config.productionTip = false 

new Vue({
  el: '#app', 
  router,
  components: { App }, 
  template: '<App/>' 
})

src/App.vue

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
     
    }
  },
  components: {
    TrangChu
  }
}
</script>

<style>
</style>

Lưu ý: Trong App.vue nên sử dụng định tuyến để引入, nếu dùng cách引入 thành phần sẽ dẫn đến hiển thị hai lần.

src/pages/trangChu.vue

<template>
    <div class="container">
        <router-view/>
    </div>
</template>
<script>
import ThanhDieuHuong from './thanhDieuHuong'
export default {
    name: 'trangChu',
    data() {
        return {

        }
    },
    components:{
        ThanhDieuHuong
    }
}
</script>
<style>
</style>

src/pages/thanhDieuHuong.vue

<template>
    <div class="musicnav">
        <div class="bars">
            <router-link to="/nhac/hot">Bài hát hot</router-link>
            <router-link to="/nhac/new">Bài hát mới</router-link>
            <router-link to="/nhac/king">Bảng xếp hạng King</router-link>
         </div> 
        <router-view/>
    </div>
</template>
<script>
export default {
    name: 'thanhDieuHuong',
    data() {
        return {
        }
    },
}
</script>
<style>
    ul.danhSachBaiHat{
        padding: 10px;
    }
    li.baiHat {
        list-style: none;
    }
    li.baiHat div.hinhAnh {
        clear: both;
        float: left;
        margin-right: 10px;
    }
    li.baiHat img {
        width: 40px;
        height: 40px;
    }
</style>

Thành phần: src/components/danhSachNhac.vue

<template>
    <div class="danhSachNhac">
        <div class="panel">
            <ul class="danhSachBaiHat">
                <li class="baiHat" v-bind:key="index" v-for="(baiHat,index) in danhSachBaiHat">
                    <div class="hinhAnh"><img v-bind:src="baiHat.pic_small"/></div>
                    <div class="thongTin"><div class="ten">{{ baiHat.title }}</div><div class="caSi">{{ baiHat.author }}</div></div>
                </li>
            </ul>
        </div>
    </div>
</template>
<script>
export default {
    name: 'danhSachNhac',
    props: {
        loaiNhac: { type: String, default: "1"},
    },
    data() {
        return {
            danhSachBaiHat: []
        }
    },
    created() {
        var url = this.HOST + '/v1/restserver/ting';
        this.$axios.get(url+'?method=baidu.ting.billboard.billList&type='+this.loaiNhac+'&size=10&offset=0')
        .then(res=>{this.danhSachBaiHat=res.data.song_list})
        .catch(error=>{console.log(error)})
    }
}
</script>
<style scoped>
    ul.danhSachBaiHat{
        padding: 10px;
    }
    li.baiHat {
        list-style: none;
    }
    li.baiHat div.hinhAnh {
        clear: both;
        float: left;
        margin-right: 10px;
    }
    li.baiHat img {
        width: 40px;
        height: 40px;
    }
</style>

src/pages/danhSachNhac/NhacHot.vue

<template>
    <div class="hot">
        <DanhSachNhac loaiNhac="1"/>
    </div>
</template>
<script>
import DanhSachNhac from "../../components/danhSachNhac"
export default {
    name: 'hot',
    data() {
        return {
        }
    },
    components: {
        DanhSachNhac
    }
}
</script>
<style>

</style>

src/pages/danhSachNhac/NhacMoi.vue

<template>
    <div class="new">
        <DanhSachNhac loaiNhac="11"/>
    </div>
</template>
<script>
import DanhSachNhac from "../../components/danhSachNhac"
export default {
    name: 'new',
    data() {
        return {
        }
    },
    components: {
        DanhSachNhac
    }
}
</script>
<style>

</style>

src/pages/danhSachNhac/NhacKing.vue

<template>
    <div class="king">
        <DanhSachNhac loaiNhac="2"/>
    </div>
</template>
<script>
import DanhSachNhac from "../../components/danhSachNhac"
export default {
    name: 'king',
    data() {
        return {
        }
    },
    components: {
        DanhSachNhac
    }
}
</script>
<style>

</style>

26. Ứng dụng Vue - Thông tin ca sĩ

Ý tưởng: Thẻ ca sĩ là một thành phần, trang web sử dụng thành phần này, mảng cố định lưu trữ ID ca sĩ

(1) Thêm định tuyến trong src/router/index.js

import Vue from 'vue'
import VueRouter from "vue-router"
import TrangChu from "../pages/trangChu" 
import ThanhDieuHuong from "../pages/thanhDieuHuong" 
import NhacHot from "../pages/danhSachNhac/NhacHot"
import NhacMoi from "../pages/danhSachNhac/NhacMoi"
import NhacKing from "../pages/danhSachNhac/NhacKing"
import ThongTinCaSi from "../pages/ThongTinCaSi/ThongTinCaSi"

Vue.use(VueRouter);

export default new VueRouter({
    routes: [
        { path: '/', name: 'TrangChu', component: TrangChu, redirect: '/hot',
            children: [
                { path: 'hot', name: 'NhacHot', component: NhacHot},
                { path: 'new', name: 'NhacMoi', component: NhacMoi},
                { path: 'king', name: 'NhacKing', component: NhacKing},
        ]}, 
        { path: '/ca-si/:idCaSi', name: 'caSi', component: ThongTinCaSi},
    ]
});

(2) Tạo thành phần src/components/danhSachCaSi.vue

<template>
    <div class="danhSachCaSi">
        <router-link v-bind:to="{name: 'caSi', params: {idCaSi: idCaSi}}" tag="div" class="card">
            <div class="hinhAnh"><img v-bind:src="thongTinCaSi.avatar_middle"/></div>
            <div class="thongTin">{{thongTinCaSi.name}}</div>
        </router-link>
    </div>
</template>
<script>
export default {
    name: "danhSachCaSi",
    props: {
        idCaSi: {type: String, default: "2517"}
    },
    data(){
        return {
            thongTinCaSi: {}
        }
    },
    created(){
        var url = this.HOST + '/v1/restserver/ting?method=baidu.ting.artist.getInfo&tinguid=' + this.idCaSi;
        this.$axios.get(url)
        .then(res=>{this.thongTinCaSi = res.data;})
        .catch(error=>{console.log(error);})
    }
}
</script>

<style scoped>
    div.card {
        float: left;
        margin-left: 8px;
        margin-top: 8px;
    }
    div.card img {
        width: 110px;
        height: 110px;
    }
</style>

(3) Tạo trang mới src/pages/ThongTinCaSi/ThongTinCaSi.vue

<template>
    <div class="thongTinCaSi">
        Danh sách bài hát của ca sĩ
        <BaiHatCaSi/>
    </div>
</template>
<script>
import BaiHatCaSi from "../../components/BaiHatCaSi"
export default {
    name: "thongTinCaSi",
    data(){
        return {}
    },
    components:{
        BaiHatCaSi
    }
}
</script>
<style scoped>

</style>

(4) Tạo trang mới src/pages/TrangCaSi.vue

<template>
    <div class="caSi">
        <div class="">
            <h2>Top ca sĩ</h2>
            <DanhSachCaSi v-bind:key="index" v-for="(item, index) in danhSachCaSi" v-bind:idCaSi="item"/> 
        </div>
    </div>
</template>
<script>
import DanhSachCaSi from '../components/danhSachCaSi'

export default {
    name: "caSi",
    data(){
        return {
            danhSachCaSi: ['2517', '1094', '1052', '45561', '1098', '1202']
        }
    },
    components: {
        DanhSachCaSi,
    }
}
</script>

<style scoped>

</style>

(5) Thêm TrangCaSi vào src/pages/trangChu.vue

<template>
    <div class="container">
        <ThanhDieuHuong/>
        <TrangCaSi/>
    </div>
</template>
<script>
import ThanhDieuHuong from './thanhDieuHuong'
import TrangCaSi from './TrangCaSi'

export default {
    name: 'trangChu',
    data() {
        return {

        }
    },
    components:{
        ThanhDieuHuong, TrangCaSi
    }
}
</script>
<style>
</style>

Cấu trúc dự án hiện tại

27. Ứng dụng Vue - Phát nhạc

Sử dụng iconfont

Cấu trúc dự án

Trang phát nhạc

(1) Thêm định tuyến { path: '/phat-nhac/:idBaiHat', name: 'phatNhac', component: TrangPhatNhac}, src/route/index.js

import Vue from 'vue'
import VueRouter from "vue-router"
import TrangChu from "../pages/trangChu" 
import ThanhDieuHuong from "../pages/thanhDieuHuong" 
import NhacHot from "../pages/danhSachNhac/NhacHot"
import NhacMoi from "../pages/danhSachNhac/NhacMoi"
import NhacKing from "../pages/danhSachNhac/NhacKing"
import ThongTinCaSi from "../pages/ThongTinCaSi/ThongTinCaSi"
import TrangPhatNhac from "../pages/TrangPhatNhac"

Vue.use(VueRouter);

export default new VueRouter({
    routes: [
        { path: '/', name: 'TrangChu', component: TrangChu, redirect: '/hot',
            children: [
                { path: 'hot', name: 'NhacHot', component: NhacHot},
                { path: 'new', name: 'NhacMoi', component: NhacMoi},
                { path: 'king', name: 'NhacKing', component: NhacKing},
        ]}, 
        { path: '/ca-si/:idCaSi', name: 'caSi', component: ThongTinCaSi},
        { path: '/phat-nhac/:idBaiHat', name: 'phatNhac', component: TrangPhatNhac},
    ]
});

(2) Tạo trang phát nhạc src/pages/TrangPhatNhac.vue

<template>
    <div class="trangPhatNhac">
        <h2>{{thongTinBaiHat.songinfo.title}}</h2>
        <div>
            <div class="caSi">{{thongTinBaiHat.songinfo.author}}</div>
            <div class="congTy">{{thongTinBaiHat.songinfo.si_proxycompany}}</div>
            <img v-bind:src="thongTinBaiHat.songinfo.pic_premium"/>
            <audio v-bind:src="thongTinBaiHat.bitrate.file_link" autoplay controls>
            </audio>
        </div>
    </div>
</template>
<script>
export default {
    name: "trangPhatNhac",
    data(){
        return{
            thongTinBaiHat: {
                songinfo: {},
                bitrate: [],
            },
        }
    },
    created(){
        var url = this.HOST + 'v1/restserver/ting?method=baidu.ting.song.play&songid=' + this.$route.params.idBaiHat;
        this.$axios.get(url)
        .then(res=>{this.thongTinBaiHat=res.data;})
        .catch(error=>{console.log(error);})
    }
    
}
</script>
<style scoped>
    div img {
        width: 350px;
        height: 350px;
        margin-left: 5px;
    }
    div audio {
        margin-left: 30px;
    }
</style>

(3) Sửa src/components/danhSachNhac.vue

<template>
    <div class="danhSachNhac">
        <div class="panel">
            <ul class="danhSachBaiHat">
                <router-link v-bind:to="{name: 'phatNhac', params: {idBaiHat: baiHat.song_id}}" tag="li" class="baiHat" v-bind:key="index" v-for="(baiHat,index) in danhSachBaiHat">
                    <div class="hinhAnh"><img v-bind:src="baiHat.pic_small"/></div>
                    <div class="thongTin"><div class="ten">{{ baiHat.title }}</div><div class="caSi">{{ baiHat.author }}</div></div>
                </router-link>
            </ul>
        </div>
    </div>
</template>
<script>
export default {
    name: 'danhSachNhac',
    props: {
        loaiNhac: { type: String, default: "1"},
    },
    data() {
        return {
            danhSachBaiHat: [],
        }
    },
    created() {
        var url = this.HOST + '/v1/restserver/ting';
        this.$axios.get(url+'?method=baidu.ting.billboard.billList&type='+this.loaiNhac+'&size=5&offset=0')
        .then(res=>{this.danhSachBaiHat=res.data.song_list})
        .catch(error=>{console.log(error)})
    }
}
</script>
<style scoped>
    ul.danhSachBaiHat{
        padding: 10px;
    }
    li.baiHat {
        list-style: none;
    }
    li.baiHat div.hinhAnh {
        clear: both;
        float: left;
        margin-right: 10px;
    }
    li.baiHat img {
        width: 40px;
        height: 40px;
    }
</style>

(4) Sửa src/components/BaiHatCaSi.vue

<template>
    <div class="baiHatCaSi">
        <div class="panel">
            <ul class="danhSachBaiHat">
                <router-link v-bind:to="{name: 'phatNhac', params: {idBaiHat: baiHat.song_id}}" tag="li" class="baiHat" v-bind:key="index" v-for="(baiHat,index) in danhSachBaiHat">
                    <div class="hinhAnh"><img v-bind:src="baiHat.pic_small"/></div>
                    <div class="thongTin"><div class="ten">{{ baiHat.title }}</div><div class="caSi">{{ baiHat.author }}</div></div>
                </router-link>
            </ul>
        </div>
    </div>
</template>
<script>
export default {
    name: 'baiHatCaSi',
    props: {
        idCaSi: { type: String, default: "2517"},
    },
    data() {
        return {
            danhSachBaiHat: []
        }
    },
    mounted() {
        var url = this.HOST + '/v1/restserver/ting';
        this.$axios.get(url+'?method=baidu.ting.artist.getSongList&tinguid='+this.$route.params.idCaSi+'&limits=6&use_cluster=1&order=2')
        .then(res=>{this.danhSachBaiHat=res.data.songlist})
        .catch(error=>{console.log(error)})
    }
}
</script>
<style scoped>
    ul.danhSachBaiHat{
        padding: 10px;
    }
    li.baiHat {
        list-style: none;
    }
    li.baiHat div.hinhAnh {
        clear: both;
        float: left;
        margin-right: 10px;
    }
    li.baiHat img {
        width: 40px;
        height: 40px;
    }
</style>

28. Ứng dụng Vue - Phát nhạc và lời bài hát

Sử dụng iconfont

  1. Truy cập trang web iconfont, đăng nhập và chọn biểu tượng, trong giỏ hàng nhấn tải mã về.
  2. Giải nén mã tải về, đổi tên thư mục thành font, đặt trong thư mục src/asserts của dự án
  3. Trong TrangPhatNhac.vue import
import "../assets/font/iconfont.css"
  1. Trong trang sử dụng ```

29. Ứng dụng Vue - Tìm kiếm khám phá

30. Ứng dụng Vue - Tải thêm khi cuộn xuống

31. Ứng dụng Vue - Chờ tải

32. Ứng dụng Vue - Chờ tải


### 29. Ứng dụng Vue - Tìm kiếm khám phá

### 30. Ứng dụng Vue - Tải thêm khi cuộn xuống

### 31. Ứng dụng Vue - Chờ tải

### 32. Ứng dụng Vue - Chờ tải

Thẻ: Vue.js JavaScript Ứng dụng di động Âm nhạc Axios

Đăng vào ngày 27 tháng 6 lúc 13:07