vue 多页面开发分页组件 有搜索功能

2018-05-29  本文已影响0人  sunxiaochuan

前言

需要具备父子组件通信的知识 不知道的可以看我的笔记了解--里面的第26、27条

image.png
Animation47.gif

正文

分页组件源码

  1. 新建分页 .vue 文件 src -> components -> pagination -> index.vue,编辑 index.vue 文件
<template>
<div>
    <!-- 分页 -->
    <nav aria-label="Page navigation" class="text-center">
        <ul class="pagination">
            <li  @click="previousGo">
              <a href="javascript:void(0);" aria-label="Previous">
                  <span aria-hidden="true">&laquo;</span>
              </a>
            </li>
                        <li v-for="(page,index) in pages" :key="index" @click="pageGo(page)" :class="{ 'active' : page === pageNumber}">
                            <a href="javascript:void(0);">{{ page }}</a>
                        </li>
            <li @click="nextGo">
              <a href="javascript:void(0);" aria-label="Next">
                  <span aria-hidden="true">&raquo;</span>
              </a>
            </li>
        </ul>
    </nav>
</div>
</template>

<script>
// import qs from 'qs' // 解决 axios 数据提交格式与后台不一致的问题  -> name=hehe&age=10
export default {
  props: ['parentPageData'], // 父组件数据 别名
  name: 'Pagination',
  data() {
    return {
      // 当前页码
      pageNumber: null,
      // 分页展示数量
      pageSize: null,
      // 数据总数量
      totalRow: null,
      // 页码数组
      pages: []
    }
  },
  watch: {
    // 监听父组件数据变化实时更新数据
    parentPageData: {
      handler: 'loadPageList',
      immediate: true
    }
  },
  methods: {
    // 转换数据
    transformPageData: function() {
      const me = this
      const pagePlugin = me.$parent.$data.pagePlugin
      // console.log(pagePlugin)
      me.pageNumber = pagePlugin.pageNumber
      me.pageSize = pagePlugin.pageSize
      me.totalRow = pagePlugin.totalRow
    },
    // 加载页面数据
    loadPageList: function() {
      // 页码数组
      const me = this
      me.transformPageData()
      let _length = me.pageSize // 每页数量 & 页码列表总长度
      let _page = me.pageNumber // 当前页面
      let _max = Math.ceil(me.totalRow / _length) // 最多的页码数字
      // console.log(_length + ' ' + _page + ' ' + _max)

      // 不是首次请求页码操作
      // 增加:判断页面长度是否为  页码列表总长度 修复 bug,bug 说明:如果当前搜索成功之后,但是页码数量少于 页码列表总长度 ,比如两页,之后将搜索框内容手动删除,再点击分页会出现请求到的数据已更新为全部,但是分页列表数组 length 还是 2 导致的 bug
      if (_page !== 1 && me.pages.length === _length) {
        if (_page === me.pages[0]) {
          // 当前页码数是数组中的第一个页码
          me.pages.pop() // 删除数组中最后一个元素
          me.pages.unshift(me.pageNumber - 1) // 向第一个元素前面追加一个元素
          return false
        } else if (_page === me.pages[me.pages.length - 1] && _page !== _max) {
          // 当前页码数是数组中的最后一个页码 且这个值不是总页码的最后一页
          me.pages.shift() // 删除数组中第一个元素
          me.pages.push(me.pageNumber + 1) // 向末尾增加一个元素
          return false
        } else if (me.pages.indexOf(_page) > -1) {
          // 当前的页码数存在于当前的页码数组中 不会向下重新拼接数组
          return false
        }
      }
      // 拼接页码操作
      let arr = []
      // 如果总页码不足 10 页 循环次数为页码数
      if (_max < 10) _length = _max
      // 当前页面已经是最后一页 倒数排列
      if (_page >= _max) {
        while (_length--) {
          arr.push(_page--)
        }
        arr.reverse()
      } else {
        while (_length--) {
          arr.push(_page++)
        }
      }
      me.pages = arr
    },
    // 分页点击
    pageGo: function(number) {
      const me = this
      // 点击的是当前页码 return
      if (me.pageNumber === number) return
      me.$parent.$data.pagePostData.page_number = number
      me.pageNumber = number
      // 调用父组件方法
      me.$emit('updatePageData')
      // me.transformPageData()
      // me.loadPageList()
    },
    // 上一页点击
    previousGo: function() {
      const me = this
      // 当前页码为 1 return
      if (me.pageNumber === 1) {
        return false
      } else {
        me.pageGo(me.pageNumber - 1)
      }
    },
    // 下一页点击
    nextGo: function() {
      const me = this
      // 当前页码为 最后一页 return
      if (me.pageNumber * me.pageSize >= me.totalRow) {
        return false
      } else {
        me.pageGo(me.pageNumber + 1)
      }
    }
  }
}
</script>

<style lang="less">
</style>

  1. 父组件相应的使用示例,多余的源码已删除
<template>
  <div class="container row">
    <div class="col-sm-10">
      <div class="row">
        <form class="navbar-form navbar-left col-sm-5" @submit.prevent="searchForm">
          <div class="form-group">
            <input type="text" class="form-control" placeholder="搜索" v-model="pagePostData.seach_name_phone">
          </div>
          <button type="submit" class="btn btn-default">搜索</button>
        </form>
        <div class="col-sm-7 text-right mtb-8">
          <button type="button" class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="下载示例文件及相关操作">下载示例</button>
          <button type="button" class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="">导出</button>
          <button type="button" class="btn btn-primary" data-toggle="tooltip" data-placement="top" title="" @click="openFilePopup">导入</button>
          <a href="addstaff.html" class="btn btn-link">新建成员</a>
          <a href="quitlist.html" class="btn btn-link">离职员工</a>
        </div>
      </div>
      <table class="table table-bordered">
        <caption>成员列表</caption>
        <thead>
          <tr>
            <th>&nbsp;&nbsp;</th>
            <th>姓名</th>
            <th>部门</th>
            <th>职位</th>
            <th>电话</th>
            <th>套餐</th>
            <th>授信额度</th>
            <th>状态</th>
            <th>操作</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(people,index) in pageGetData" :key="people.id">
            <td>
              <div class="custom-control custom-checkbox">
                <input class="form-check-input" type="checkbox" :id="'inlineCheckbox' + index">
              </div>
            </td>
            <td>{{ people.name }}</td>
            <td>{{ people.department }}</td>
            <td>{{ people.position }}</td>
            <td>{{ people.phone_number }}</td>
            <td>{{ people.package_code }}</td>
            <td>{{ people.balance }}</td>
            <td>{{ people.IS_USED }}</td>
            <td>
              <span>修改</span>
              <span>禁用</span>
              <span>移动</span>
              <span role="button" @click="leaveGo" :data-number="people.phone_number">离职</span>
              <span>详情</span>
            </td>
          </tr>
        </tbody>
      </table>
      <div class="data-none" v-show="pageGetData.length === 0">暂无数据</div>
      <!-- 分页 -->
      <pagination @updatePageData="loadPageData"  :parentPageData="pageGetData" v-show="pageGetData.length > 0"></pagination>
    </div>
    <!-- 弹窗 -->
    <msg-modal :modal-msg="modalMsg"></msg-modal>
  </div>
</template>

<script>
import qs from 'qs' // 解决 axios 数据提交格式与后台不一致的问题  -> name=hehe&age=10
import MsgModal from '@/components/msgmodal'
import Pagination from '@/components/pagination'

export default {
  name: 'App',
  components: { MsgModal, Pagination },
  data() {
    return {
      // 弹窗信息 在执行操作时使用
      modalMsg: '',
      // 信息提交接口
      pagePostAPI: '/jjhServerApi/ab/getAbByCondition',
      // 信息提交数据
      pagePostData: {
        /**
         * page_number 分页页数  不填默认为1
         * seach_name_phone 手机号或姓名 非必填  模糊查询传的条件
         */
        page_number: '',
        seach_name_phone: ''
      },
      // 页面数据
      pageGetData: [],
      // 分页组件参数
      pagePlugin: {
        // 当前页码
        pageNumber: '',
        // 分页展示数量
        pageSize: '',
        // 数据总数量
        totalRow: ''
      }
    }
  },
  mounted() {
    const me = this
    // 初始化页面数据
    me.loadPageData()
  },
  methods: {
    // 加载页面所需的数据
    loadPageData: function() {
      const me = this
      // console.log(qs.stringify(me.pagePostData))
      me.axios
        .post(me.pagePostAPI, qs.stringify(me.pagePostData))
        .then(response => {
          // console.log(response)
          const getData = response.data
          if (getData.code === 0) {
            me.pageGetData = getData.result.list
            me.pagePostData.page_number = getData.result.pageNumber
            // 分页数据转换
            me.pagePlugin.pageNumber = getData.result.pageNumber
            me.pagePlugin.pageSize = getData.result.pageSize
            me.pagePlugin.totalRow = getData.result.totalRow
          } else {
            me.openAlertModel(getData.info)
          }
        })
        .catch(error => {
          console.log(error)
          me.openAlertModel('请求服务器失败了,请稍后重试!')
        })
    },
    // 打开弹窗
    openAlertModel: function(message) {
      const me = this
      me.modalMsg = message
      $('#myModal').modal('show')
    },
    // 搜索表单提交
    searchForm: function() {
      const me = this
      // 页码重置为 1
      me.pagePlugin.pageNumber = me.pagePostData.page_number = 1
      me.loadPageData()
    }
  }
}
</script>

<style lang="less">
</style>

import Vue from 'vue'
import axios from 'axios'

Vue.prototype.axios = axios

总结

刚开始觉得还是蛮简单的,后来发现最早时候写的 bug 很多

上一篇下一篇

猜你喜欢

热点阅读