基于vant UI 写一个具备下拉刷新上滑加载及搜索功能的列表

1,575 阅读4分钟

效果图

1.安装vant

通过npm安装   npm i vant -S
通过yarn安装  yarn add vant

2.引入组件

自动按需引入组件
babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式

3.安装插件

npm i babel-plugin-import -D

// 在.babelrc 中添加配置
// 注意:webpack 1 无需设置 libraryDirectory
{
  "plugins": [
    ["import", {
      "libraryName": "vant",
      "libraryDirectory": "es",
      "style": true
    }]
  ]
}

4.在main.js中

import Vue from 'vue';
import { PullRefresh } from 'vant';

Vue.use(PullRefresh);

在页面中使用:
<van-pull-refresh v-model="isLoading" @refresh="onRefresh">
  <p>刷新次数: {{ count }}</p>
</van-pull-refresh>

也可以在页面中单独引用同引入自定义组件的方式

// 引入 vant UI库
import { DatetimePicker, Popup, List, PullRefresh } from 'vant';

components: {
    DatetimePicker,
    Popup,
    List,
    PullRefresh
},

5.html代码

<!-- 账单列表 -->
<pull-refresh v-model="refreshLoading" @refresh="onRefresh" :success-text='successText'>
    <list :immediate-check="false" v-model="loading" :finished="finished" :finished-text="finishedText" @load="onLoad">
        <div class="list-wrap month-order-list" v-for="(item, index) in orderData" :key="index">
            <div class="list-header">
                <div class="date" @click="endTimePop=true">{{item.year}}年{{item.month}}月<span class="icon-triangle"></span></div>
                <div class="budget">支出&nbsp;&nbsp;¥{{item.pay | formatMoney}}&nbsp;&nbsp;&nbsp;&nbsp;收入&nbsp;&nbsp;¥{{item.income | formatMoney}} </div>
            </div>
            <div class="bills-container">
                <BillItem v-for="(v, idx) in item.lists" :key="idx" :data-list="v" @gotoDetail="gotoDetail(v)" />
            </div>
        </div>
    </list>
</pull-refresh>
    

<script>
// 引入 vant UI库
import { DatetimePicker, Popup, List, PullRefresh } from 'vant';
import Loading from '@/components/mfbLoading'
import BillItem from './components/BillItem';
import { formatDate, formatMoney } from '../../assets/js/common.js';
export default {
    name: 'billsList',
    components: {
        Loading,
        BillItem,
        DatetimePicker,
        Popup,
        List,
        PullRefresh
    },
    filters: {
      // 金额格式化
      formatMoney (time) {
        return formatMoney(time)
      }
    },
    data() {
        return {
            finishedText: '没有更多了',
            // 上滑加载的 loading
            loading: false,
            // 控制是否加载完
            finished: false,
            refreshLoading: false,
            isLoading: false,
            successText: '',
            minDate: new Date(2016,10),
            maxDate: new Date(),
            currentDate: new Date(),
            endTimePop: false, // 控制日期弹层的显示和隐藏
            startDate: '', //选中月份的第一天 2019-08-01 00:00:00
            endDate: '', //选中月份的最后一天 2019-08-31 23:59:00
            end_time:'',
            userNo: '',
            merchantNo: '',
            formatCurDate: '',
            billType: '', // 账单类型
            noPageRecords: false,
            isShowDrawer: false,
            orderData: [],
            searchBarFixed: false,
            // 页数
            pageIndex: 0,
            pageSize: 30,
            screenCondition: [
                {
                    billType: '',
                    name: '全部'
                },{
                    billType: '093',
                    name: '消费'
                },{
                    billType: '050',
                    name: '退款'
                },{
                    billType: '010',
                    name: '充值'
                },{
                    billType: '020',
                    name: '提现'
                },

            ],
        }
    },
    created() {
        this.$parent.setNavBar('筛选');
        this.formatCurDate = formatDate(new Date(), "yyyy-MM-dd hh:mm:ss")
        this._getBillsList('', this.formatCurDate, '', 1, '',
            res => {
                let data = res.transactionList;
                this.orderData = this.formatList(data)
            })
    },
    computed: {
        fixedTitle() {
            return this.orderData.map((group) => {
                return `${group.year + '年' + group.month + '月'}`
            })
        },
        payAmount() {
            return this.orderData.map((group) => {
                return group.pay
            })
        },
        incomeAmount() {
            return this.orderData.map((group) => {
                return group.income
            })
        }
    },
    methods: {
        // 上滑加载函数
        onLoad() {
            let newData = null;
            let sameMonthData = null;
            if (this.endDate == '') {
                this.endDate = this.formatCurDate
            }
            this._getBillsList(this.startDate, this.endDate, this.billType, 1, 3,
                (res) => {
                    let data = res.transactionList;
                    newData = this.formatList(data);
                    if (this.orderData[this.orderData.length - 1].year == newData[0].year && this.orderData[this.orderData.length - 1].month == newData[0].month) {
                        sameMonthData = newData[0].lists;
                        newData.shift();
                        this.orderData[this.orderData.length - 1].lists = this.orderData[this.orderData.length - 1].lists.concat(sameMonthData);
                    }
                    this.orderData = this.orderData.concat(newData);
                    this.loading = false;
                }
            )
        },
        onRefresh() {
            this.pageIndex = 0
            this._getBillsList('', this.formatCurDate, '', 5, 3,
                res => {
                    // this.finished = false
                    let data = res.transactionList;
                    this.orderData = this.formatList(data)
                }
            )
        },
        endTimeChange(e) {
            let endTimeArr = e.getValues();//["2019", "03", "22", "17", "28"]
            this.end_time = `${endTimeArr[0].substring(0,4)}-${endTimeArr[1].substring(0,2)}`
            if (this.end_time.substring(5,6) == '0') {
                this.end_time = `${endTimeArr[0].substring(0,4)}-${endTimeArr[1].substr(1,1)}`
            } else {
                this.end_time = `${endTimeArr[0].substring(0,4)}-${endTimeArr[1].substring(0,2)}`
            }
            this.startDate = this.getCurrentMonthFirst(this.end_time) + ' ' + '00:00:00'
            this.endDate = formatDate(this.getCurrentMonthLast(this.end_time), "yyyy-MM-dd hh:mm:ss")
        },
        confirmDate() {
            if (this.startDate == '' && this.endDate == '') {
                this.startDate = this.getCurrentMonthFirst(this.currentDate) + ' ' + '00:00:00' 
                this.endDate = formatDate(this.getCurrentMonthLast(this.currentDate), "yyyy-MM-dd hh:mm:ss")
            }
            this.endTimePop = false
            this.pageIndex = 0
            // 选择日期时 需要传入所选月份的第一天和最后一天
            this._getBillsList(this.startDate, this.endDate, '', 5, '', res => {
                let data = res.transactionList;
                this.orderData = this.formatList(data)
            })
        },
        formatter(type, value) {
            if (type === 'year') {
                return `${value}年`;
            } else if (type === 'month') {
                return `${value}月`
            }
            return value;
        },
        // 头部'筛选按钮'
        addAction() {
            this.isShowDrawer = true
        },
        // 点击 '筛选条件'
        selectCondition(item) {
            this.pageIndex = 0
            this.isShowDrawer = false
            this.billType = item.billType
            this._getBillsList('', this.formatCurDate, this.billType, 5, '', res => {
                let data = res.transactionList;
                this.orderData = this.formatList(data)
            })
        },
        // 获取账单列表数据  type=5时 是点击筛选按钮 选择筛选条件
        _getBillsList(startTime,endTime,transactionTag, type, isShowLoading,fn) {
            // if (type !== 5) {
                ++this.pageIndex;
            // }
            if (isShowLoading != '3') {
                this.isLoading = true
            }
            this.$post({
            url: this.$api.getBillList,
            data: {
                pageNo: this.pageIndex,
                pageSize: this.pageSize,
                startTime,
                endTime,
                transactionTag // 传空的时表示查询全部账单列表
            },
            callback: res => {
                let data = res.transactionList;
                if (this.pageIndex == 1 && data.length == 0) {
                    this.noPageRecords = true
                    this.finishedText = ''
                    this.isLoading = false
                    this.orderData = data;
                    this.finished = true;
                } else {
                    this.refreshLoading = false
                    this.noPageRecords = false
                    this.successText = '刷新成功'
                    this.isLoading = false
                    if (data.length == 0) {
                        this.finished = true;
                        return;
                    } else if (0 < data.length && data.length < this.pageSize) {
                        this.finished = true;
                    }
                    fn(res);
                }
                this.isFinished = true;
            },
            noRespondBack: () => {
                this.isLoading = false
                this.orderData = [];
                this.isFinished = true;
                this.finished = true;
            }
            })
        },
        // 处理订单数据
        formatList(arr) {
            let currYear = 0;
            let currMonth = 0;
            let index = 0;
            let tmpObj = {
                year: 0,
                month: 0,
                lists: []
            };
            let result = [];
            function createObj(year, month) {
                currYear = year;
                currMonth = month;
                ++index;
                result[index] = JSON.parse(JSON.stringify(tmpObj));
                result[index].year = year;
                result[index].month = month;
            }
            arr.forEach(v => {
                let date = v.createTime.split(' ')[0];
                let year = new Date(date).getFullYear();
                let month = new Date(date).getMonth() + 1;
                if (year == currYear) {
                    if (month == currMonth) {
                        result[index].lists.push(v);
                    } else {
                        createObj(year, month);
                        result[index].lists.push(v);
                    }
                } else {
                    createObj(year, month);
                    result[index].lists.push(v);
                }
            });
            result.shift();
            return result;
        },
        gotoDetail(list) {
            this.$router.push({
                path: '/bills/billDetail',
                query: {
                    ...list
                }
            })
        },
        //获取所选月份的第一天
        getCurrentMonthFirst(month) {
            var date = new Date(month)
            date.setDate(1)
            var month = parseInt(date.getMonth() + 1)
            var day = date.getDate()
            if (month < 10) {
                month = '0' + month
            }
            if (day < 10) {
                day = '0' + day
            }
            return date.getFullYear() + '-' + month + '-' + day
        },
         //获取所选月份的最后一天
        getCurrentMonthLast(val) {
            let endDate = new Date(val)
            let month = endDate.getMonth()
            let nextMonth = ++ month
            let nextMonthFirstDay = new Date(endDate.getFullYear(),nextMonth, 1)
            let oneDay = 1000 * 60
            return new Date(nextMonthFirstDay - oneDay)
        }
    },
    watch: {
        // 根据订单数据变化,改变保存选择月份的数据
        orderData: {&emsp;&emsp;&emsp;&emsp;
            handler(newValue, oldValue) {
                for(let i = 0; i < newValue.length; i++) {
                    let obj = {};
                    let arry = newValue[i].lists
                    arry.forEach(item => {
                        if(obj[item.accountOrderType]){
                            obj[item.accountOrderType] += item.actualAmount;
                        }else{
                            obj[item.accountOrderType] = item.actualAmount;
                        }
                    })
                    let s = [],pay = [],income = [];
                    for(let k in obj) {
                        s.push({accountOrderType:k,actualAmount:obj[k]});
                    }
                    for (let v = 0; v < s.length; v++) {
                        if (s[v].accountOrderType == '02' || s[v].accountOrderType == '04') {
                            pay.push(s[v].actualAmount)
                        } else {
                            income.push(s[v].actualAmount)
                        }
                    }
                    let payVal = 0, incomeVal = 0;
                    pay.forEach((val) => {
                        payVal += val
                    })
                    income.forEach((val) => {
                        incomeVal += val
                    })
                    newValue[i]['income'] = incomeVal
                    newValue[i]['pay'] = payVal
                }
            },
            deep: true&emsp;&emsp;
        }
    }
}
</script>