一、安装axios
npm install axios --save
二、请求数据(封装)
在src下创建service文件夹下的base.js用于封装axios
// 导入
import axios from 'axios'
// url路径地址 params可选参数
export function get(url, params) {
return axios.get(url, {
params
}).then(res => {
return res.data // 返回响应的data数据
}).catch(err => {
throw err
})
}
三、自定义轮播组件
1、推荐页
recommend.js
// 推荐页相关的数据
import { get } from './base'
//请求轮播数据
export function getRecommend() {
// 直接定义接口
return get('/banner', {
type: 2
})
}
Recommend.vue(记得异步要加async await)
<script setup>
import { getRecommend } from "@/service/recommend";
import { onMounted, ref } from "vue";
import MySlider from "@/components/base/Slider"
onMounted(() => {
// 调用接口地址
const result = getRecommend();
console.log(result);
})
const sliders = ref([])
onMounted(async () => {
// 调用接口地址
const result = await getRecommend();
console.log(result);
sliders.value = result.banners;
});
</script>
打印结果
> npm install @better-scroll/core --save
> npm install @better-scroll/slide --save
抽离组件功能
在components下面创建base文件夹下面Slider.vue
<template>
<!-- // 封装轮播组件 -->
<div class="slider" ref="rootRef">
<div class="slider-group">
<div class="slider-page" v-for="(item, index) in sliders" :key="index">
<img :src="item.pic" alt="" />
</div>
</div>
<div class="dots-wrapper">
<span
class="dot"
v-for="(item, index) in sliders"
:key="index"
:class="{ active: index === currentIndex }"
></span>
</div>
</div>
</template>
<script setup>
import { useSlider } from "@/assets/js/useSlider";
const props = defineProps({
sliders: {
type: Array,
require: true,
},
}); //Recommend组件传来的数据
const { rootRef, currentIndex } = useSlider();
</script>
<style lang="scss" scoped>
.slider {
min-height: 1px;
font-size: 0;
// 启用单手垂直移动
touch-action: pan-y;
position: relative;
.slider-group {
position: relative;
overflow: hidden;
white-space: nowrap;
.slider-page {
display: inline-block;
transform: translate3d(0, 0, 0);
backface-visibility: hidden;
img {
display: block;
width: 100%;
}
}
}
.dots-wrapper {
position: absolute;
left: 50%;
bottom: 12px;
line-height: 12px;
transform: translateX(-50%);
.dot {
display: inline-block;
margin: 0 4px;
width: 8px;
height: 8px;
transform: translateZ(1px);
border-radius: 50%;
background-color: $color-text-l;
&.active {
width: 20px;
border-radius: 5px;
background: $color-text-ll;
}
}
}
}
</style>
在assets下创建js文件夹下useSlider.js
import BScroll from "@better-scroll/core";
import Slide from "@better-scroll/slide";
import { onActivated, onDeactivated, onMounted, onUnmounted, ref } from "vue";
BScroll.use(Slide)
// 第一个参数元素节点,第二个参数配置项
export function useSlider() {
// 创建slider对象
const slider = ref(null)
const rootRef = ref(null)
const currentIndex = ref(0)
onMounted(() => {
// new BScroll(需要挂载的DOM,配置对象:支持的功能)
slider.value = new BScroll(rootRef.value, {
slide: true,//插件激活
click: true,//允许点击
scrollX: true,//横向滚动
scrollY: false,//不允许纵向滚动
momentum: false,//不根据滑动的距离和时间计算生成滚动动画
bounce: false,//不需要回弹动画
probeType: 2,//派发scroll事件的频率,仅当手指按在滚动区域上,一直派发scroll事件
})
// 页面页码发生变化时触发这个事件
slider.value.on('slideWillChange', (page) => {
currentIndex.value = page.pageX
})
})
// 销毁时
onUnmounted(() => {
slider.value.destroy()
})
// 激活时
onActivated(() => {
slider.value.enable//恢复功能
slider.value.refresh//刷新一下
})
// 失活时
onDeactivated(() => {
slider.value.enable//恢复功能
})
return {
rootRef,
currentIndex
}
}
2、热门歌单推荐
recommend.js
// 推荐页相关的数据接口
import { get } from './base'
//请求热门歌单推荐数据
export function getRecommendAlbum() {
// 直接定义接口
return get('/top/playlist', {
limit: 30
})
}
Recommend.vue
<template>
<div class="recommend">
<my-scroll class="recommend-content">
<div>
<!-- 轮播 -->
<div class="slider-wrapper">
<div class="slider-content">
<my-slider v-if="sliders.length" :sliders="sliders"></my-slider>
</div>
</div>
<!-- 热门歌单推荐 -->
<div class="recommend-list">
<h2 class="list-title">热门歌单推荐</h2>
<ul>
<li
class="recommend-item"
v-for="(item, index) in albums"
:key="item.id"
>
<div class="icon">
<img :src="item.coverImgUrl" width="60" height="60" alt="" />
</div>
<div class="text">
<p class="name">{{ item.name }}</p>
<p class="description">{{ item.description }}</p>
</div>
</li>
</ul>
</div>
</div>
</my-scroll>
</div>
</template>
<script setup>
import { getRecommend, getRecommendAlbum } from "@/service/recommend";
import { onMounted, ref } from "vue";
import MySlider from "@/components/base/Slider";
import MyScroll from "@/components/base/Scroll";
const sliders = ref([]);
const albums = ref([]);
onMounted(async () => {
// 获取轮播数据
// 调用接口地址
const result = await getRecommend();
// console.log(result);
sliders.value = result.banners;
// 获取热门歌单推荐数据
const albumResult = await getRecommendAlbum();
// console.log(albumResult);
albums.value = albumResult.playlists;
});
</script>
<style lang="scss" scoped>
.recommend {
position: fixed;
width: 100%;
top: 88px;
bottom: 0;
overflow: scroll;
.recommend-content {
height: 100%;
overflow: hidden;
.recommend-list {
.list-title {
height: 65px;
line-height: 65px;
text-align: center;
font-size: $font-size-medium;
color: $color-theme;
}
.recommend-item {
display: flex;
box-sizing: border-box;
align-items: center;
padding: 0 20px 20px 20px;
.icon {
flex: 0 0 60px;
width: 60px;
padding-right: 20px;
}
.text {
display: flex;
flex-direction: column;
justify-content: center;
flex: 1;
line-height: 20px;
overflow: hidden;
font-size: $font-size-medium;
}
.name {
margin-bottom: 10px;
color: $color-text-ll;
}
.description {
@include no-wrap();
color: $color-text-d;
}
}
}
}
}
</style>
安装回弹效果并封装
> npm install @better-scroll/observe-dom --save
在assets下js文件夹中创建useScroll.js
import BScroll from '@better-scroll/core'
import ObserveDOM from '@better-scroll/observe-dom'
import { onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'
BScroll.use(ObserveDOM)
export function useScroll(props) {
const rootRef = ref(null)
const scroll = ref(null)
onMounted(() => {
scroll.value = new BScroll(rootRef.value, {
observeDOM: true, //开启observe-dom插件,深度监听
...props
})
// 获取实时滚动距离
// if(props.probType > 0) {
// // 外层时betterscroll对象,自带的
// scroll.value.on('scroll', (pos) => {
// // 触发父组件内的scroll自定义事件
// defineEmits('scroll', pos)
// })
// }
})
onUnmounted(() => {
// 销毁
scroll.value.destroy()
})
onActivated(() => {
// 恢复功能
scroll.value.enable()
// 刷新
scroll.value.refresh()
})
onDeactivated(() => {
// 失去功能
scroll.value.disable()
})
return {
rootRef
}
}
在components下base文件夹中创建Scroll.vue
<template>
<div class="" ref="rootRef">
<slot></slot>
</div>
</template>
<script setup>
import { useScroll } from "@/assets/js/useScroll";
const props = defineProps({
probeType: {
type: Number,
default: 1,
},
});
const { rootRef } = useScroll(props);
</script>
<style lang="scss" scoped>
</style>