• vue前台(四点一)


    一,mockjs模拟banner和floor接口操作,组件获取数据

    1.创建mock文件夹,创建banner.json和floor.json, mockServer.js(提供服务,模拟接口)    安装mockjs  npm  i  mockjs

    mockServer.js 文件内容

    //正儿八经的模拟接口
    import Mock from 'mockjs'
    import banner from './banner.json'  //json数据被引入之后会变为真正的数组,不再是json串了
    import floor from './floor.json'  //json数据被引入之后会变为真正的数组,不再是json串了
    
    //第一个参数,是以后我们要请求的模拟接口路径
    //第二个参数,是访问这个接口后返回的数据
    //   '/mock/banner'   /mock不能省,因为这个并不是去发送ajax请求,
    // 发请求可以省,是因为我们在axios配置了baseUrl
    // 这个不是发请求,是模拟整个接口
    Mock.mock('/mock/banner',{code:200,data:banner})
    Mock.mock('/mock/floor',{code:200,data:floor})
    
    //最后切记在入口文件去引入一下,代表这个文件一开始就会执行

    2.在入口文件main.js导入mock,    

    import '@/mock/mockServer'
     
    3.在 ajax文件夹中新建mockAjax.js, 二次封装关于mock的ajax
     
    mockAjax.js文件内容
    //对axios的二次封装
    // 配置基础路径和超时限制
    // 添加进度条信息  nprogress
    // 返回的响应不再需要从data属性当中拿数据,而是响应就是我们要的数据
    // 统一处理请求错误, 具体请求也可以选择处理或不处理
    import axios from 'axios'
    import NProgress from 'nprogress'
    import 'nprogress/nprogress.css'
    
    
    const service = axios.create({
      baseURL: '/mock',  // 配置基础路径
      timeout: 20000,  //和超时限制
    });
    
    
    //请求拦截器
    //请求拦截器内部一般不会处理错误的信息
    service.interceptors.request.use(config => {
      //config是发送请求的配置对象,必须处理完返回这个配置对象
      //开启我们的进度条
      NProgress.start()
      return config
    });
    // 响应拦截器
    service.interceptors.response.use(
      response => {
        //停止进度条
        NProgress.done()
        //返回响应的时候,直接返回响应的data
        return response.data
      },
      error => {
    
        NProgress.done()
    
        alert('请求出错' + error.message || '未知错误')
        //以后不允许用户继续处理: 中断promise链
        return new Promise(() => {}) //返回pending状态的promise 中断
        //以后它允许用户继续对错误进行处理
        // return Promise.reject(error)
      }
    );
    
    
    export default service

    4.在api---index.js中,使用mock的接口去请求 banner数据 

    引入二次封装的ajax;    import mockAjax from '@/ajax/mockAjax'

    // 使用mock的接口去请求 banner数据   get 请求     /banner
    export const reqBannerList = () => mockAjax.get('/banner')
    export const reqFloorList = () => mockAjax.get('/floor')

    5.在入口文件main.js中导入mock接口函数

    //这个是为了测试接口请求函数  后期也会使用这样的方式去使用
    import * as API from '@/api'
    //这个是为了测试接口请求函数  后期也会使用这样的方式去使用
    import * as API from '@/api'
    // console.log(API)
    // API.reqBannerList()
    // API.reqFloorList()

    6.在store---home.js,中,将mock请求的数据保存在vuex中

    home.js内容

    import {reqCategoryList,reqBannerList,reqFloorList} from '@/api'
    
    const state = {
      categoryList : [],
      bannerList:[],
      floorList:[]
    }
    const mutations = {
      //直接修改数据
      RECEIVECATEGORYLIST(state,categoryList){
        state.categoryList = categoryList
      },
      RECEIVEBANNERLIST(state,bannerList){
        state.bannerList = bannerList
      },
      RECEIVEFLOORLIST(state,floorList){
        state.floorList = floorList
      }
    }
    
    const actions = {
      //异步请求数据
      //async 和 await的用法
      async getCategoryList({commit}){
        const result = await reqCategoryList()
        if(result.code === 200){
          commit('RECEIVECATEGORYLIST',result.data)
        }
      },
      async getBannerList({commit}){
        const result = await reqBannerList()
        if(result.code === 200){
          commit('RECEIVEBANNERLIST',result.data)
        }
      },
      async getFloorList({commit}){
        const result = await reqFloorList()
        if(result.code === 200){
          commit('RECEIVEFLOORLIST',result.data)
        }
      },
      
    }
    
    const getters = {
      bannerList(state){
        return state.bannerList
      }
    }
    
    export default {
      state,
      mutations,
      actions,
      getters
    }
    vuex的数据
     
    7.在listContainer组件,index.vue中,关联到vuex,     this.$store.dispatch("getBannerList");
     
      mounted() {
        this.getBannerList();
    }
     
     methods: {
        getBannerList() {
          this.$store.dispatch("getBannerList");
        }
      },
     
    获取vuex的数据
    import { mapGetters } from "vuex";
     
     computed: {
        // 总的store 内部的state比较特殊  state总的内部会有home,数据是放在home对象内部
        // 其它的getters  mutations  actions 都没有
        // ...mapState({
        //   bannerList : state => state.home.bannerList
        // })
        ...mapGetters(["bannerList"])
      },

    在html模板中填充数据

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

    此时mock模拟接口的图片需要放在public文件夹中,图片才会显示

     
    8.home组件index.vue中,关联到vuex,     this.$store.dispatch('getFloorList')
    获取数据
    import { mapState } from 'vuex'
     computed:{
        ...mapState({
          floorList: state => state.home.floorList
        })
      }

    组件数据

    注:此时数据在父组件home中,需要将数据传给子组件floor组件中,父子通信,属性传递

    <template>
      <div>
        <TypeNav></TypeNav>
        <ListContainer></ListContainer>
        <Recommend></Recommend>
        <Rank></Rank>
        <Like></Like>
        <Floor v-for="(floor, index) in floorList" :key="floor.id" :floor="floor"></Floor>
        <Brand></Brand>
      </div>
    </template>

    子组件floor接收数据   props:['floor'],

    html模板填充数据

    <div class="blockgary">
                  <ul class="jd-list">
                    <li v-for="(keyword, index) in floor.keywords" :key="index">{{keyword}}</li>
                  </ul>
                  <img :src="floor.imgUrl" />
                </div>
     <div class="split">
                  <span class="floor-x-line"></span>
                  <div class="floor-conver-pit">
                    <img :src="floor.recommendList[0]" />
                  </div>
                  <div class="floor-conver-pit">
                    <img :src="floor.recommendList[1]" />
                  </div>
                </div>
     

     二, 轮播图swiper基本使用及动态数据

    1.安装5版本的swiper,  npm  i swiper@5  -S     目前最新是6,不稳定

    2.在listContainer组件中,引入swiper, 

    //swiper引入js和css
    // import Swiper from "swiper";
    // import "swiper/css/swiper.min.css";
     
    轮播图html模板
     <!-- <div class="swiper-container" ref="banner">
              <div class="swiper-wrapper">
                <div class="swiper-slide" v-for="(banner, index) in bannerList" :key="banner.id">
                  <img :src="banner.imgUrl" />
                </div>
                
              </div>
              <div class="swiper-pagination"></div>
    
              <div class="swiper-button-prev"></div>
              <div class="swiper-button-next"></div>
            </div> -->
     

    3. 实例化swiper对象

      mounted() {
        this.getBannerList();
        //为什么Swiper在实例的时候放在mounted当中 静态数据是可以的
        //动态数据就不行
        // 静态数据一上来就加载完成了,我们页面的结构也就形成了,然后创建swiper 理所当然就可以
        //动态数据 是我们异步请求的,mounted里面发请求完之后 立即实例化swiper,此时请求的数据不一定回来
        //而我们的页面结构是依赖动态的数据进行创建的
        // new Swiper(this.$refs.banner, {
        //   // direction: "vertical", // 垂直切换选项,默认是水平切换
        //   // loop: true, // 循环模式选项
    
        //   // 如果需要分页器
        //   pagination: {
        //     el: ".swiper-pagination"
        //   },
    
        //   // 如果需要前进后退按钮
        //   navigation: {
        //     nextEl: ".swiper-button-next",
        //     prevEl: ".swiper-button-prev"
        //   }
    
        //   // 如果需要滚动条
        //   // scrollbar: {
        //   //   el: ".swiper-scrollbar"
        //   // }
        // });
      },

    注:此时swiper没有效果,因为页面还没有渲染成型,更深的说,this.getBannerList();发送ajax,是异步的,数据还没有请求过来,页面就还未渲染

     
    处理方法,解决请求动态数据,有swiper轮播图的效果,
    此时需要去监视请求的数据bannerList,如果请求的数据过来了,才可以实例化swiper,此时才会去渲染页面
     
    4.处理方法,监视bannerList
     // watch: {
      //   bannerList: {
      //     handler() {
      //       //Vue.nextTick或者vm.$nextTick是一样的功能
      //       //在最近的一次dom更新之后执行nextTick里面传的回调函数
      //       this.$nextTick(() => {
      //         new Swiper(this.$refs.banner, {
      //           // direction: "vertical", // 垂直切换选项
      //           // autoplay:true,//等同于以下设置
      //           loop: true, // 循环模式选项
    
      //           // 如果需要分页器
      //           pagination: {
      //             el: ".swiper-pagination"
      //           },
    
      //           // 如果需要前进后退按钮
      //           navigation: {
      //             nextEl: ".swiper-button-next",
      //             prevEl: ".swiper-button-prev"
      //           }
    
      //           // 如果需要滚动条
      //           // scrollbar: {
      //           //   el: ".swiper-scrollbar"
      //           // }
      //         });
      //       });
      //     },
      //     immediate:true //立即执行,在最近dom更新之前就会执行
      //   },
    
      // }

    注:此时swiper轮播图还是没有数据,因为,数据跟新了,但是此时有v-for, 页面还未渲染,此时需要引入vm.$nextTick

    在最近的一次dom更新之后执行nextTick里面传的回调函数,这时,swiper轮播图才有效果

     floor组件依次引入swiper,进行轮播图切换

    抽离公共的swiper组件,注册为全局组件,将数据传入swiper组件

     
  • 相关阅读:
    springboot、监听器
    springboot、拦截器
    Thymeleaf模板引擎
    springboot-banner.txt
    springboot,swagger2
    springboot 热部署
    判断是否为微信环境下打开的网页
    后台接收json数据
    ios 面试题
    iOS 适配问题
  • 原文地址:https://www.cnblogs.com/fsg6/p/13345853.html
Copyright © 2020-2023  润新知