尚品汇项目复盘(四)

简介: 尚品汇项目复盘(四)

接上文

(十四)封装mock使用虚拟数据

14.1 引入mockjs

yarn add mockjs

14.2新建文件夹

在目录中新建一个mock文件夹

json文件中 写入自己想要模拟实现的数据

mockServe中的内容为

// 先引入mockjs模块
import Mock from 'mockjs'
// 引入.json数据 json数据可以不用对外暴漏但是可以直接引入
// 原因 webpack默认对外暴漏图片和JSON数据
import banner from './banner.json'
import floor from './floor.json'

// mock数据: 第一个参数请求地址 第二个参数是请求数据{data{code:200 //代表请求成功}}
Mock.mock('/mock/banner',{code:200,data:banner})
Mock.mock('/mock/floor',{code:200,data:floor})
// 之后在入口文件引入使执行

之后就是在api文件夹中 新建一个mock的axios 请求

// 对axios二次封装
import axios from 'axios'
// 引入进度条
import nprogress from 'nprogress'
// 引入进度条样式
import "nprogress/nprogress.css"

const mockrequests = axios.create({
  // 配置对象
  // 基础路径,发送请求的时候,路径当众会出现api
  baseURL:'/mock',
  timeout:5000
})

// 添加请求拦截器
mockrequests.interceptors.request.use(function (config) {
  // 在发送请求之前做些什么
  //引入进度条
  nprogress.start()
  return config;
}, function (error) {
  // 对请求错误做些什么
  return Promise.reject(error);
});

// 添加响应拦截器
mockrequests.interceptors.response.use(function (response) {
  // 2xx 范围内的状态码都会触发该函数。
  // 对响应数据做点什么
  // 进度条结束
  nprogress.done()
  return response.data;
}, function (error) {
  // 超出 2xx 范围的状态码都会触发该函数。
  // 对响应错误做点什么
  return Promise.reject(error);
});

//导出
export default mockrequests

之后就可以像一个后台发送来的接口一样 可以正常使用了

(十五)swiper的使用

想要使用swiper需要完成以下四部

(1)安装swiper

(2)在需要使用轮播图的组件内导入swpier和它的css样式

(3)在组件中创建swiper需要的dom标签(html代码,参考官网代码)

(4)创建swiper实例


注意:在创建swiper对象时,我们会传递一个参数用于获取展示轮播图的DOM元素,官网直接通过class(而且这个class不能修改,是swiper的css文件自带的)获取。但是这样有缺点:当页面中有多个轮播图时,因为它们使用了相同的class修饰的DOM,就会出现所有的swiper使用同样的数据,这肯定不是我们希望看到的。

解决方法:在轮播图最外层DOM中添加ref属性


通过ref属性值获取DOM let mySwiper = new Swiper(this.$refs.cur,{...})

         <!--banner轮播-->
        <div class="swiper-container" id="mySwiper" ref="cur">

          <div class="swiper-wrapper">
            <div class="swiper-slide" v-for="(carouse,index) in bannerList" :key="carouse.id">
              <img :src="carouse.imgUrl" />
            </div>
          </div>

          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>

          <!-- 如果需要导航按钮 -->
          <div class="swiper-button-prev" ></div>
          <div class="swiper-button-next"></div>
        </div>
    <script>
    //引入Swiper
    import Swiper from 'swiper'
    //引入Swiper样式
    import 'swiper/css/swiper.css'
    </script>

接下来要考虑的是什么时候去加载这个swiper,我们第一时间想到的是在mounted中创建这个实例。

但是会出现无法加载轮播图片的问题。

原因:


我们在mounted中先去异步请求了轮播图数据,然后又创建的swiper实例。由于请求数据是异步的,所以浏览器不会等待该请求执行完再去创建swiper,而是先创建了swiper实例,但是此时我们的轮播图数据还没有获得,就导致了轮播图展示失败。

mounted() {
  //请求数据
    this.$store.dispatch("getBannerList")
    //创建swiper实例
    let mySwiper = new Swiper(document.getElementsByClassName("swiper-container"),{
        pagination:{
          el: '.swiper-pagination',
          clickable: true,
        },
        // 如果需要前进后退按钮
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
        // 如果需要滚动条
        scrollbar: {
          el: '.swiper-scrollbar',
        },
      })
  },

解决方法一:等我们的数据请求完毕后再创建swiper实例。只需要加一个1000ms时间延迟再创建swiper实例.。将上面代码改为:

mounted() {
    this.$store.dispatch("getBannerList")
    setTimeout(()=>{
      let mySwiper = new Swiper(document.getElementsByClassName("swiper-container"),{
        pagination:{
          el: '.swiper-pagination',
          clickable: true,
        },
        // 如果需要前进后退按钮
        navigation: {
          nextEl: '.swiper-button-next',
          prevEl: '.swiper-button-prev',
        },
        // 如果需要滚动条
        scrollbar: {
          el: '.swiper-scrollbar',
        },
      })
    },1000)
  },

方法一肯定不是最好的,但是我们开发的第一要义就是实现功能,之后再完善。

解决方法二:我们可以使用watch监听bannerList轮播图列表属性,因为bannerList初始值为空,当它有数据时,我们就可以创建swiper对象

watch:{
    bannerList(newValue,oldValue){
        let mySwiper = new Swiper(this.$refs.cur,{
          pagination:{
            el: '.swiper-pagination',
            clickable: true,
          },
          // 如果需要前进后退按钮
          navigation: {
            nextEl: '.swiper-button-next',
            prevEl: '.swiper-button-prev',
          },
          // 如果需要滚动条
          scrollbar: {
            el: '.swiper-scrollbar',
          },
        })
    }
  } 

即使这样也还是无法实现轮播图,原因是,我们轮播图的html中有v-for的循环,我们是通过v-for遍历bannerList中的图片数据,然后展示。我们的watch只能保证在bannerList变化时创建swiper对象,但是并不能保证此时v-for已经执行完了。假如watch先监听到bannerList数据变化,执行回调函数创建了swiper对象,之后v-for才执行,这样也是无法渲染轮播图图片(因为swiper对象生效的前提是html即dom结构已经渲染好了)。


完美解决方案:使用watch+this.$nextTick()

官方介绍:this. $nextTick它会将回调延迟到下次 DOM 更新循环之后执行(循环就是这里的v-for)。

个人理解:无非是等我们页面中的结构都有了再去执行回调函数


完整代码

<template>
  <!--列表-->
  <div class="list-container">
    <div class="sortList clearfix">
      <div class="center">
        <!--banner轮播-->
        <div class="swiper-container" id="mySwiper">

          <div class="swiper-wrapper">
            <div class="swiper-slide" v-for="(carouse,index) in bannerList" :key="carouse.id">
              <img :src="carouse.imgUrl" />
            </div>
          </div>

          <!-- 如果需要分页器 -->
          <div class="swiper-pagination"></div>

          <!-- 如果需要导航按钮 -->
          <div class="swiper-button-prev" ></div>
          <div class="swiper-button-next"></div>
        </div>
      </div>
      </div>
    </div>
  </div>
</template>
<script>
//引入Swiper
import Swiper from 'swiper'
//引入Swiper样式
import 'swiper/css/swiper.css'
import {mapState} from "vuex";
export default {
  name: "index",
  //主键挂载完毕,ajax请求轮播图图片
  mounted() {
    this.$store.dispatch("getBannerList")
  },
  computed:{
    ...mapState({
    //从仓库中获取轮播图数据
      bannerList: (state) => {return state.home.bannerList}
    })
  },
  watch:{
    bannerList(newValue,oldValue){
        //this.$nextTick()使用
        this.$nextTick(()=>{
          let mySwiper = new Swiper(document.getElementsByClassName("swiper-container"),{
            pagination:{
              el: '.swiper-pagination',
              clickable: true,
            },
            // 如果需要前进后退按钮
            navigation: {
              nextEl: '.swiper-button-next',
              prevEl: '.swiper-button-prev',
            },
            // 如果需要滚动条
            scrollbar: {
              el: '.swiper-scrollbar',
            },
          })
        })
    }
  }
}
</script>

注意:之前我们在学习watch时,一般都是监听的定义在data中的属性,但是我们这里是监听的computed中的属性,这样也是完全可以的,并且如果你的业务数据也是从store中通过computed动态获取的,也需要watch监听数据变化执行相应回调函数,完全可以模仿上面的写法。

转载自:https://blog.csdn.net/weixin_43424325/article/details/121684101


目录
相关文章
|
JSON 前端开发 JavaScript
【Element-UI】Mockjs及案例首页导航、左侧菜单
Mock.js是一个用于生成模拟数据的JavaScript库。它能够模拟后端API接口,用于前端开发时进行接口调试和测试提高自动化测试效率。使用Mock.js可以快速创建虚拟的数据,并且可以设置数据的类型、格式和规则,从而模拟真实的数据响应。Mock.js支持生成随机数据拦截Ajax请求以返回模拟数据支持RESTful API风格等功能,能够提高前端开发效率,并且减少对后端接口的依赖。支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。
|
11月前
|
缓存 前端开发 Java
SpringBoot 实现动态菜单功能完整指南
本文介绍了一个动态菜单系统的实现方案,涵盖数据库设计、SpringBoot后端实现、Vue前端展示及权限控制等内容,适用于中后台系统的权限管理。
1139 1
|
消息中间件 存储 安全
对象存储OSS产品常见问题之使用中上传图片慢如何解决
对象存储OSS是基于互联网的数据存储服务模式,让用户可以安全、可靠地存储大量非结构化数据,如图片、音频、视频、文档等任意类型文件,并通过简单的基于HTTP/HTTPS协议的RESTful API接口进行访问和管理。本帖梳理了用户在实际使用中可能遇到的各种常见问题,涵盖了基础操作、性能优化、安全设置、费用管理、数据备份与恢复、跨区域同步、API接口调用等多个方面。
3625 0
|
SQL 前端开发 测试技术
谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)-1
谷粒商城--SPU和SKU(属性分组、规格参数、销售属性)
1006 0
|
Web App开发
vscode如何设置默认打开的浏览器为Chrome(vscode设置默认打开的浏览器为Chrome为什么不还是用其他浏览器打开)
vscode如何设置默认打开的浏览器为Chrome(vscode设置默认打开的浏览器为Chrome为什么不还是用其他浏览器打开)
2738 0
|
14天前
|
人工智能 自然语言处理 文字识别
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
Qwen3.7-Max是阿里云百炼面向智能体时代推出的新一代旗舰模型,对标GPT-5.5、Claude Opus 4.7等闭源旗舰。该模型支持百万级token上下文窗口,具备顶级推理能力、多模态搜索与视觉理解增强、流式输出低延迟响应等核心优势,覆盖编程、办公、长周期自主执行等复杂场景。同时支持OpenAI接口兼容,便于系统快速迁移。用户可通过Token Plan团队或节省计划等订阅方式灵活调用,适合企业级高要求场景使用。
5585 28
阿里云百炼Qwen3.7-Max简介:能力、优势、支持订阅计划参考
|
9天前
|
存储 定位技术 数据库
CodeGraph 如何让 Claude Code减少 7 成工具调用?
CodeGraph 为 Coding Agent 提供本地代码知识图谱,把函数、类、调用链和框架路由提前整理成“项目地图”,减少盲目搜索和文件读取。它不是新 Agent,而是上下文基础设施,让 Agent 更快找到正确代码路径,平均减少 7 成工具调用。
1134 2