最近用 mint-ui 實現了上拉加載更多和下拉刷新,正好今天有空就把實現過程都給記錄下來,下面我準備來個小白教程。css
我這個利用vue單頁和普通頁面方式展現。html
一、首先用腳手架 vue-cli 搭建環境(這裏我百度找了一個算看到舒服的教程,僅供參考)vue
二、Mint-UI (這裏官網快速上手,能夠根據裏面的教程快速的添加 mint-ui 到項目中去,圖片和代碼看都有,推薦本身看圖手敲代碼)webpack
.babelrc文件git
{ "presets": [ ["env", { "modules": false, "targets": { "browsers": ["> 1%", "last 2 versions", "not ie <= 8"] } }], "stage-2" ], "plugins": ["transform-vue-jsx", "transform-runtime", ["component", [ { "libraryName": "mint-ui", "style": true } ] ] ] }
main.jsgithub
// The Vue build version to load with the `import` command // (runtime-only or standalone) has been set in webpack.base.conf with an alias. import Vue from 'vue' import App from './App' import router from './router' import { Loadmore } from 'mint-ui' Vue.component(Loadmore.name, Loadmore); Vue.config.productionTip = false /* eslint-disable no-new */ new Vue({ el: '#app', router, components: { App }, template: '<App/>' })
HelloWorld.vue(頁面就直接上代碼截圖太長了,裏面用的圖片[chicken-wings.jpg, swine-fever.jpg]我是百度的須要圖片的本身找, 另外這兩張圖都是直接放在 static 文件夾)web
<template> <div class="hello"> <mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" @top-status-change="handleTopChange" @bottom-status-change="handleBottomChange" :autoFill="false" ref="loadmore" > <ul> <li class="order-intr clearfix" v-for="(item, index) in list" :key="index"> <img class="fl" :src="item.cover"> <div class="title fl"> <h3>{{item.title}}</h3> <p>數量:{{item.num}}</p> </div> <b class="fr price">¥{{item.price}}</b> </li> </ul> <div slot="top" class="mint-loadmore-top"> <span v-show="topStatus !== 'loading'" :class="{ 'rotate': topStatus === 'drop' }">鬆手釋放↓</span> <span v-show="topStatus === 'loading'">加載中</span> </div> <div slot="bottom" class="mint-loadmore-bottom"> <span v-show="bottomStatus !== 'loading'" :class="{ 'rotate': bottomStatus === 'drop' }" >鬆手釋放↑</span> <span v-show="bottomStatus === 'loading'">加載中</span> </div> <p v-if="allLoaded" class="to-the-bottom">我是有底線的</p> </mt-loadmore> </div> </template> <script> export default { name: "HelloWorld", data() { return { topStatus: "", bottomStatus: "", allLoaded: false, list: [], mockArr: [], number: 0 }; }, created() { // ajax 模擬初始加載, 使用定時器默認ajax加載 let timer = setTimeout(_ => { clearTimeout(timer); this.loadData('refresh'); }, 200); }, methods: { loadData(p_status) { // 第一次加載或者下拉刷新最新數據 if (p_status === "refresh") { this.mockArr = []; } for (let i = 0; i < 5; ) { let obj = { cover: "./static/chicken-wings.jpg", title: "奧爾良雞中翅飯", num: 1, price: 14.88 }; obj["id"] = this.mockArr.length + 1; if (i % 2) { obj["cover"] = "./static/swine-fever.jpg"; obj["title"] = "豬扒飯"; obj["num"] += 1; obj["price"] -= 1; } i++; this.mockArr.push(obj); } this.list = this.mockArr; }, handleTopChange(p_status) { this.topStatus = p_status; }, handleBottomChange(p_status) { this.bottomStatus = p_status; }, loadBottom() { // 一次下拉加載5條更多數據,使用定時器默認ajax加載 this.loadData() this.number++; // allLoaded 設置爲 true 時,表示數據已所有獲取完畢不須要再出現上拉加載更多 if (this.number === 3) { this.allLoaded = true; } this.$refs.loadmore.onBottomLoaded(); }, loadTop() { // 默認下拉刷新最新數據 this.loadData("refresh"); this.number = 0; this.allLoaded = false; this.$refs.loadmore.onTopLoaded(); } } }; </script> <style> * { margin: 0; padding: 0; box-sizing: border-box; } /* 這裏直接設置 1rem = 50px begin */ html { font-size: 50px; } /* 這裏直接設置 1rem = 50px end */ html, body { font-family: "微軟雅黑"; color: #333; background: #fff; } ul, li { list-style: none; } /* 給要上拉的容器設置 begin */ .hello { height: 100vh; overflow-y: auto; } /* 給要上拉的容器設置 end */ .fl { float: left; } .fr { float: right; } .clearfix::before, .clearfix::after { content: ""; display: block; overflow: hidden; clear: both; visibility: hidden; } li { background: #fff; } .order-intr { position: relative; padding: 0.3rem 0.4rem; width: calc(100% - 0.6rem); margin: 0.4rem auto; border: 0.02rem solid #666; border-radius: 0.16rem; } .order-intr img { width: 3rem; height: 2.4rem; } .title { margin-left: 0.24rem; text-align: left; } .title h3 { font-size: 0.4rem; } .title p { font-size: 0.3rem; } .price { position: absolute; right: 0.3rem; bottom: 0.3rem; font-size: 0.5rem; color: #fe696b; } .mint-loadmore-top, .mint-loadmore-bottom { font-size: 0.28rem; } /* 我是有底線的 begin */ .to-the-bottom { position: relative; color: #999999; font-size: 0.32rem; text-align: center; padding: 0.1rem 0; background: #f1eded; } .to-the-bottom::before, .to-the-bottom::after { position: absolute; top: 50%; height: 0.02rem; width: 25%; margin-top: -0.01rem; background: #999; content: ""; } .to-the-bottom::before { left: 10%; } .to-the-bottom::after { right: 10%; } /* 我是有底線的 end */ </style>
三、最後來一個單頁代碼(圖片本身找,圖片路徑也能夠本身改)ajax
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>loadmore</title> <!-- 引入樣式 --> <link rel="stylesheet" href="https://unpkg.com/mint-ui/lib/style.css"> <style> * { margin: 0; padding: 0; box-sizing: border-box; } /* 這裏直接設置 1rem = 50px begin */ html { font-size: 50px; } /* 這裏直接設置 1rem = 50px end */ html, body { font-family: "微軟雅黑"; color: #333; background: #fff; } ul, li { list-style: none; } /* 給要上拉的容器設置 begin */ .data-list { height: 100vh; overflow-y: auto; } /* 給要上拉的容器設置 end */ .fl { float: left; } .fr { float: right; } .clearfix::before, .clearfix::after { content: ""; display: block; overflow: hidden; clear: both; visibility: hidden; } li { background: #fff; } .order-intr { position: relative; padding: 0.3rem 0.4rem; width: calc(100% - 0.6rem); margin: 0.4rem auto; border: 0.02rem solid #666; border-radius: 0.16rem; } .order-intr img { width: 3rem; height: 2.4rem; } .title { margin-left: 0.24rem; text-align: left; } .title h3 { font-size: 0.4rem; } .title p { font-size: 0.3rem; } .price { position: absolute; right: 0.3rem; bottom: 0.3rem; font-size: 0.5rem; color: #fe696b; } .mint-loadmore-top, .mint-loadmore-bottom { font-size: 0.28rem; } /* 我是有底線的 begin */ .to-the-bottom { position: relative; color: #999999; font-size: 0.32rem; text-align: center; padding: 0.1rem 0; background: #f1eded; } .to-the-bottom::before, .to-the-bottom::after { position: absolute; top: 50%; height: 0.02rem; width: 25%; margin-top: -0.01rem; background: #999; content: ""; } .to-the-bottom::before { left: 10%; } .to-the-bottom::after { right: 10%; } /* 我是有底線的 end */ </style> </head> <body> <div id="app"> <div class="data-list"> <mt-loadmore :top-method="loadTop" :bottom-method="loadBottom" :bottom-all-loaded="allLoaded" @top-status-change="handleTopChange" @bottom-status-change="handleBottomChange" :autoFill="false" ref="loadmore"> <ul> <li class="order-intr clearfix" v-for="(item, index) in list" :key="index"> <img class="fl" :src="item.cover"> <div class="title fl"> <h3>{{item.title}}</h3> <p>數量:{{item.num}}</p> </div> <b class="fr price">¥{{item.price}}</b> </li> </ul> <div slot="top" class="mint-loadmore-top"> <span v-show="topStatus !== 'loading'" :class="{ 'rotate': topStatus === 'drop' }">鬆手釋放↓</span> <span v-show="topStatus === 'loading'">加載中</span> </div> <div slot="bottom" class="mint-loadmore-bottom"> <span v-show="bottomStatus !== 'loading'" :class="{ 'rotate': bottomStatus === 'drop' }">鬆手釋放↑</span> <span v-show="bottomStatus === 'loading'">加載中</span> </div> <p v-if="allLoaded" class="to-the-bottom">我是有底線的</p> </mt-loadmore> </div> </div> <!-- 先引入 Vue --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <!-- 引入組件庫 --> <script src="https://unpkg.com/mint-ui/lib/index.js"></script> <script> let vm = new Vue({ el: '#app', data() { return { topStatus: "", bottomStatus: "", allLoaded: false, list: [], mockArr: [], number: 0 }; }, created() { // ajax 模擬初始加載, 使用定時器默認ajax加載 let timer = setTimeout(_ => { clearTimeout(timer); this.loadData('refresh'); }, 200); }, methods: { loadData(p_status) { // 第一次加載或者下拉刷新最新數據 if (p_status === "refresh") { this.mockArr = []; } for (let i = 0; i < 5;) { let obj = { cover: "./static/chicken-wings.jpg", title: "奧爾良雞中翅飯", num: 1, price: 14.88 }; obj["id"] = this.mockArr.length + 1; if (i % 2) { obj["cover"] = "./static/swine-fever.jpg"; obj["title"] = "豬扒飯"; obj["num"] += 1; obj["price"] -= 1; } i++; this.mockArr.push(obj); } this.list = this.mockArr; }, handleTopChange(p_status) { this.topStatus = p_status; }, handleBottomChange(p_status) { this.bottomStatus = p_status; }, loadBottom() { // 一次下拉加載5條更多數據,使用定時器默認ajax加載 this.loadData() this.number++; // allLoaded 設置爲 true 時,表示數據已所有獲取完畢不須要再出現上拉加載更多 if (this.number === 3) { this.allLoaded = true; } this.$refs.loadmore.onBottomLoaded(); }, loadTop() { // 默認下拉刷新最新數據 this.loadData("refresh"); this.number = 0; this.allLoaded = false; this.$refs.loadmore.onTopLoaded(); } } }) </script> </body> </html>
這是 demo 百度雲盤連接vue-cli
連接: https://pan.baidu.com/s/1NSOQA8gU0rg20QqL2iPW8g babel
提取碼: mhpp
下面是官方對於refs的說明:
如何解決上面的報錯,我這裏推薦使用先判斷在執行
this.$refs.loadmore && this.$refs.loadmore.onTopLoaded();