使用vue.js制作分页组件


Posted in Javascript onJune 27, 2016

学习了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);
}

就这样了吧。

github地址

Javascript 相关文章推荐
动态调用css文件——jquery的应用
Feb 20 Javascript
关于全局变量和局部变量的那些事
Jan 11 Javascript
JavaScript格式化日期时间的方法和自定义格式化函数示例
Apr 04 Javascript
js实现跨域访问的三种方法
Dec 09 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
Jan 08 Javascript
Angularjs中使用Filters详解
Mar 11 Javascript
jQuery自定义多选下拉框效果
Jun 19 jQuery
vue监听对象及对象属性问题
Aug 20 Javascript
jQuery实现的简单手风琴效果示例
Aug 29 jQuery
解决vue axios的封装 请求状态的错误提示问题
Sep 25 Javascript
webpack中的模式(mode)使用详解
Feb 20 Javascript
js实现贪吃蛇游戏(简易版)
Sep 29 Javascript
js编写一个简单的产品放大效果代码
Jun 27 #Javascript
用JS实现轮播图效果(二)
Jun 26 #Javascript
用JS实现图片轮播效果代码(一)
Jun 26 #Javascript
JavaScript中Form表单技术汇总(推荐)
Jun 26 #Javascript
jQuery滚动新闻实现代码
Jun 26 #Javascript
js css实现垂直方向自适应的三角提示菜单
Jun 26 #Javascript
JS中的进制转换以及作用
Jun 26 #Javascript
You might like
第十四节--命名空间
2006/11/16 PHP
纯真IP数据库的应用 IP地址转化成十进制
2009/06/14 PHP
基于php上传图片重命名的6种解决方法的详细介绍
2013/04/28 PHP
提高PHP编程效率的方法
2013/11/07 PHP
php多文件上传下载示例分享
2014/02/20 PHP
ThinkPHP的URL重写问题
2014/06/22 PHP
PHP验证码无法显示的原因及解决办法
2017/08/11 PHP
js停止输出代码
2008/07/20 Javascript
javascript getElementsByName()的用法说明
2009/07/31 Javascript
Jquery选择子控件&quot;大于号&quot;和&quot; &quot;区别介绍及使用示例
2013/06/25 Javascript
Ubuntu中搭建Nodejs开发环境过程分享
2014/06/01 NodeJs
node.js中的fs.writeFile方法使用说明
2014/12/14 Javascript
原生js和jQuery写的网页选项卡特效对比
2015/04/27 Javascript
vue.js移动数组位置,同时更新视图的方法
2018/03/08 Javascript
jQuery+Cookie实现切换皮肤功能【附源码下载】
2018/03/25 jQuery
node.js中TCP Socket多进程间的消息推送示例详解
2018/07/10 Javascript
Vue.js组件间通信方式总结【推荐】
2018/11/23 Javascript
JS创建自定义对象的六种方法总结
2020/12/15 Javascript
[00:32]2018DOTA2亚洲邀请赛VG出场
2018/04/03 DOTA
Python模块学习 re 正则表达式
2011/05/19 Python
python控制台中实现进度条功能
2015/11/10 Python
python连接mysql实例分享
2016/10/09 Python
Python实现井字棋小游戏
2020/03/09 Python
Python基于codecs模块实现文件读写案例解析
2020/05/11 Python
python自动化测试三部曲之request+django实现接口测试
2020/10/07 Python
德国运动鞋网上商店:Afew Store
2018/01/05 全球购物
英国最出名高街品牌:Forever Unique
2018/02/24 全球购物
连锁酒店店长职责范本
2014/02/13 职场文书
房务中心文员岗位职责
2014/04/16 职场文书
解除劳动合同证明书
2014/09/26 职场文书
群众路线四风问题整改措施
2014/09/27 职场文书
走群众路线学习心得体会
2014/10/31 职场文书
高一军训决心书
2015/02/05 职场文书
2015年信贷员工作总结
2015/04/28 职场文书
英文诗歌翻译方法(赏析)
2019/08/16 职场文书
zabbix 代理服务器的部署与 zabbix-snmp 监控问题
2022/07/15 Servers