vue项目的实用性总结

1、mockjs 基本使用 ★

  1. 安装:npm i mockjs

  2. src/mock/index.js内容如下:

    import Mock from 'mockjs'
    //制订拦截规则
    Mock.mock('http://www.0313.com','get','你好啊')
    
  3. 记得在main.js中引入一下,让其参与整个项目的运行。

  4. 只要发出去的是get类型的ajax请求,地址只要是http://www.0313.com就能拦截了。

  5. 备注:使用mockjs后,浏览器的网络选项卡中一定看不到被拦截的请求。

  6. Test组件中发送一个请求测试一下。

    async handleTest(){
      const result = await axios.get('http://www.0313.com')
      console.log(result)
    }
    

2、处理 vuex 假报错 ★

  1. 问题描述:从undefined上读取属性会报错,代码演示如下:

    //例如vuex中数据格式如下:
    const state = {
      a:[],
      x:{}
    }
    
    
    <h1>{{a[0].id}}h1>
    <h1>{{x.y.z}}h1>
    
  2. 如何解决?

    • 第一种方法:在最初就设计好数据层次 —— 不推荐。

      const state = {
        a:[{}],
        x:{y:{}}
      }
      
    • 第二种方法:使用数据时加判断。

      <h1 v-if="a[0]">{{a[0].id}}h1>
      <h1 v-if="x.y">{{x.y.z}}h1>
      
    • 第三种方法:使用问号 —— 最推荐。

      <h1>{{a[0]?.id}}h1>
      <h1>{{x.y?.z}}h1>
      
    • 第四种方法:若模板中恰巧使用了v-for遍历,那么问题自动消失。

      <h1 v-for="s in carouselList" :key="s.id">{{s.imgUrl}}h1>
      
    • 第五种方法:使用&&短路

      <h1>{{a[0] && a[0].id}}h1>
      <h1>{{x.y && x.y.z}}h1>
      

3、vue-awesome-swiper 的使用 ★

  1. Swiper是专门做轮播图的库,在:原生项目、Vue项目、React项目中,均可使用。

  2. Vue项目中,可以使用vue-awesome-swiper来更方便的实现轮播图。

  3. 安装:npm i [email protected]

  4. Test组件中实现一个简单的轮播

    <template>
      <swiper class="swiper" :options="swiperOption">
        <swiper-slide class="item">Slide 1</swiper-slide>
        <swiper-slide class="item">Slide 2</swiper-slide>
        <swiper-slide class="item">Slide 3</swiper-slide>
        <swiper-slide class="item">Slide 4</swiper-slide>
        <div class="swiper-pagination" slot="pagination"></div>
        <div class="swiper-button-prev" slot="button-prev"></div>
        <div class="swiper-button-next" slot="button-next"></div>
      </swiper>
    </template>
    
    <script>
      import {Swiper, SwiperSlide} from 'vue-awesome-swiper'
      import 'swiper/css/swiper.css'
    
      export default {
        name: 'Test',
        components: {Swiper,SwiperSlide},
        data() {
          return {
            //轮播图配置对象
            swiperOption: {
                slidesPerView: 1, //同时展示几屏
                spaceBetween: 30, //每屏间隔
                loop: true, //是否循环轮播
                speed: 1000, //切换速度
                //自动轮播
                autoplay: {
                  delay: 2000,//轮播间隔
                  disableOnInteraction: false //鼠标点击后,是否禁止自动轮播
                },
                //分页器配置(小圆点)
                pagination: {
                  el: '.swiper-pagination', //分页器元素
                  clickable: true //小圆点是否可以点击
                },
                //导航按钮(左箭头、右箭头)
                navigation: {
                  nextEl: '.swiper-button-next',
                  prevEl: '.swiper-button-prev'
                }
            }
          }
        }
      }
    </script>
    
    <style lang="less" scoped>
      .item {
        line-height: 200px;
        text-align: center;
        font-size: 40px;
        background-image: linear-gradient(45deg,red,yellow,green);
        height: 200px;
      }
    </style>
    

4、整合搜索参数 ★

  1. 目标:无论是点击分类,还是点击搜索Search组件都需要接收路由参数。

  2. 使用watch监听$route

    watch:{	
      $route:{		
        //立即监视,目的是为了让第一次搜索的时候,可以拿到参数。
        immediate:true,
        //此处的value是谁? —— 是$route的新值(监视的是谁,handler得到的就是谁的新值)
        handler(value){	
          console.log(value.query)		
        }	
      }
    }
    
  3. 具体思路:使用watch监听$route,只要当前路由信息变化,就存储搜索参数。

    watch:{
    	$route:{
            //追加立即监视,为了初次挂载拿到参数
    		immediate:true,
            //注意此处的query是谁?—— 路由传递过来的query参数   
    		handler({query}){
                //重置之前的一级id、二级id、三级id,随后将最新的参数合并进去
    			Object.assign(this.searchParams,{
    				category1Id:'', //重置一级分类id
    				category2Id:'', //重置二级分类id
    				category3Id:'', //重置三级分类id
    			},query)
    		}
    	}
    }
    

5、对分页器的理解★

  1. 为什么要用?—— 大量数据不能一次全部展示。
  2. 分页器想工作,需要哪些数据?
    • 总数(total)
    • **页大小(pageSize)**通俗理解:每页展示几条。
    • **页码(pageNo)**通俗理解:看第几页。
    • **连续页数(continues)**一般为奇数,例如:357 等,为什么?—— 好看,通常是5
    • 总页数(totalPage) = total/pageSize(注意要向上取整)

备注:红色是必须传项,绿色的不用传,可以根据红色算出来。

6、分页器_ 连续页_特殊情况一 ★

  • 连续页数continues > totalPage

    vue项目的实用性总结_第1张图片
  • 具体编码:

      export default {      
        name: "Pagination",   
        props:['total','pageSize','pageNo','continues'],
        computed:{
          // 计算总页数
          totalPage(){
            return Math.ceil(this.total / this.pageSize)
          },
          // 计算连续页的起始页、结束页
          startEnd(){
            // 获取外部传入的各种参数
            const {continues,pageNo,totalPage} = this
            let start = 0 //起始页初始值
            let end = 0 //结束页初始值
            // 判断一下目前的情况是不是一个“大变态”
            //(你要求的连续页数,比我倾家荡产的总页数都要多,推都不推,都给你)
            if(continues > totalPage){
              start = 1
              end = totalPage
            }else{
              // 标准情况
              start = pageNo - (continues - 1)/2
              end = pageNo + (continues - 1)/2
            }
            return {start,end}
          }
        }
      };
    

7. 分页器_ 连续页_特殊情况二★

  • 算连续页start的时候,往左推,推多了,出现 start < 1 了。

    vue项目的实用性总结_第2张图片
  • 处理方式如下:

    export default {      
        name: "Pagination",   
        props:['total','pageSize','pageNo','continues'],
        computed:{
          // 计算总页数
          totalPage(){
            return Math.ceil(this.total / this.pageSize)
          },
          // 计算连续页的起始页、结束页
          startEnd(){
            // 获取外部传入的各种参数
            const {continues,pageNo,totalPage} = this
            let start = 0 //起始页初始值
            let end = 0 //结束页初始值
    
            // 判断一下目前的情况是不是一个“大变态”
            //(你要求的连续页数,比我倾家荡产的总页数都要多,推都不推,都给你)
            if(continues > totalPage){
              start = 1
              end = totalPage
            }else{
              // 标准情况(正常左推,右推)
              start = pageNo - (continues - 1)/2
              end = pageNo + (continues - 1)/2
              // 判断左边是否“冒了”(start是否小于1)
              if(start < 1){ 
                start = 1
                end = continues
              }
            }
            return {start,end}
          }
        }
      };
    

8. 分页器_ 连续页_特殊情况三★

  • 往右推,算结束页码的时候,推多了,出现end > totalPage 了。

    vue项目的实用性总结_第3张图片>

  • 处理方式如下:

    export default {      
        name: "Pagination",   
        props:['total','pageSize','pageNo','continues'],
        computed:{
          // 计算总页数
          totalPage(){
            return Math.ceil(this.total / this.pageSize)
          },
          // 计算连续页的起始页、结束页
          startEnd(){
            // 获取外部传入的各种参数
            const {continues,pageNo,totalPage} = this
            let start = 0 //起始页初始值
            let end = 0 //结束页初始值
    
            // 判断一下目前的情况是不是一个“大变态”
            //(你要求的连续页数,比我倾家荡产的总页数都要多,推都不推,都给你)
            if(continues > totalPage){
              start = 1
              end = totalPage
            }else{
              // 标准情况(正常左推,右推)
              start = pageNo - (continues - 1)/2
              end = pageNo + (continues - 1)/2
              // 判断左边是否“冒了”(start是否小于1)
              if(start < 1){ 
                start = 1
                end = continues
              }
              // 判断右边是否“冒了”(end是否大于totalPage)
              if(end > totalPage){ 
                start = totalPage - continues + 1
                end = totalPage
              }
            }
            return {start,end}
          }
        }
      };
    

9. 分页器_整体显示

  • 分页器整体的显示,逻辑如下:

    • 当前已经是第一页了,那么【上一页】就不能点了。
    • 当前已经是最后一页了,那么【下一页】就不能点了。
    • 两个数中间,有其他数,再出现三个点。
    	
    

10.分页器_整体交互

  • 第一步:对接真实数据,把:totalpageNopageSize,传给Pagination组件。

    注意1:total是服务器返回给我们的,要去searchResInfo中拿。

    注意2:pageNopageSize是我们传给服务器的,要去searchParams中拿。

    注意3:continues是连续页数,是我们自己指定的。

    
    
    
  • 第二步:传递页码,Pagination组件将用户点击的页码,传给Search组件,Search组件接收参数,随后重新请求数据。

    1. Saecrh组件中:

      
      
      
      
    2. Pagination组件中: