20.获取Banner轮播图的数据
修改代码:
src/api目录下新建mockAjax.js文件
//对axios二次封装
import axios from "axios";
import nprogress from "nprogress";
//如果出现进度条没有显示:一定是你忘记了引入样式了
import "nprogress/nprogress.css";
//1、利用axios对象的vreate,区创建一个axios实例
//2.:request就是axios,只不过稍微配置一下
const requests = axios.create({
//基础路径,requests发出的请求的时候,路径当中会出现api
baseURL:'/mock',
//代表请求超时的时间5s
timeout: 5000,
})
//3、配置请求拦截器,在发请求之前,请求拦截器可以检测到,可以在请求发出去之前做一些事情
requests.interceptors.request.use(config => {
//进度条开始
nprogress.start();
//config:配置对象,对象里面有一个属性很重要,Header请求头
return config;
})
//4、配置响应拦截器
requests.interceptors.response.use((res) => {
//成功的回调函数
//进度条结束
nprogress.done();
return res.data;
},(error) => {
//失败的回调函数
console.log("响应失败"+error)
return Promise.reject(new Error('fail'))
})
//5、对外暴露
export default requests;
在src/api/index.js中对外暴露mockjs的方法
import mockRequests from "@/api/mockAjax"
//获取banner(Home首页轮播图接口)
export const mockGetBannerList = ()=> mockRequests.get("/banner")
在src/store/home/index.js补充查询轮播图数据的结构
import {getCategoryList, mockGetBannerList} from '@/api'
//Home模块的小仓库
//actions代表一系列动作,可以书写自己的业务逻辑,也可以处理异步
const actions = {
//获取首页轮播图的数据
async mockGetBannerList(context) {
let response = await mockGetBannerList();
if (response.code == 200) {
context.commit("MOCK_GET_BANNER_LIST", response.data)
}
}
}
//mutations代表维护,操作维护的是state中的数据,且state中数据只能在mutations中处理
const mutations = {
MOCK_GET_BANNER_LIST(state, bannerList) {
state.bannerList = bannerList
}
}
//state代表仓库中的数据
const state = {
//轮播图的数据
bannerList: []
}
在src/pages/Home/ListContainer/index.vue补充触发调用
import { mapState } from "vuex";
mounted() {
//mounted:组件挂载完毕,正常说组件结构(DOM)已经全有了
this.$store.dispatch("mockGetBannerList")
},
computed: {
...mapState({bannerList : state => state.home.bannerList})
}
21.使用swiper轮播图插件
安装命令:cnpm install --save swiper
修改代码如下:
src/pages/Home/ListContainer/index.vue
<!--banner轮播-->
<div class="swiper-container" ref="mySwiper">
<div class="swiper-wrapper">
<div class="swiper-slide" v-for="carousel in bannerList" :key="carousel.id">
<img :src="carousel.imgUrl"/>
</div>
</div>
<!-- 如果需要分页器 -->
<div class="swiper-pagination"></div>
<!-- 如果需要导航按钮 -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
</div>
import Swiper from "swiper"
watch: {
//方式2:watch + nextTick
bannerList: {
handler(newValue, oldValue) {
this.$nextTick(() => {
var mySwiper = new Swiper('.swiper-container', {
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
clickable: true, //此参数设置为true时,点击分页器的指示点分页器会控制Swiper切换。
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// 如果需要滚动条
scrollbar: {
el: '.swiper-scrollbar',
},
})
});
}
}
}
src/main.js
//引入swiper样式
import "swiper/css/swiper.css"
Swiper插件使用步骤:
- 引入swiper包
- 引入css样式
- 准备dom结构
- 实例化swiper
swiper用于前端或者android,用于展示轮播图的一款插件。
swiper官网:https://www.swiper.com.cn/
注意点0
:版本兼容
vue版本 | swiper版本 |
---|---|
vue2 | swiper6及以下版本 |
vue3 | swiper7、8版本 |
注意点1
:使用swiper插件时,初始化swiper前页面结构div啥的必须存在,即先存在页面结构div节点然后才能初始化swiper。
注意点2
:初始化swiper的第一个参数,可以是字符串也可以是真实DOM节点
方式1:class类的字符串
var mySwiper = new Swiper ('.swiper', {})
方式2:真实DOM节点
var mySwiper = new Swiper (this.$refs.swiper, {})
注意点3
:页面结构中的class类名不能随意瞎改,改了就不认识就没有效果了。
注意点4
:
问题:我vue2项目安装的swiper7版本,引入css的时候报错:swiper7 ./swiper-.min.css is not exported from package
答案:请查看node_modules/swiper/路径下压根没有swiper-.min.css,所以导致报错不存在该文件,原因在于vue2最高只能安装swiper6版本,swiper7是vue3适配的,所以重新安装swiper6版本或者swiper5版本就可以解决问题。
注意点5
:
问题:轮播图结构在ListContainer组件中,在mounted中实例化swiper或者watch监听bannerList触发实例化swiper时,发现轮播图不动,且图片下方没有原点
答案
:swiper实例化不能放在mounted中或者watch监听器中,因为/
那么修改方案有2种:
(1)第一种方案:实例化swiper放在update()中
,缺点是:如果update()中方法使用了data中数据,那么每次data数据改变,就会实例化swiper一次,这明显不靠谱。
update() {
var mySwiper = new Swiper ('.swiper-container', {
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
clickable: true, //此参数设置为true时,点击分页器的指示点分页器会控制Swiper切换。
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// 如果需要滚动条
scrollbar: {
el: '.swiper-scrollbar',
},
})
}
(2)第二种方案:放在mounted()中写个定时器实例化swiper
,缺点是:图片下方的小球会在1秒后才刷新出来。
注意:定时器setTimeout()是规定时间后执行一次,而setInterval()方法是时间间隔重复执行n次,别用混了!
mounted() {
//因为dispatch当中涉及到异步语句,导致v-for遍历的时候结构还没完全因此不行
setTimeout(()=>{
var mySwiper = new Swiper ('.swiper-container', {
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
clickable: true, //此参数设置为true时,点击分页器的指示点分页器会控制Swiper切换。
},
// 如果需要前进后退按钮
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev',
},
// 如果需要滚动条
scrollbar: {
el: '.swiper-scrollbar',
},
})
}, 1000)
}
(3)方案3:最完美的解决方案:watch+nextTick 数据监听+监听已有数据变化
nextTick:在下次DOM更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的DOM。
注意点6
:
问题:引入swiper包是在ListContainer组件中引入的,为啥引入swiper的CSS样式却放在了main.js中?
答案
:因为这个CSS的样式不仅在ListContainer组件中使用,还在Floor组件中使用,所以放在main.js中只需加载一次即可,其他组件就都可以使用了,避免重复引入多次。
本人其他相关文章链接
1.vue尚品汇商城项目-day03【16.开发Search组件模块中的TypeNav商品分类菜单(过渡动画效果)+17.(优化)针对三级菜单联动进行优化,优化方向为减少查询】
2.vue尚品汇商城项目-day03【18.合并params和query参数(Header组件+TypeNav组件)】
3.vue尚品汇商城项目-day03【vue插件-19.mockjs模拟数据(开发Home首页当中的ListContainer组件与Floor组件)】
4.vue尚品汇商城项目-day03【20.获取Banner轮播图的数据+21.使用swiper轮播图插件】
5.vue尚品汇商城项目-day03【22.开发Floor组件】