vue-music(Vue3.0项目——打造企业级音乐App(一)Tab栏、轮播图、歌单列表、滚动组件)
导读:系列文章目录 内容 参考链接 Vue3.0 项目启动 Vue3.0 项目启动(打造企业级音乐App) Vue3.0项目——打造企业级音乐App(一) Tab栏、轮播图、歌单列表、滚动组件...
系列文章目录
内容 参考链接 Vue3.0 项目启动 Vue3.0 项目启动(打造企业级音乐App) Vue3.0项目——打造企业级音乐App(一) Tab栏 、轮播图 、歌单列表 、滚动组件 Vue3.0项目——打造企业级音乐App(二) 图片懒加载 、v-loading指令的开发和优化项目演示
vue3.0-music
设置移动端限制
该项目为移动端的项目 ,我们要设置缩放比例为 1 ,并且禁止用户双击缩放 。
引入全局样式文件
在 main.js 中引入样式文件
import @/assets/scss/index.scssTab 组件实现
总体效果图:
header.vue 组件
设置头部组件的内容 ,样式 两个 icon ,一个名字 <template> <div class="header"> <span class="icon"></span> <h1 class="text">Joyful Music</h1> <router-link class="mine" to="/user"> <i class="icon-mine"></i> </router-link> </div> </template> <script> export default { name: m-header } </script> <style lang="scss" scoped>...</style>tab 组件
<template> <div class="tab"> <router-link class="tab-item" v-for="tab in tabs" :key="tab.path" :to="tab.path" > <span class="tab-link"> {{tab.name}} </span> </router-link> </div> </template> <script> export default { name: tab, data() { return { tabs: [ { name: 推荐, path: /recommend }, { name: 歌手, path: /singer }, { name: 排行, path: /top-list }, { name: 搜索, path: /search } ] } } } </script> <style lang="scss" scoped>...</style>App.vue 组件
<template> <m-header></m-header> <tab></tab> <router-view></router-view> </template> <script> import Header from @/components/header/header.vue import Tab from @/components/tab/tab.vue export default { components: { MHeader: Header, Tab } } </script> <style lang="scss"></style>./router/index.js 文件
import { createRouter, createWebHashHistory } from vue-router import Recommend from @/views/recommend import Singer from @/views/singer import TopList from @/views/top-list import Search from @/views/search const routes = [ { path: /, redirect: /recommend // 重定向 }, { path: /recommend, component: Recommend }, { path: /singer, component: Singer }, { path: /top-list, component: TopList }, { path: /search, component: Search } ] const router = createRouter({ history: createWebHashHistory(), routes }) export default router获取轮播图接口数据
./server/base.js 文件
封装 axios import axios from axios const ERR_OK = 0 // 开发环境下这样定义baseURL const baseURL = / axios.defaults.baseURL = baseURL export function get(url, params) { return axios.get(url, { params }).then((res) => { const serverData = res.data if (serverData.code === ERR_OK) { return serverData.result } }).catch((e) => { console.log(e) }) }./server/recommend.js 文件
获取轮播图接口 ./base 里面是后端的一些配置 import { get } from ./base export function getRecommend() { return get(/api/getRecommend) }recommend.vue 组件
把刚刚的轮播图文件导入进来 async await 异步处理 ,打印获取的结果 <template> <div class="recommend"> 推荐页面 </div> </template> <script> import { getRecommend } from @/service/recommend export default { name: recommend, async created() { const result = await getRecommend() console.log(result) } } </script>推荐页轮播图
轮播图效果使用的是 BetterScroll 2.0 参考链接
./base/slider/use-slider.js 文件
导入轮播图核心滚动和滑动栏 定义滑动栏和当前页 new BScroll() 可以接收多个参数 ,第二个参数可以是对象的形式 ,里面添加多个参数 import BScroll from @better-scroll/core import Slide from @better-scroll/slide import { onMounted, onUnmounted, ref } from vue BScroll.use(Slide) export default function useSlider(wrapperRef) { const slider = ref(null) const currentPageIndex = ref(0) onMounted(() => { const sliderVal = slider.value = new BScroll(wrapperRef.value, { click: true, scrollX: true, // 横向滚动 scrollY: false, momentum: false, // 避免惯性动画带来的快速滚动时的闪烁的问题和快速滑动时一次滚动多页的问题 bounce: false, // 避免在循环衔接的时候出现闪烁 probeType: 2, // 在用户拖动 slide 时 ,实时获取到 slide 的 PageIndex 的改变 ,需要设置为 2 or 3 slide: true }) sliderVal.on(slideWillChange, (page) => { currentPageIndex.value = page.pageX }) }) // 销毁 onUnmounted(() => { slider.value.destroy() }) return { slider, currentPageIndex } }./component/base/slider/slider.vue 组件
渲染图片和滚动条 <template> <div class="slider" ref="rootRef"> <div class="slider-group"> <div class="slider-page" v-for="item in sliders" :key="item.id" > <a :href="item.link"> <img :src="item.pic"/> </a> </div> </div> <div class="dots-wrapper"> <span class="dot" v-for="(item, index) in sliders" :key="item.id" :class="{active: currentPageIndex === index}"> </span> </div> </div> </template> <script> import { ref } from vue import useSlider from ./use-slider export default { name: slider, props: { sliders: { type: Array, default() { return [] } } }, setup() { const rootRef = ref(null) const { currentPageIndex } = useSlider(rootRef) useSlider(rootRef) return { rootRef, currentPageIndex } } } </script> <style lang="scss" scoped>...</style>./views/recommend.vue 组件
获取数据,绑定到推荐页面上 <template> <div class="recommend"> <div class="slider-warpper"> <div class="slider-content"> <slider v-if="sliders.length" :sliders="sliders"></slider> </div> </div> </div> </template> <script> import { getRecommend } from @/service/recommend import Slider from @/components/base/slider/slider export default { name: recommend, components: { Slider }, data() { return { sliders: [] } }, async created() { const result = await getRecommend() // 拿到数据 this.sliders = result.sliders } } </script>歌单列表实现 & 滚动组件(可回弹)
效果图如下:
./components/scroll/use-scroll.js 文件
observe-dom 插件特性:
针对改变频繁的 CSS 属性 ,增加 debounce 如果改变发生在 scroll 动画过程中 ,则不会触发 refresh import BScroll from @better-scroll/core import ObserveDOM from @better-scroll/observe-dom import { onMounted, onUnmounted, ref } from vue BScroll.use(ObserveDOM) export default function useScroll(warpperRef, options) { const scroll = ref(null) onMounted(() => { scroll.value = new BScroll(warpperRef.value, { observeDOM: true, ...options }) }) onUnmounted(() => { scroll.value.destroy() }) }./component/scroll/scroll.vue 组件
滚动组件使用封装的 js 文件 给 setup 传入默认行为 <template> <div ref="rootRef"> <slot></slot> </div> </template> <script> import useScroll from ./use-scroll import { ref } from vue export default { name: scroll, // 组件的默认行为 props: { click: { type: Boolean, default: true } }, setup(props) { const rootRef = ref(null) useScroll(rootRef, props) return { rootRef } } } </script>./views/recommend.vue 组件
<template> <div class="recommend"> <scroll class="recommend-content"> <div> <div class="slider-wrapper"> <div class="slider-content"> <slider v-if="sliders.length" :sliders="sliders"></slider> </div> </div> <div class="recommend-list"> <h1 class="list-title">热门歌单推荐</h1> <ul> <li v-for="item in albums" class="item" :key="item.id" > <div class="icon"> <img width="60" height="60" :src="item.pic"> </div> <div class="text"> <h2 class="name"> {{ item.username }} </h2> <p class="title"> {{item.title}} </p> </div> </li> </ul> </div> </div> </scroll> </div> </template> <script> import { getRecommend } from @/service/recommend import Slider from @/components/base/slider/slider import Scroll from @/components/base/scroll/scroll export default { name: recommend, components: { Slider, Scroll }, data() { return { sliders: [], albums: [] } }, async created () { const result = await getRecommend() this.sliders = result.sliders this.albums = result.albums } } </script>不积跬步无以至千里 不积小流无以成江海
点个关注不迷路,持续更新中…
声明:本站所有文章 ,如无特殊说明或标注 ,均为本站原创发布 。任何个人或组织,在未征得本站同意时 ,禁止复制 、盗用 、采集 、发布本站内容到任何网站 、书籍等各类媒体平台 。如若本站内容侵犯了原著者的合法权益 ,可联系我们进行处理 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!