美文网首页
vue 多页面开发分页组件 有搜索功能

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

作者: sunxiaochuan | 来源:发表于2018-05-29 15:19 被阅读0次

    前言

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

    • 多页面结构截图
    image.png
    • 效果 gif 图
    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>
    
    
    • axios 挂载是在相应的 js 文件中
    import Vue from 'vue'
    import axios from 'axios'
    
    Vue.prototype.axios = axios
    

    总结

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

    • 需要注意的地方(bug 产生的原因):
      • 搜索后要将 "页码重置为 1"
      • "如果当前搜索成功之后,但是页码数量少于 页码列表总长度 ,比如两页,之后将搜索框内容手动删除,再点击分页会出现请求到的数据已更新为全部,但是分页列表数组 length 还是 2 导致的 bug"

    相关文章

      网友评论

          本文标题:vue 多页面开发分页组件 有搜索功能

          本文链接:https://www.haomeiwen.com/subject/kvhajftx.html