使用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 相关文章推荐
Jquery实战_读书笔记2 选择器
Jan 22 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
Oct 20 Javascript
JavaScript将字符串转换成字符编码列表的方法
Mar 19 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
Sep 10 Javascript
JS+CSS实现类似QQ好友及黑名单效果的树型菜单
Sep 22 Javascript
jquery广告无缝轮播实例
Jan 05 Javascript
聊聊JavaScript如何实现继承及特点
Apr 07 Javascript
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
vue router下的html5 history在iis服务器上的设置方法
Oct 18 Javascript
webpack4 配置 ssr 环境遇到“document is not defined”
Oct 24 Javascript
JS实现星星海特效
Dec 24 Javascript
JavaScript实现班级抽签小程序
May 19 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
PHP 类型转换函数intval
2009/06/20 PHP
PHP处理excel cvs表格的方法实例介绍
2013/05/13 PHP
php通过字符串调用函数示例
2014/03/02 PHP
php去除二维数组的重复项方法
2015/11/03 PHP
php源码之将图片转化为data/base64数据流实例详解
2016/11/27 PHP
载入进度条 效果
2006/07/08 Javascript
js中判断文本框是否为空的两种方法
2011/07/31 Javascript
jQuery设置和获取HTML、文本和值示例
2014/07/08 Javascript
JavaScript监听文本框回车事件并过滤文本框空格的方法
2015/04/16 Javascript
javascript实现将文件保存到本地方法汇总
2015/07/26 Javascript
JS跨域解决方案之使用CORS实现跨域
2016/04/14 Javascript
flag和jq on 的绑定多个对象和方法(必看)
2017/02/27 Javascript
vue中使用cropperjs的方法
2018/03/01 Javascript
JS实现的RC4加密算法示例
2018/08/16 Javascript
js实现类似iphone的网页滑屏解锁功能示例【附源码下载】
2019/06/10 Javascript
用js实现放大镜效果
2020/10/28 Javascript
Python的socket模块源码中的一些实现要点分析
2016/06/06 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
2017/08/24 Python
python 获取文件下所有文件或目录os.walk()的实例
2018/04/23 Python
在django中使用post方法时,需要增加csrftoken的例子
2020/03/13 Python
如何表示python中的相对路径
2020/07/08 Python
Python3如何使用多线程升程序运行速度
2020/08/11 Python
CSS3属性box-shadow使用指南
2014/12/09 HTML / CSS
台湾时尚彩瞳专门店:imeime
2019/08/16 全球购物
Deux par Deux官方网站:设计师童装
2020/01/03 全球购物
荷兰天然和有机产品网上商城:BigGreenSmile.nl
2020/07/26 全球购物
UML设计模式笔试题
2014/06/07 面试题
请问软件开发中的设计模式你会使用哪些
2015/05/13 面试题
学生干部学习的自我评价
2014/02/18 职场文书
企业消防安全责任书
2014/07/23 职场文书
学习十八大的心得体会
2014/09/01 职场文书
机电专业毕业生自我鉴定2014
2014/10/04 职场文书
2014年外贸业务员工作总结
2014/12/11 职场文书
学习焦裕禄观后感
2015/06/09 职场文书
电脑关机速度很慢怎么办 提升电脑关机速度设置教程
2022/04/08 数码科技
微信小程序 根据不同用户切换不同TabBar
2022/04/21 Javascript