Vue使用v-model封装el-pagination组件的全过程

使用v-model绑定分页信息对象,分页信息对象包括3个核心属性参数,分页事件直接绑定查询数据的方法,消除父组件的handleSizeChange和handleCurrentChange的绑定事件方法。

1、前言

  通过封装el-pagination组件开发自定义分页组件的类似文章网上已经有很多了,但看了一圈,总是不如意,于是决定还是自己动手搞一个。

2、背景

2.1、常规分页处理方法

  利用el-pagination组件的常规做法如下:

  模板部分:

 <el-pagination @size-change="handleSizeChange"
            @current-change="handleCurrentChange" :current-page="pageInfo.pagenum"
            :page-sizes="[5, 10, 15, 20]" :page-size="pageInfo.pagesize"
            layout="total, sizes, prev, pager, next, jumper" :total="pageInfo.total"
            background>
        </el-pagination>

  脚本部分:

export default {
  data() {
    return {
      formData : {
        //查询信息
        queryInfo:{
          userType  : 0,
          deleteFlag: 2,  //表示所有类型
          pagenum   : 1,
          pagesize  : 10
        },

        // 用户类型选择框当前选中显示标签值
        userTypeLabel : "所有类型",

        // 用户状态选择框当前选中显示标签值
        userStatusLabel : "所有类型"
      },

      // 分页信息
      pageInfo:{
        pagenum   : 1,
        pagesize  : 10,
        total     : 0
      }
    }
  },
  methods: {
    // 查询用户信息列表
    queryUsers(){
      let _this = this;
      //console.log(this.pageInfo);

      this.formData.queryInfo.pagenum = this.pageInfo.pagenum;
      this.formData.queryInfo.pagesize = this.pageInfo.pagesize;

      this.instance.queryUsers(
        this.$baseUrl,this.formData.queryInfo
      ).then(res => {
        //console.log(res.data);
        if (res.data.code == this.global.SucessRequstCode){
          //如果查询成功
          _this.pageInfo.total = res.data.data.length;
          _this.userInfoList = res.data.data;
        }else{
          alert(res.data.message);
        }
      }).catch(error => {
        alert('查询失败!');
        console.log(error);
      });
    },
    // 每页条数改变
    handleSizeChange(newSize) {
        this.pageInfo.pagesize = newSize;
        this.queryUsers();
    },
    // 当前页码改变
    handleCurrentChange(newPage) {
        this.pageInfo.pagenum = newPage;
        this.queryUsers();
    }
  }

2.2、问题分析

  每个分页查询,都需要这么来一套,有点简单重复,又略有不同,即查询数据的方法会不同。

  对于有强迫症的程序猿来说,简单重复的代码无疑非常令人不爽。因此,需要将之组件化。

  分析el-pagination分页组件:

  1. 有三个核心属性参数,分别是:当前页码(current-page)、每页条数(page-size)、总记录条数(total)。核心属性参数通过绑定父组件页面数据,实行双向联动。其中当前页码和每页条数一般通过操作分页子组件来改变,总记录条数通过查询数据后由父组件进行设置。
  2. 有两个事件:分别是:@size-change(每页条数改变事件)、@current-change(当前页码改变事件)。这两个事件,分别绑定父组件的对应事件处理方法handleSizeChange和handleCurrentChange,两者均调用查询数据的方法,查询数据的方法中,得到结果集后,设置总记录条数。

  自定义分页组件的开发目标:消除父组件的handleSizeChange和handleCurrentChange的绑定事件方法。

  思路:使用v-model绑定分页信息对象,分页信息对象包括3个核心属性参数,即上述的pageInfo。然后分页事件直接绑定查询数据的方法。

3、方案实施

3.1、自定义分页组件

  编写一个自定义分页组件代码,文件为/src/Pagination.vue。代码如下:

<template lang="html">
  <div class="pagination">
    <el-pagination
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page.sync="pageInfo.pagenum"
      :page-size="pageInfo.pagesize"
      :page-sizes="pageSizes"
      :total="pageInfo.total"
      layout="total, sizes, prev, pager, next, jumper"
      background >
    </el-pagination>
  </div>
</template>

<script>
  export default {
    name  : "pagination",
    model : {
        prop    : 'pageInfo',
        event   : 'change'
    },
    props : {
      // 每页条数选择项
      pageSizes: {
        type: Array,
        default() {
          return [5, 10, 15, 20];
        }
      },
      // v-model绑定的数据对象
      pageInfo: {
        type: Object,
        reuqired:true
      }
    },
    data(){
      return {
      }
    },
    methods: {
      handleSizeChange(newSize) {
        var newValue={
					pagesize : newSize,
					pagenum : newSize <= this.total  ?  1  :  this.pageInfo['pagenum']
				};
        this.$emit('change',Object.assign(this.pageInfo,newValue));
        this.$emit('pagination');
      },
      handleCurrentChange(newPage) {
        this.$emit('change',Object.assign(this.pageInfo,{pagenum : newPage}));
        this.$emit('pagination');
      }
    }
  }
</script>

<style lang="css" scoped>
.pagination {
    padding: 10px 0;
    text-align: center;
}
</style>

  自定义分页组件,名称为pagination,其使用v-model,实现双向数据通信。当页码或每页条数改变时,触发分页事件@pagination,提供与父组件方法绑定。

  此处约定了pageInfo的字段结构如下:

  pageInfo:{
        pagenum   : 1,	//Number
        pagesize  : 10,	//Number
        total     : 0	//Number
      }

  父组件必须提供相同结构的数据对象来绑定组件内部的pageInfo对象。

3.2、注册分页组件

  然后注册此分页组件,在main.js中加入下列代码:

import pagination  from '@/components/Pagination.vue'

// 注册分页插件
Vue.component('pagination', pagination)

3.3、父组件调用方法

  用pagination组件修改前面第二章的代码。

  模板部分:

  <!-- 分页区域 -->
        <pagination v-model="pageInfo" @pagination="queryUsers"></pagination>

  脚本部分:

export default {
  data() {
    return {
      formData : {
        //查询信息
        queryInfo:{
          userType  : 0,
          deleteFlag: 2,  //表示所有类型
          pagenum   : 1,
          pagesize  : 10
        },

        // 用户类型选择框当前选中显示标签值
        userTypeLabel : "所有类型",

        // 用户状态选择框当前选中显示标签值
        userStatusLabel : "所有类型"
      },

      // 分页信息
      pageInfo:{
        pagenum   : 1,
        pagesize  : 10,
        total     : 0
      }
    }
  },
  methods: {
    // 查询用户信息列表
    queryUsers(){
      let _this = this;
      //console.log(this.pageInfo);

      this.formData.queryInfo.pagenum = this.pageInfo.pagenum;
      this.formData.queryInfo.pagesize = this.pageInfo.pagesize;

      this.instance.queryUsers(
        this.$baseUrl,this.formData.queryInfo
      ).then(res => {
        //console.log(res.data);
        if (res.data.code == this.global.SucessRequstCode){
          //如果查询成功
          _this.pageInfo.total = res.data.data.length;
          _this.userInfoList = res.data.data;
        }else{
          alert(res.data.message);
        }
      }).catch(error => {
        alert('查询失败!');
        console.log(error);
      });
    }
  }

  这样,就去掉了handleSizeChange和handleCurrentChange事件响应方法了。分页信息发生改变时,触发绑定的queryUsers方法。

  另外,如需调整pageSizes,则在模板处类似如下设置:

:pageSizes=[10,20,30,50,100]

4、参考文章

  此组件开发主要参考了下列文章:

Vue+el-pagination二次封装,https://blog.csdn.net/weixin_47259997/article/details/107887823。

vue项目 使用elementui中的el-pagination封装公用分页组件,https://www.jianshu.com/p/e241e5710fb0/。

到此这篇关于Vue使用v-model封装el-pagination组件的全过程的文章就介绍到这了,更多相关v-model封装el-pagination组件内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue使用自定义事件的表单输入组件用法详解【日期组件与货币组件】

    本文实例讲述了vue使用自定义事件的表单输入组件用法.分享给大家供大家参考,具体如下: 自定义事件可以用来创建自定义的表单输入组件,使用 v-model 来进行数据双向绑定. v-model的实现原理 : <input v-model="something"> 这不过是以下示例的语法糖: <input v-bind:value="something" v-on:input="something = $event.target.value&

  • vue 表单输入框不支持focus及blur事件的解决方案

    采用指令的方式来解决这个问题(此处的前端框架以mint-ui为例): 1.html引用: v-mtfocus 2.在实例中添加指令 directives: { 'mtfocus' (el, binding, vnode) { let mtinput = el.querySelector('input') mtinput.onfocus = function () { ...//如果要对节点的数据进行更改,且更改要映射到页面上,则更改可在vnode.context上进行,这样,改完之后,改变就会映

  • vue使用v-model进行跨组件绑定的基本实现方法

    大家好,今天我们来说一下使用v-model实现父子组件的绑定效果 1:简单版代码如下: 父组件: <template> <div> // 3:使用子组件,并使用v-model绑定 <About v-model="father"/> </div> </template> <script> // 1:引入子组件 import About from "./About"; export default

  • vue3组件中v-model的使用以及深入讲解

    目录 v-model input中使用双向绑定数据 组件中的v-model 其他写法 总结 v-model input中使用双向绑定数据 v-model在vue中我们经常用它与input输入框的输入值进行绑定,简单的实现原理大家也应该都知道 通过v-bind绑定value值 及结合@input输入事件动态改变绑定的value值来实现双向绑定,如下vue3实现代码: <template> <input type="text" :value="tryText&q

  • vue 使用 v-model 双向绑定父子组件的值遇见的问题及解决方案

    场景 今天在使用 v-model 进行组件双向数据绑定的时候遇到了一个奇怪的问题,网页本身运行正常,浏览器一直出现警告信息. [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value

  • 浅谈vue实现双向事件绑定v-model的原理

    目录 解释: 总结 补充 与js或者jquery直接改变操作dom不同,vue使用v-model实现数据的双向绑定,它会根据控件类型自动选取正确的方法来更新元素. v-model就是vue的双向绑定的指令,能将页面上控件输入的值同步更新到相关绑定的data属性,也会在更新data绑定属性时候,更新页面上输入控件的值 官方文档这么解释: v-model只不过是一个语法糖而已,真正的实现靠的还是 v-bind:绑定响应式数据 触发 input 事件 并传递数据 (核心和重点) 如下代码 <input

  • vue自定义组件实现v-model双向绑定数据的实例代码

    项目中会遇到自定义公共组件供项目调用,正常情况可以使用 props定义参数接收父组件传的参数,然后通过子组件的$emits()方法回传数据给父组件. 类似如下: 父组件 <common-checkbox :checked="goodsSelected" class="left" :height="'16px'" :width="'16px'" @checkChange="checkChange">

  • vue 表单输入格式化中文输入法异常问题

    v-model 是 vue.js 提供的语法糖,根据不同的表单控件监听不同的事件,实现对表单控件的数据双向绑定. 当控件是 <input> 输入框时,v-model 监听其 input 事件. 如下所示,这两种写法有什么区别吗? <input :value="name" @input="name = $event.target.value"><input v-model="name"> 输入中文格式化问题 表单

  • Vue表单输入绑定的示例代码

    基础用法 你可以用v-model指令在表单input,textarea以及select元素上创建双向数据绑定.它会根据控件类型自动选取正确的方法来更新元素.尽管有些神奇,但是v-model本质上不过是语法糖.它负责监听用户的输入事件以更新数据. v-model会忽略所有表单元素的value, checked, selected特性的初始值而总是将Vue实例的数据作为数据来源.你应该通过JavaScript在组件的data选项中声明初始值. (1) 文本 <input v-model="me

  • vue中v-model指令与.sync修饰符的区别详解

    目录 v-model .sync 细微之处的区别 总结功能作用场景: v-model <!--父组件--> <template> <!--v-model 指令是语法糖--> <Child v-model="model"></Child> <!-- 把 v-model 指令展开后相当于下面的代码 --> <!-- v-model绑定的默认事件是input,默认prop是value属性 --> <Ch

  • Vue 表单输入绑定v-model

    目录 1.v-model 2.绑定的属性和事件 3.表单元素绑定 3.1 input绑定 3.2 textarea绑定 3.3 checkbox绑定 3.4 radio绑定 3.5 select绑定 4.值绑定 4.1 代码详解 5.修饰符 5.1 .lazy 5.2 .number 5.3 .trim 1.v-model v-model指定可以实现表单值与属性的双向绑定.即表单元素中更改了值会自动的更新属性中的值,属性中的值更新了会自动更新表单中的值 2.绑定的属性和事件 v-model在内部

随机推荐