ThinkSSL🔒 一键申购 5分钟快速签发 30天无理由退款 购买更放心 广告
## 一、分页 > 非全家桶,基于vue.min.js ![](images/screenshot_1547629072835.png) data数据 ``` page: { cur: 1, // 当前页 total: 1, // 总页数 visible: 6, // 可见页数 search: '' // 搜索页 } ``` method方法 ``` // 切换页码 switchPage: function(pageNum) { if(1<=pageNum && pageNum<=this.page.total && pageNum!==this.page.cur) { this.page.cur = pageNum; this.params.page = pageNum; this.reqListData(); } } ``` · template模板渲染 ``` <div class="zh-page zh-page-black text-right zh-mt-20"> <div class="zh-page-content"> <ul> <li :class="{'zh-disabled': page.cur===1}" @click="switchPage(1)"><a href="javascript:;">首页</a></li> <li :class="{'zh-disabled': page.cur===1}" @click="switchPage(page.cur-1)"><a href="javascript:;">上一页</a></li> <template v-if="page.total <= page.visible"> <li v-for="(v,i) in page.total" :key="i" :class="{'zh-cur': page.cur===v}" @click="switchPage(v)"> <a href="javascript:;">{{ v }}</a> </li> </template> <template v-else> <template v-if="page.cur < page.visible-1"> <li v-for="(v,i) in page.visible-1" :key="i" :class="{'zh-cur': page.cur===v}" @click="switchPage(v)"> <a href="javascript:;">{{ v }}</a> </li> <li><a href="javascript:;">...</a></li> <li><a href="javascript:;" @click="switchPage(page.total)">{{ page.total }}</a></li> </template> <template v-else-if="page.cur >= page.visible-1"> <template v-if="page.total-page.cur <= page.visible-4"> <li><a href="javascript:;" @click="switchPage(1)">1</a></li> <li><a href="javascript:;">...</a></li> <li v-for="(v,i) in page.total" :key="i" :class="{'zh-cur': page.cur===v}" v-if="v >= page.total-(page.visible-2)" @click="switchPage(v)"> <a href="javascript:;">{{ v }}</a> </li> </template> <template v-else> <li><a href="javascript:;" @click="switchPage(1)">1</a></li> <li><a href="javascript:;">...</a></li> <li v-for="(v,i) in page.cur+1" :key="i" :class="{'zh-cur': page.cur===v}" v-if="v >= page.cur-(page.visible-4)" @click="switchPage(v)"> <a href="javascript:;">{{ v }}</a> </li> <li><a href="javascript:;">...</a></li> <li><a href="javascript:;" @click="switchPage(page.total)">{{ page.total }}</a></li> </template> </template> </template> <li :class="{'zh-disabled': page.cur===page.total}"><a href="javascript:;" @click="switchPage(page.cur+1)">下一页</a></li> <li :class="{'zh-disabled': page.cur===page.total}"><a href="javascript:;" @click="switchPage(page.total)">尾页</a></li> </ul> <span class="zh-total">共{{ page.total }}页</span> <div class="zh-skip"> <input type="text" v-model.trim.number="page.search"> <button class="zh-btn-blue" type="button" @click="switchPage(page.search)">跳转</button> </div> </div> </div> ``` ## 二、自定义toast > 基于全家桶 components/Toast/index.js ``` /* 自定义 toast 组件 调用 this.$toast('hello world~', {duration: 1500}) */ let _TOAST = { show: false, // 存储toast显示状态 vm: null // 存储toast vm }; export default { install(Vue) { // toast Vue.prototype.$toast = function(text, opts) { let defaultOpts = { position: 'bottom', duration: 2500, wordWrap: false, // width: '90%' }; opts = Object.assign(defaultOpts, opts); let wordWrap = opts.wordWrap ? 'zh-word-wrap' : '', style = opts.width ? `style="width: ${opts.width}"` : ''; if (_TOAST.show) { return; } if (!_TOAST.vm) { let toastTpl = Vue.extend({ data: function() { return { show: _TOAST.show, text: text, position: `zh-toast-${opts.position}` } }, template: `<div v-show="show" :class="position" class="zh-toast ${wordWrap}" ${style}>{{text}}</div>` }); _TOAST.vm = new toastTpl(); let element = _TOAST.vm.$mount().$el; document.body.appendChild(element); } _TOAST.vm.position = 'zh-toast-' + opts.position; _TOAST.vm.text = text; _TOAST.vm.show = _TOAST.show = true; setTimeout(function() { _TOAST.vm.show = _TOAST.show = false; }, opts.duration) }; } } ``` components/Toast/index.css ``` .zh-toast { position: fixed; bottom: 100px; left: 50%; box-sizing: border-box; max-width: 80%; height: 40px; line-height: 20px; padding: 10px 20px; transform: translateX(-50%); -webkit-transform: translateX(-50%); text-align: center; z-index: 9999; font-size: 14px; color: #fff; border-radius: 5px; background: rgba(0, 0, 0, 0.7); animation: show-toast .5s; -webkit-animation: show-toast .5s; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .zh-toast.zh-word-wrap { width: 80%; white-space: inherit; height: auto; } .zh-toast.zh-toast-top { top: 50px; bottom: inherit; } .zh-toast.zh-toast-center { top: 50%; margin-top: -20px; bottom: inherit; } @keyframes show-toast { from { opacity: 0; transform: translate(-50%, -10px); -webkit-transform: translate(-50%, -10px); } to { opacity: 1; transform: translate(-50%, 0); -webkit-transform: translate(-50%, 0); } } ``` main.js ``` // Toast import './components/Toast/index.css'; import Toast from './components/Toast/index'; Vue.use(Toast); ``` ## 三、自定义loading > 基于全家桶 components/Loading/index.js ``` /* 自定义 loading 组件 调用 this.$loading('正在加载中...'); this.$loading.close(); */ let _LOADING = { show: false, // 存储loading显示状态 node: null // 存储loading节点元素 }; export default { install(Vue) { // loading Vue.prototype.$loading = function(text, type) { if (type == 'close') { _LOADING.node.show = _LOADING.show = false; } else { if (_LOADING.show) { return; } let loadTpl = Vue.extend({ data: function() { return { show: _LOADING.show } }, template: `<div v-show="show" class="zh-load-mark"> <div class="zh-load-box"> <div class="zh-loading"> <div class="loading_leaf loading_leaf_0"></div> <div class="loading_leaf loading_leaf_1"></div> <div class="loading_leaf loading_leaf_2"></div> <div class="loading_leaf loading_leaf_3"></div> <div class="loading_leaf loading_leaf_4"></div> <div class="loading_leaf loading_leaf_5"></div> <div class="loading_leaf loading_leaf_6"></div> <div class="loading_leaf loading_leaf_7"></div> <div class="loading_leaf loading_leaf_8"></div> <div class="loading_leaf loading_leaf_9"></div> <div class="loading_leaf loading_leaf_10"></div> <div class="loading_leaf loading_leaf_11"></div> </div> <div class="zh-load-content">${text}</div> </div> </div>` }); _LOADING.node = new loadTpl(); let element = _LOADING.node.$mount().$el; document.body.appendChild(element); _LOADING.node.show = _LOADING.show = true; } }; // loading 打开/关闭 ['open', 'close'].forEach(function(type) { Vue.prototype.$loading[type] = function(text) { return Vue.prototype.$loading(text, type); } }); } } ``` components/Loading/index.css ``` .zh-load-mark { position: fixed; left: 0; top: 0; width: 100%; height: 100%; z-index: 9999; } .zh-load-box { position: fixed; z-index: 3; width: 7.6em; min-height: 7.6em; top: 180px; left: 50%; margin-left: -3.8em; background: rgba(0, 0, 0, 0.7); text-align: center; border-radius: 5px; color: #FFFFFF; } .zh-load-content { margin-top: 64%; font-size: 14px; } .zh-loading { position: absolute; width: 0px; left: 50%; top: 38%; } .loading_leaf { position: absolute; top: -1px; opacity: 0.25; } .loading_leaf:before { content: " "; position: absolute; width: 9.14px; height: 3.08px; background: #d1d1d5; box-shadow: rgba(0, 0, 0, 0.0980392) 0px 0px 1px; border-radius: 1px; -webkit-transform-origin: left 50% 0px; transform-origin: left 50% 0px; } .loading_leaf_0 { -webkit-animation: opacity-0 1.25s linear infinite; animation: opacity-0 1.25s linear infinite; } .loading_leaf_0:before { -webkit-transform: rotate(0deg) translate(7.92px, 0px); transform: rotate(0deg) translate(7.92px, 0px); } .loading_leaf_1 { -webkit-animation: opacity-1 1.25s linear infinite; animation: opacity-1 1.25s linear infinite; } .loading_leaf_1:before { -webkit-transform: rotate(30deg) translate(7.92px, 0px); transform: rotate(30deg) translate(7.92px, 0px); } .loading_leaf_2 { -webkit-animation: opacity-2 1.25s linear infinite; animation: opacity-2 1.25s linear infinite; } .loading_leaf_2:before { -webkit-transform: rotate(60deg) translate(7.92px, 0px); transform: rotate(60deg) translate(7.92px, 0px); } .loading_leaf_3 { -webkit-animation: opacity-3 1.25s linear infinite; animation: opacity-3 1.25s linear infinite; } .loading_leaf_3:before { -webkit-transform: rotate(90deg) translate(7.92px, 0px); transform: rotate(90deg) translate(7.92px, 0px); } .loading_leaf_4 { -webkit-animation: opacity-4 1.25s linear infinite; animation: opacity-4 1.25s linear infinite; } .loading_leaf_4:before { -webkit-transform: rotate(120deg) translate(7.92px, 0px); transform: rotate(120deg) translate(7.92px, 0px); } .loading_leaf_5 { -webkit-animation: opacity-5 1.25s linear infinite; animation: opacity-5 1.25s linear infinite; } .loading_leaf_5:before { -webkit-transform: rotate(150deg) translate(7.92px, 0px); transform: rotate(150deg) translate(7.92px, 0px); } .loading_leaf_6 { -webkit-animation: opacity-6 1.25s linear infinite; animation: opacity-6 1.25s linear infinite; } .loading_leaf_6:before { -webkit-transform: rotate(180deg) translate(7.92px, 0px); transform: rotate(180deg) translate(7.92px, 0px); } .loading_leaf_7 { -webkit-animation: opacity-7 1.25s linear infinite; animation: opacity-7 1.25s linear infinite; } .loading_leaf_7:before { -webkit-transform: rotate(210deg) translate(7.92px, 0px); transform: rotate(210deg) translate(7.92px, 0px); } .loading_leaf_8 { -webkit-animation: opacity-8 1.25s linear infinite; animation: opacity-8 1.25s linear infinite; } .loading_leaf_8:before { -webkit-transform: rotate(240deg) translate(7.92px, 0px); transform: rotate(240deg) translate(7.92px, 0px); } .loading_leaf_9 { -webkit-animation: opacity-9 1.25s linear infinite; animation: opacity-9 1.25s linear infinite; } .loading_leaf_9:before { -webkit-transform: rotate(270deg) translate(7.92px, 0px); transform: rotate(270deg) translate(7.92px, 0px); } .loading_leaf_10 { -webkit-animation: opacity-10 1.25s linear infinite; animation: opacity-10 1.25s linear infinite; } .loading_leaf_10:before { -webkit-transform: rotate(300deg) translate(7.92px, 0px); transform: rotate(300deg) translate(7.92px, 0px); } .loading_leaf_11 { -webkit-animation: opacity-11 1.25s linear infinite; animation: opacity-11 1.25s linear infinite; } .loading_leaf_11:before { -webkit-transform: rotate(330deg) translate(7.92px, 0px); transform: rotate(330deg) translate(7.92px, 0px); } @-webkit-keyframes opacity-0 { 0% { opacity: 0.25; } 0.01% { opacity: 0.25; } 0.02% { opacity: 1; } 60.01% { opacity: 0.25; } 100% { opacity: 0.25; } } @-webkit-keyframes opacity-1 { 0% { opacity: 0.25; } 8.34333% { opacity: 0.25; } 8.35333% { opacity: 1; } 68.3433% { opacity: 0.25; } 100% { opacity: 0.25; } } @-webkit-keyframes opacity-2 { 0% { opacity: 0.25; } 16.6767% { opacity: 0.25; } 16.6867% { opacity: 1; } 76.6767% { opacity: 0.25; } 100% { opacity: 0.25; } } @-webkit-keyframes opacity-3 { 0% { opacity: 0.25; } 25.01% { opacity: 0.25; } 25.02% { opacity: 1; } 85.01% { opacity: 0.25; } 100% { opacity: 0.25; } } @-webkit-keyframes opacity-4 { 0% { opacity: 0.25; } 33.3433% { opacity: 0.25; } 33.3533% { opacity: 1; } 93.3433% { opacity: 0.25; } 100% { opacity: 0.25; } } @-webkit-keyframes opacity-5 { 0% { opacity: 0.270958333333333; } 41.6767% { opacity: 0.25; } 41.6867% { opacity: 1; } 1.67667% { opacity: 0.25; } 100% { opacity: 0.270958333333333; } } @-webkit-keyframes opacity-6 { 0% { opacity: 0.375125; } 50.01% { opacity: 0.25; } 50.02% { opacity: 1; } 10.01% { opacity: 0.25; } 100% { opacity: 0.375125; } } @-webkit-keyframes opacity-7 { 0% { opacity: 0.479291666666667; } 58.3433% { opacity: 0.25; } 58.3533% { opacity: 1; } 18.3433% { opacity: 0.25; } 100% { opacity: 0.479291666666667; } } @-webkit-keyframes opacity-8 { 0% { opacity: 0.583458333333333; } 66.6767% { opacity: 0.25; } 66.6867% { opacity: 1; } 26.6767% { opacity: 0.25; } 100% { opacity: 0.583458333333333; } } @-webkit-keyframes opacity-9 { 0% { opacity: 0.687625; } 75.01% { opacity: 0.25; } 75.02% { opacity: 1; } 35.01% { opacity: 0.25; } 100% { opacity: 0.687625; } } @-webkit-keyframes opacity-10 { 0% { opacity: 0.791791666666667; } 83.3433% { opacity: 0.25; } 83.3533% { opacity: 1; } 43.3433% { opacity: 0.25; } 100% { opacity: 0.791791666666667; } } @-webkit-keyframes opacity-11 { 0% { opacity: 0.895958333333333; } 91.6767% { opacity: 0.25; } 91.6867% { opacity: 1; } 51.6767% { opacity: 0.25; } 100% { opacity: 0.895958333333333; } } ``` main.js ``` // Loading import './components/Loading/index.css'; import Loading from './components/Loading/index'; Vue.use(Loading); ```