J'étudie vue.js depuis un moment et je l'ai utilisé pour créer deux petits composants pour m'entraîner.
J'utilise webpack pour l'emballage ici, je connais donc son utilisation.
Le code source est placé à l'adresse github à la fin de l'article.
Le premier est 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>
J'ai mis le composant de l'application dans
let Vue = require('vue'); import App from './components/app'; let app_vue = new Vue({ el: '#main', components: { app: App } });
Jetons un coup d'œil dans cette application, composant suivant
<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>
Il comporte deux sous-composants, à savoir comment.vue et page.vue, qui communiquent entre les composants parent et enfant via liaison dynamique des données. Je pense que oui. La page actuelle doit être transmise de page.vue à app.vue, nous utilisons donc ici la liaison bidirectionnelle, comme les paramètres, l'URL, isSync, c'est-à-dire ce qui demande des données. l'arrière-plan et s'il est synchronisé. Ou un fonctionnement asynchrone
Ensuite, jetez un œil au composant de commentaire 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>
Le getData.js ici sera mentionné ci-dessous et c'est là que nous obtenons les données.
chargement : l'intention initiale est de charger un masque avec une transparence de 0,5 pour le commentaire actuel lors du passage au numéro de page pour charger les commentaires, puis ajax annule le masque via sa fonction de rappel. Maintenant, cela ne peut pas être réalisé et peut. seulement être forcé d'écrire, mais cela ne sert à rien..
hasComment : Lorsque le composant de commentaire est chargé pour la première fois, nous demanderons la longueur totale des données. S'il n'y a pas de données, le contenu de la mise en page du composant de commentaire le sera. ne pas être affiché
·curPageIndex· : il est transmis via l'application du composant parent et utilise les données props
. Il est préférable pour nous de définir une valeur et un type par défaut.
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>
est principalement une application d'événements de composants, = l'événement de clic le plus courant, et la liaison de classe et de style, selon curPageIndex et ceci. pageIndex Pour comparer et déterminer si vous disposez de cette classe, utilisez l'attribut calculé pour obtenir le tableau des numéros de page. Comme il changera en fonction de la page actuelle, le numéro de page total est calculé lors de la création.
Le dernier est le fichier js actuellement généré pour obtenir des données statiques
// 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); }
C'est tout.
Pour plus d'articles sur l'utilisation de vue.js pour créer des composants de pagination, veuillez faire attention au site Web PHP chinois !