系列文章目录
文章目录
设置移动端限制
该项目为移动端的项目,我们要设置缩放比例为 1,并且禁止用户双击缩放。
引入全局样式文件
在 main.js 中引入样式文件
import'@/assets/scss/index.scss'
Tab 组件实现
总体效果图:
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>exportdefault{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>exportdefault{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'exportdefault{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
})exportdefault router
获取轮播图接口数据
./server/base.js 文件
- 封装 axios
import axios from'axios'constERR_OK=0// 开发环境下这样定义baseURLconst baseURL ='/'
axios.defaults.baseURL = baseURL
exportfunctionget(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'exportfunctiongetRecommend(){returnget('/api/getRecommend')}
recommend.vue 组件
- 把刚刚的轮播图文件导入进来
- async await 异步处理,打印获取的结果
<template><div class="recommend">
推荐页面
</div></template><script>import{ getRecommend }from'@/service/recommend'exportdefault{name:'recommend',asynccreated(){const result =awaitgetRecommend()
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)exportdefaultfunctionuseSlider(wrapperRef){const slider =ref(null)const currentPageIndex =ref(0)onMounted(()=>{const sliderVal = slider.value =newBScroll(wrapperRef.value,{click:true,scrollX:true,// 横向滚动scrollY:false,momentum:false,// 避免惯性动画带来的快速滚动时的闪烁的问题和快速滑动时一次滚动多页的问题bounce:false,// 避免在循环衔接的时候出现闪烁probeType:2,// 在用户拖动 slide 时,实时获取到 slide 的 PageIndex 的改变,需要设置为 2 or 3slide: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'exportdefault{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'exportdefault{name:'recommend',components:{
Slider
},data(){return{sliders:[]}},asynccreated(){const result =awaitgetRecommend()// 拿到数据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)exportdefaultfunctionuseScroll(warpperRef, options){const scroll =ref(null)onMounted(()=>{
scroll.value =newBScroll(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'exportdefault{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'exportdefault{name:'recommend',components:{
Slider,
Scroll
},data(){return{sliders:[],albums:[]}},asynccreated(){const result =awaitgetRecommend()this.sliders = result.sliders
this.albums = result.albums
}}</script>
不积跬步无以至千里 不积小流无以成江海
点个关注不迷路,持续更新中…
版权归原作者 前端杂货铺 所有, 如有侵权,请联系我们删除。