使用vue.js制作分页组件
来源: 阅读:1179 次 日期:2016-07-12 15:00:55
温馨提示: 小编为您整理了“使用vue.js制作分页组件”,方便广大网友查阅!

本文给大家分享的是个人在使用vue.js制作的文章和评论的分页组件,并使用webpack打包起来,这里推荐给大家,有需要的小伙伴可以参考下

学习了vue.js一段时间,拿它来做2个小组件,练习一下。

我这边是用webpack进行打包,也算熟悉一下它的运用。

源码放在文末的 github 地址上。

首先是index.html

<!DOCTYPE html>

<html>

<head>

 <title>Page</title>

 <style type="text/css">

  * {

   margin: 0;

   padding: 0;

   font-family: 'Open Sans', Arial, sans-serif;

  }

  .contianer {

   width: 50%;

   height: auto;

   margin: 20px auto;

  }

  article {

   margin-bottom: 50px;

  }

 </style>

</head>

<body>

 <div class='contianer'>

  <article>

   文章内容...

  </article>

  <div id='main'>

   <app></app>  

  </div>

 </div>

 <script type="text/javascript" src='bundle.js'></script>

</body>

</html>

我将 app这个组件放在 <div id='main'></div> 内

通过webpack打包后,入口的js文件是entry.js,用来引入app.vue组件

entry.js

let Vue = require('vue');

import App from './components/app';

let app_vue = new Vue({

 el: '#main',

 components: {

  app: App

 }

});

接下来看下这个app组件

<style type="text/css" scoped>

</style>

<template>

 <comment :cur-page-index="curPageIndex" :each-page-size="eachPageSize" :comment-url="commentUrl"

  :comment-params="commentParams" :comment-is-sync="commentIsSync">

 </comment>

 <page :cur-page-index.sync="curPageIndex" :each-page-size="eachPageSize" :page-url="pageUrl"

  :page-params="pageParams" :page-is-sync="pageIsSync">

 </page>

</template> 

<script type="text/javascript">

 import Comment from './comment';

 import Page from './page';

 export default {

  data () {

   return {

    curPageIndex: 1,

    eachPageSize: 7,

   }

  },

  components: {

   comment: Comment,

   page: Page

  },

 }

</script>

它有2个子组件,分别是comment.vue和page.vue,通过动态绑定数据,进行父子间组件通信,我是这样认为的,对于 当前在第几页 应当由 page.vue传递给app.vue,所以这里我们使用 双向绑定,其余的如 params, url, isSync,即向后台请求数据的东西以及是否同步或异步操作<当然,这里我还没有测试过后台数据,目前是直接js生成静态数据>。

接下来,看下comment.vue评论组件

<style type="text/css" scoped>

 .comt-mask {

  opacity: 0.5;

 }

 .comt-title {

 }

 .comt-line {

  width: 100%;

  height: 2px;

  background-color: #CCC;

  margin: 10px 0;

 }

 .comt-wrap {

 }

 .comt-user {

  float: left;

 }

 .comt-img {

  width: 34px;

  height: 34px;

  border-radius: 17px;

 }

 .comt-context {

  margin: 0 0 0 60px;

 }

 .comt-name {

  color: #2B879E;

  margin-bottom: 10px;

  font-size: 18px;

 }

</style>

<template>

 <div v-if="hasComment" :class="{'comt-mask': loading}">

  <h3 class='comt-title'>{{ totalCommentCount }} 条评论</h3>

  <div class="comt-line"></div>

  <div class="comt-wrap" v-for="comment of commentArr">

   <div class="comt-user">

    <img src='{{ comment.avatar }}' class="comt-img"/>

   </div>

   <div class="comt-context">

    <p class="comt-name">{{ comment.name }}</p>   

    <p>

     {{ comment.context }}

    </p>

   </div>

   <div class="comt-line"></div>

  </div>

 </div>

</template>

<script type="text/javascript">

 import {getCommentData, getTotalCommentCount} from './getData';

 export default {

  props: {

   curPageIndex: {

    type: Number,

    default: 1,

   },

   eachPageSize: {

    type: Number,

    default: 7,

   },

   commentUrl: {

    type: String,

    default: '',

   },

   commentParams: {

    type: Object,

    default: null,

   },

   commentIsSync: {

    type: Boolean,

    default: true,

   },

  },

  data () {

   return {

    totalCommentCount: 0,

    hasComment: false,

    loading: true,   

   }

  },

  computed: {

   commentArr () {

    this.loading = true;

    let res = getCommentData(this.commentUrl, this.commentParams, this.commentIsSync, this.curPageIndex, this.eachPageSize);

    this.loading = false;

    return res;

   },

  },

  created () {

   let cnt = getTotalCommentCount(this.commentUrl, this.commentParams);

   this.totalCommentCount = cnt;

   this.hasComment = cnt > 0;

  }

 }

</script>

这里的 getData.js 将在下面提到,是我们获取数据的位置。

loading: 本意是在跳转页码加载评论时,对于当前评论加载0.5的透明度的遮罩,然后ajax通过它的回调函数来取消遮罩,现在这样就不能实现了,只能强行写下,然而是没有用的..

hasComment: comment组件第一次加载的时候,我们就去请求获得总共的数据长度,如果没有数据,则不显示comment组件布局内容

·curPageIndex·: 通过父组件app传递下来,使用的是props

这些数据,我们都设置一个默认值与类型比较好。

page.vue

<style type="text/css" scoped>

 .page {

  text-align: center;

  margin: 30px;

 }

 .page-btn {

  color: gray;

  background-color: white;

  border: white;

  width: 30px;

  height: 30px;

  margin: 5px;

  font-size: 18px;

  outline: none;

 }

 .page-btn-link {

  cursor: Crosshair;

 }

 .page-btn-active {

  border: 1px solid gray;

  border-radius: 15px;

 }

</style>

<template>

 <div class="page">

  <button v-for="pageIndex of pageArr" track-by='$index' :class="{'page-btn': true, 'page-btn-active': 

   this.curPageIndex === pageIndex, 'page-btn-link': checkNum(pageIndex)}"

   @click="clickPage(pageIndex)" >

    {{ pageIndex }}

  </button>  

 </div>

</template>

<script type="text/javascript">

 import {getTotalPageCount} from './getData';

 export default {

  props: {

   totalPageCount: {

    type: Number,

    default: 0,

   },

   curPageIndex: {

    type: Number,

    default: 1,

   },

   eachPageSize: {

    type: Number,

    default: 7,

   },

   pageAjcn: {

    type: Number,

    default: 4,

   },

   pageUrl: {

    type: String,

    default: '',

   },

   pageParams: {

    type: Object,

    default: null,

   },

   pageIsSync: {

    type: Boolean,

    default: true,

   }      

  },

  data () {

   return {

   }

  },

  computed: {

   pageArr () {

    let st = 1,

     end = this.totalPageCount,

     cur = this.curPageIndex,

     ajcn = this.pageAjcn,

     arr = [],

     left = Math.floor(ajcn / 2),

     right = ajcn - left;

    if (end == 0 || cur == 0) {

     return arr;

    } else {

     console.log(st, end, cur, left, right);

     arr.push(st);

     console.log(st+1, cur-left);

     if (st + 1 < cur - left) {

      arr.push('...');

     }

     for (let i = Math.max(cur - left, st + 1); i <= cur - 1; ++i) {

      arr.push(i);

     }

     if (cur != st) {

      arr.push(cur);

     }

     for (let i = cur + 1; i <= cur + right && i <= end - 1 ; ++i) {

      arr.push(i);

     }

     if (cur + right < end - 1) {

      arr.push('...');

     }

     if (end != cur) {

      arr.push(end);

     }

     return arr;

    } 

   }

  },

  methods: {

   clickPage (curIndex) {

    if (Number.isInteger(curIndex)) {

     this.curPageIndex = curIndex;

    }

   },

   checkNum (curIndex) {

    return Number.isInteger(curIndex);

   }   

  },

  created () {

   this.totalPageCount = getTotalPageCount(this.pageUrl,  this.pageParams, this.pageIsSync, 

    this.eachPageSiz);

  }

 }

</script>

主要是个对于 组件事件的运用,=最常见的click事件,以及class与style的绑定,根据 curPageIndex与this.pageIndex来比较,判断是否拥有这个class,通过computed计算属性,来获得 页码数组 因为会根据当前页 有所变化,created的时候 计算出总页码。

最后一个是 目前生成获取静态数据的js文件.

// let data = {

//  avatar: '', 头像

//  name: '', 用户名

//  context: '', 评论内容

// }

let dataArr = [];

function randomStr (len) {

 return Math.random().toString(36).substr(len);

}

function initData () {

 for (var i = 0; i<45 ; ++i) {

  let _avator = "./resources/" + i%7 + ".jpg";

  let _name = randomStr(20);

  let _context = randomStr(2);

  dataArr.push({

   avatar: _avator,

   name: _name,

   context: _context

  });

 }

}

if (!dataArr.length) {

 initData();

}

export function getCommentData (url = '', params = null, isSync = true, curPageIndex = 1, eachPageSize = 7) {

 /* ajax */

 let st = (curPageIndex - 1) * eachPageSize;

 let end = st + eachPageSize;

 return dataArr.slice(st, end);

}

export function getTotalCommentCount(url = '', params = null, isSync = true) {

 /* ajax */

 return dataArr.length;

}

export function getTotalPageCount(url = '', params = null, isSync = true, eachPageSize = 7) {

 /* ajax */

 return Math.floor((dataArr.length + eachPageSize -1 ) / eachPageSize);

}

就这样了吧。

更多信息请查看网络编程
手机网站地址:使用vue.js制作分页组件
由于各方面情况的不断调整与变化, 提供的所有考试信息和咨询回复仅供参考,敬请考生以权威部门公布的正式信息和咨询为准!
关于我们 | 联系我们 | 人才招聘 | 网站声明 | 网站帮助 | 非正式的简要咨询 | 简要咨询须知 | 加入群交流 | 手机站点 | 投诉建议
工业和信息化部备案号:滇ICP备2023014141号-1 云南省教育厅备案号:云教ICP备0901021 滇公网安备53010202001879号 人力资源服务许可证:(云)人服证字(2023)第0102001523号
云南网警备案专用图标
联系电话:0871-65317125(9:00—18:00) 获取招聘考试信息及咨询关注公众号:hfpxwx
咨询QQ:526150442(9:00—18:00)版权所有:
云南网警报警专用图标
Baidu
map