Prechádzať zdrojové kódy

1. 日历添加手势

Cee.Yang 3 rokov pred
rodič
commit
4241ffff00

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 1 - 0
components/scroll-list/images.js


+ 667 - 0
components/scroll-list/scroll-list.vue

@@ -0,0 +1,667 @@
+<template>
+    <view class="scroll-list-wrap" :style="[scrollListWrapStyle]">
+        <scroll-view
+            class="scroll-view"
+            :class="[elClass]"
+            :style="[listWrapStyle]"
+            scroll-y
+            scroll-anchoring
+            enable-back-to-top
+            :scroll-top="scrollTop"
+            :lower-threshold="defaultOption.lowerThreshold"
+            @scroll="handleScroll"
+            @touchend="handleTouchEnd"
+            @touchmove.prevent.stop="handleTouchMove"
+            @touchstart="handleTouchStart"
+            @scrolltolower="handleScrolltolower"
+        >
+            <view class="scroll-content" :style="[scrollContentStyle]">
+                <view class="pull-down-wrap">
+                    <slot name="pulldown" v-if="$slots.pulldown"></slot>
+                    <view class="refresh-view" :style="[refreshViewStyle]" v-else>
+                        <view class="pull-down-animation" :class="{ refreshing: refreshing }" :style="[pullDownAnimationStyle]"></view>
+                        <text class="pull-down-text" :style="[pullDownTextStyle]">{{ refreshStateText }}</text>
+                    </view>
+                </view>
+                <view class="empty-wrap" v-if="showEmpty">
+                    <slot name="empty" v-if="$slots.empty"></slot>
+                    <view class="empty-view" v-else>
+                        <image class="empty-image" :src="defaultOption.emptyImage || images.empty" mode="aspectFit"></image>
+                        <text class="empty-text" :style="[emptyTextStyle]">{{ emptyText }}</text>
+                    </view>
+                </view>
+                <view class="list-content"><slot></slot></view>
+                <view class="pull-up-wrap" v-if="showPullUp">
+                    <slot name="pullup" v-if="$slots.pullup"></slot>
+                    <view class="load-view" v-else>
+                        <view class="pull-up-animation" v-if="loading" :style="[pullUpAnimationStyle]"></view>
+                        <text class="pull-up-text" :style="[pullUpTextStyle]">{{ loadStateText }}</text>
+                    </view>
+                </view>
+            </view>
+        </scroll-view>
+    </view>
+</template>
+
+<script>
+import images from './images.js';
+export default {
+    name: 'scroll-list',
+    props: {
+        // 配置信息
+        option: {
+            type: Object,
+            default: () => ({})
+        }
+    },
+    data() {
+        return {
+            defaultOption: {
+                page: 1, // 分页
+                size: 15, // 分页大小
+                auto: true, // 自动加载
+                height: null, // 组件高度
+                disabled: false, // 禁用
+                background: '', // 背景颜色属性
+                emptyImage: '', // 空数据提示图片
+                offsetBottom: 0, // 底部高度补偿
+                pullDownSpeed: 0.5, // 下拉速率
+                lowerThreshold: 40, // 距离底部上拉加载距离
+                refresherThreshold: 80, // 距离顶部下拉刷新距离
+                refreshDelayed: 800, // 刷新延迟
+                refreshFinishDelayed: 800, // 刷新完成后的延迟
+                safeArea: false, // 是否开启安全区域适配
+                emptyTextColor: '#82848a', // 空提示文字颜色
+                loadTextColor: '#82848a', // 上拉加载文字颜色
+                loadIconColor: '#82848a', // 上拉加载图标颜色
+                refresherTextColor: '#82848a', // 下拉刷新文字颜色
+                refresherIconColor: '#82848a', // 下拉刷新图标颜色
+                emptyText: '暂无列表~', // 空数据提示文字
+                loadingText: '正在加载中~', // 加载中文字
+                loadFailText: '加载失败啦~', // 加载失败文字
+                noMoreText: '没有更多啦~', // 没有更多文字
+                refreshingText: '正在刷新~', // 正在刷新文字
+                refreshFailText: '刷新失败~', // 刷新失败文字
+                refreshSuccessText: '刷新成功~', // 刷新成功文字
+                pulldownText: '下拉刷新~', // 下拉中的文字
+                pulldownFinishText: '松开刷新~' // 下拉完成的文字
+            },
+            images, // 内置图片
+            elClass: '', // 组件动态class
+            windowInfo: {}, // 窗口信息
+            scrollTop: 0, // 距离顶部滚动高度
+            scrollViewTop: -1, // 滚动视图顶部位置
+            scrollViewHeight: 0, // 滚动视图高度
+            currentPage: 1, // 当前分页页码
+            currentSize: 15, // 当前分页大小
+            currentScrollTop: 0, // 当前滚动高度
+            emptyText: '暂无列表~',
+            loadStateText: '正在加载中~', // 加载状态文字
+            refreshStateText: '下拉刷新~', // 刷新状态文字
+            loadDisabled: false, // 是否禁用上拉加载
+            loading: false, // 是否加载中
+            refreshing: false, // 是否刷新中
+            refreshFinish: false, // 是否刷新完成
+            pulldowning: false, // 是否正在下拉
+            pullDownHeight: 0, // 下拉高度
+            showEmpty: false, // 是否显示空数据提示
+            showPullUp: false, // 是否显示上拉加载
+            showPullDown: false // 是否显示下拉刷新
+        };
+    },
+    methods: {
+        // 组件初始化
+        handleInit() {
+            // 合并配置
+            this.defaultOption = Object.assign(this.defaultOption, this.option);
+            this.showEmpty = !this.defaultOption.auto;
+            this.currentPage = this.defaultOption.page;
+            this.currentSize = this.defaultOption.size;
+            this.emptyText = this.defaultOption.emptyText;
+            this.loadStateText = this.defaultOption.loadingText;
+            this.refreshStateText = this.defaultOption.pulldownText;
+            // 计算高度
+            this.queryRect('.' + this.elClass).then(rect => {
+                // 设置组件顶部位置
+                this.scrollViewTop = rect.top;
+                // 判断是否自动加载
+                if (this.defaultOption.auto) this.load();
+            });
+        },
+        // 加载数据
+        load() {
+            if (this.defaultOption.disabled || this.loading || this.loadDisabled) return;
+            // 开启正在加载
+            this.loading = true;
+            // 设置正在加载状态文字
+            this.loadStateText = this.defaultOption.loadingText;
+            // 显示上拉加载
+            this.showPullUp = true;
+            // 分页参数
+            let paging = { page: this.currentPage, size: this.currentSize };
+            // 触发load事件
+            this.$emit('load', paging);
+        },
+        // 加载成功
+        loadSuccess(data = {}) {
+            // 解构数据
+            const { list, total } = data;
+            // 判断列表是否是数组
+            if (Array.isArray(list)) {
+                // 判断列表长度
+                if (list.length) {
+                    // 判断列表长度和列表总数是否相同
+                    if (list.length >= total) {
+                        // 设置禁用上拉加载
+                        this.loadDisabled = true;
+                        // 加载状态文字
+                        this.loadStateText = this.defaultOption.noMoreText;
+                    } else {
+                        // 关闭禁用上拉加载
+                        this.loadDisabled = false;
+                        // 设置分页参数
+                        this.currentPage++;
+                        // 加载状态为加载中
+                        this.loadStateText = this.defaultOption.loadingText;
+                        // 加载计算
+                        this.loadCompute();
+                    }
+                    // 显示上拉加载
+                    this.showPullUp = true;
+                    // 隐藏空数据提示
+                    this.showEmpty = false;
+                } else {
+                    // 设置禁用上拉加载
+                    this.loadDisabled = true;
+                    // 隐藏上拉加载
+                    this.showPullUp = false;
+                    // 隐藏上拉加载
+                    this.showPullUp = false;
+                    // 显示空数据提示
+                    this.showEmpty = true;
+                }
+                // 关闭正在加载
+                this.loading = false;
+                // 触发加载成功事件
+                this.$emit('loadSuccess', list);
+            } else {
+                // 不是数组类型当作加载失败处理
+                this.loadFail();
+                console.error('the list must be a array');
+            }
+        },
+        // 加载失败
+        loadFail() {
+            // 关闭正在加载
+            this.loading = false;
+            // 关闭空数据提示
+            this.showEmpty = false;
+            // 显示上拉加载
+            this.showPullUp = true;
+            // 加载状态为加载失败
+            this.loadStateText = this.defaultOption.loadFailText;
+            // 触发加载失败事件
+            this.$emit('loadFail');
+        },
+        // 刷新数据
+        refresh() {
+            // 如果是下拉刷新
+            if (this.pullDownHeight == this.defaultOption.refresherThreshold) {
+                // 关闭正在加载
+                this.loading = false;
+                // 隐藏上拉加载
+                this.showPullUp = false;
+            } else {
+                // 开启正在加载
+                this.loading = true;
+                // 隐藏空数据提示
+                this.showEmpty = false;
+                // 显示上拉加载
+                this.showPullUp = true;
+                // 设置正在刷新状态文字
+                this.loadStateText = this.defaultOption.refreshingText;
+            }
+            // 设置刷新未完成
+            this.refreshFinish = false;
+            // 开启正在刷新
+            this.refreshing = true;
+            // 设置正在刷新状态文字
+            this.refreshStateText = this.defaultOption.refreshingText;
+            // 设置分页参数
+            this.currentPage = 1;
+            this.currentSize = this.defaultOption.size;
+            let paging = { page: this.currentPage, size: this.currentSize };
+            // 触发refresh事件
+            setTimeout(() => {
+                this.$emit('refresh', paging);
+            }, this.defaultOption.refreshDelayed);
+        },
+        // 刷新成功
+        refreshSuccess(data) {
+            // 解构数据
+            const { list, total } = data;
+            // 判断列表是否是数组
+            if (Array.isArray(list)) {
+                // 判断列表长度
+                if (list.length) {
+                    // 判断列表长度和列表总数是否相同
+                    if (list.length >= total) {
+                        // 设置禁用上拉加载
+                        this.loadDisabled = true;
+                        // 设置没有更多状态文字
+                        this.loadStateText = this.defaultOption.noMoreText;
+                    } else {
+                        // 设置分页参数
+                        this.currentPage++;
+                        // 关闭禁用上拉加载
+                        this.loadDisabled = false;
+                        // 设置加载中状态文字
+                        this.loadStateText = this.defaultOption.loadingText;
+                        // 开启自动加载
+                        this.defaultOption.auto = true;
+                        // 加载计算
+                        this.loadCompute();
+                    }
+                    // 关闭空数据提示
+                    this.showEmpty = false;
+                    // 显示上拉加载
+                    this.showPullUp = true;
+                } else {
+                    // 设置禁用上拉加载
+                    this.loadDisabled = true;
+                    // 隐藏上拉加载
+                    this.showPullUp = false;
+                    // 显示空数据提示
+                    this.showEmpty = true;
+                    // 设置没有更多状态文字
+                    this.loadStateText = this.defaultOption.noMoreText;
+                }
+                // 关闭正在加载
+                this.loading = false;
+                // 设置刷新成功状态文字
+                this.refreshStateText = this.defaultOption.refreshSuccessText;
+                // 关闭正在刷新
+                this.refreshing = false;
+                // 关闭正在下拉
+                this.pulldowning = false;
+                // 触发刷新成功事件
+                this.$emit('refreshSuccess', list);
+                setTimeout(() => {
+                    // 设置刷新完成
+                    this.refreshFinish = true;
+                    // 重置下拉高度
+                    this.pullDownHeight = 0;
+                    // 隐藏下拉刷新
+                    this.showPullDown = false;
+                    this.$emit('refreshSuccess');
+                }, this.defaultOption.refreshFinishDelayed);
+            } else {
+                // 不是数组类型当作刷新失败处理
+                this.refreshFail();
+                console.error('the list must be a array');
+            }
+        },
+        // 刷新失败
+        refreshFail() {
+            // 设置加载失败状态文字
+            this.loadStateText = this.defaultOption.refreshFailText;
+            // 设置刷新失败状态文字
+            this.refreshStateText = this.defaultOption.refreshFailText;
+            // 关闭正在加载
+            this.loading = false;
+            // 显示下拉加载
+            this.showPullUp = true;
+            // 关闭正在刷新
+            this.refreshing = false;
+            // 关闭正在下拉
+            this.pulldowning = false;
+            // 延迟执行刷新完成后状态
+            setTimeout(() => {
+                // 设置刷新完成
+                this.refreshFinish = true;
+                // 重置下拉高度
+                this.pullDownHeight = 0;
+                // 隐藏下拉刷新
+                this.showPullDown = false;
+                // 触发刷新失败事件
+                this.$emit('refreshError');
+            }, this.defaultOption.refreshFinishDelayed);
+        },
+        // 加载计算
+        loadCompute() {
+            // 判断是否自动加载
+            if (this.defaultOption.auto) {
+                // 延迟执行下否者可能会高度计算错误
+                setTimeout(() => {
+                    this.$nextTick(() => {
+                        this.queryRect('.list-content').then(rect => {
+                            if (rect.height <= this.scrollViewHeight) {
+                                this.load();
+                            }
+                        });
+                    });
+                }, 100);
+            }
+        },
+        // 上拉触底事件
+        handleScrolltolower(e) {
+            if (this.loadDisabled) return;
+            this.$emit('scrolltolower', e);
+            this.load();
+        },
+        // 滚动事件
+        handleScroll(event) {
+            this.currentScrollTop = event.detail.scrollTop;
+            this.$emit('scroll', event.detail);
+        },
+        // 触摸按下处理
+        handleTouchStart(event) {
+            if (this.defaultOption.disabled) return;
+            this.currentTouchStartY = event.touches[0].clientY;
+            this.$emit('touchStart', event);
+        },
+        // 触摸按下滑动处理
+        handleTouchMove(event) {
+            if (this.defaultOption.disabled || this.currentScrollTop) return;
+            if (event.touches[0].clientY >= this.currentTouchStartY) {
+                this.pulldowning = true;
+                this.showPullDown = true;
+                let pullDownDistance = (event.touches[0].clientY - this.currentTouchStartY) * this.defaultOption.pullDownSpeed;
+                this.pullDownHeight = pullDownDistance > this.defaultOption.refresherThreshold ? this.defaultOption.refresherThreshold : pullDownDistance;
+                this.refreshStateText =
+                    this.pullDownHeight >= this.defaultOption.refresherThreshold ? this.defaultOption.pulldownFinishText : this.defaultOption.pulldownText;
+                this.$emit('touchMove', event);
+            }
+        },
+        // 触摸松开处理
+        handleTouchEnd(event) {
+            if (this.defaultOption.disabled) return;
+            // 当下拉高度小于下拉阈值
+            if (this.pullDownHeight < this.defaultOption.refresherThreshold) {
+                // 关闭正在下拉
+                this.pulldowning = false;
+                // 重置下拉高度
+                this.pullDownHeight = 0;
+                // 隐藏下拉刷新
+                this.showPullDown = false;
+                // 触发下拉中断事件
+                this.$emit('refreshStop');
+            } else {
+                this.refresh();
+            }
+            // 触发下拉触摸松开事件
+            this.$emit('touchEnd', event);
+        },
+        // 更新组件
+        updateScrollView() {
+            if (this.defaultOption.height) {
+                this.scrollViewHeight = uni.upx2px(this.defaultOption.height);
+            } else {
+                this.scrollViewHeight = this.windowInfo.windowHeight - this.scrollViewTop;
+            }
+            this.scrollViewObserve();
+        },
+        // 监听列表高度变化
+        listContentObserve() {
+            this.disconnectObserve('_listContentObserve');
+            const listContentObserve = this.createIntersectionObserver({
+                thresholds: [0, 0.5, 1]
+            });
+            listContentObserve.relativeToViewport({
+                // #ifdef H5
+                top: -(this.windowInfo.windowTop + rect.top),
+                // #endif
+                // #ifndef H5
+                top: -rect.top
+                // #endif
+            });
+        },
+        // 监听组件位置变化
+        scrollViewObserve() {
+            this.disconnectObserve('_scrollViewObserve');
+            this.$nextTick(() => {
+                this.queryRect('.' + this.elClass).then(rect => {
+                    const scrollViewObserve = this.createIntersectionObserver({
+                        thresholds: [0, 0.5, 1]
+                    });
+                    scrollViewObserve.relativeToViewport({
+                        // #ifdef H5
+                        top: -(this.windowInfo.windowTop + rect.top),
+                        // #endif
+                        // #ifndef H5
+                        top: -rect.top
+                        // #endif
+                    });
+                    scrollViewObserve.observe('.' + this.elClass, position => {
+                        // #ifdef H5
+                        this.scrollViewTop = position.boundingClientRect.top - this.windowInfo.windowTop;
+                        // #endif
+                        // #ifndef H5
+                        this.scrollViewTop = position.boundingClientRect.top;
+                        // #endif
+                    });
+                    this._scrollViewObserve = scrollViewObserve;
+                });
+            });
+        },
+        // 断开监听组件
+        disconnectObserve(observerName) {
+            const observer = this[observerName];
+            observer && observer.disconnect();
+        },
+        // 查询dom节点信息
+        queryRect(selector, all) {
+            return new Promise(resolve => {
+                uni.createSelectorQuery()
+                    .in(this)
+                    [all ? 'selectAll' : 'select'](selector)
+                    .boundingClientRect(rect => {
+                        if (all && Array.isArray(rect) && rect.length) {
+                            resolve(rect);
+                        }
+                        if (!all && rect) {
+                            resolve(rect);
+                        }
+                    })
+                    .exec();
+            });
+        },
+        // 16进制转RGB
+        hexToRgb(hex) {
+            const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
+            hex = hex.replace(shorthandRegex, (m, r, g, b) => {
+                return r + r + g + g + b + b;
+            });
+            const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
+            return result
+                ? {
+                      r: parseInt(result[1], 16),
+                      g: parseInt(result[2], 16),
+                      b: parseInt(result[3], 16)
+                  }
+                : null;
+        }
+    },
+    computed: {
+        scrollListWrapStyle(){
+            let style = {};
+            style.background = this.defaultOption.background;
+            return style;
+        },
+        // 组件容器样式
+        listWrapStyle() {
+            let style = {};
+            const { offsetBottom } = this.defaultOption;
+            style.height = this.scrollViewHeight - uni.upx2px(offsetBottom) + 'px';
+            if (this.defaultOption.safeArea) style.paddingBottom = 'env(safe-area-inset-bottom) !important';
+            return style;
+        },
+        // 滚动内容样式
+        scrollContentStyle() {
+            const style = {};
+            const { pullDownHeight, pulldowning, showPullDown } = this;
+            style.transform = showPullDown ? `translateY(${pullDownHeight}px)` : `translateY(0px)`;
+            style.transition = pulldowning ? `transform 100ms ease-out` : `transform 200ms cubic-bezier(0.19,1.64,0.42,0.72)`;
+            return style;
+        },
+        // 下拉刷新样式
+        refreshViewStyle() {
+            const style = {};
+            const { showPullDown } = this;
+            style.opacity = showPullDown ? 1 : 0;
+            return style;
+        },
+        // 下拉中动画样式
+        pullDownAnimationStyle() {
+            const style = {};
+            const { refresherIconColor, refresherThreshold } = this.defaultOption;
+            const { refreshing, pullDownHeight } = this;
+            const { r, g, b } = this.hexToRgb(refresherIconColor);
+            const rate = pullDownHeight / refresherThreshold;
+            style.borderColor = `rgba(${r},${g},${b},0.2)`;
+            style.borderTopColor = refresherIconColor;
+            if (!refreshing) {
+                style.transform = `rotate(${360 * rate}deg)`;
+                style.transition = 'transform 100ms linear';
+            }
+            return style;
+        },
+        pullDownTextStyle() {
+            const style = {};
+            const { refresherTextColor } = this.defaultOption;
+            style.color = refresherTextColor;
+            return style;
+        },
+        // 上拉中动画样式
+        pullUpAnimationStyle() {
+            const style = {};
+            const { loadIconColor } = this.defaultOption;
+            const { r, g, b } = this.hexToRgb(loadIconColor);
+            style.borderColor = `rgba(${r},${g},${b},0.2)`;
+            style.borderTopColor = loadIconColor;
+            return style;
+        },
+        // 上拉中文字样式
+        pullUpTextStyle() {
+            const style = {};
+            const { loadTextColor } = this.defaultOption;
+            style.color = loadTextColor;
+            return style;
+        },
+        // 空数据提示文字样式
+        emptyTextStyle() {
+            const style = {};
+            const { emptyTextColor } = this.defaultOption;
+            style.color = emptyTextColor;
+            return style;
+        }
+    },
+    watch: {
+        scrollViewTop(val) {
+            this.updateScrollView();
+        }
+    },
+    created() {
+        this.elClass = 'scroll-view-' + this._uid;
+        this.windowInfo = uni.getSystemInfoSync();
+    },
+    mounted() {
+        this.handleInit();
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.scroll-list-wrap {
+    box-sizing: border-box;
+    .scroll-view {
+        position: relative;
+        .scroll-content {
+            height: 100%;
+            display: flex;
+            will-change: transform;
+            flex-direction: column;
+            .pull-down-wrap {
+                left: 0;
+                width: 100%;
+                display: flex;
+                padding: 30rpx 0;
+                position: absolute;
+                align-items: flex-end;
+                justify-content: center;
+                transform: translateY(-100%);
+                .refresh-view {
+                    display: flex;
+                    justify-content: center;
+                    .pull-down-animation {
+                        width: 32rpx;
+                        height: 32rpx;
+                        border-width: 4rpx;
+                        border-style: solid;
+                        border-radius: 50%;
+                        &.refreshing {
+                            animation: spin 0.5s linear infinite;
+                        }
+                        @keyframes spin {
+                            to {
+                                transform: rotate(360deg);
+                            }
+                        }
+                    }
+                    .pull-down-text {
+                        margin-left: 10rpx;
+                    }
+                }
+            }
+            .empty-wrap {
+                top: 0;
+                left: 0;
+                width: 100%;
+                height: 100%;
+                display: flex;
+                position: absolute;
+                align-items: center;
+                flex-direction: column;
+                .empty-view {
+                    margin: auto;
+                    display: flex;
+                    align-items: center;
+                    flex-direction: column;
+                    .empty-image {
+                        width: 200rpx;
+                        height: 200rpx;
+                    }
+                    .empty-text {
+                        color: #606266;
+                        margin-top: 20rpx;
+                    }
+                }
+            }
+            .list-content {
+            }
+            .pull-up-wrap {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                .load-view {
+                    padding: 20rpx 0;
+                    display: flex;
+                    align-items: center;
+                    justify-content: center;
+                    .pull-up-animation {
+                        width: 32rpx;
+                        height: 32rpx;
+                        border-width: 4rpx;
+                        border-style: solid;
+                        border-radius: 50%;
+                        animation: spin 0.5s linear infinite;
+                    }
+                    .pull-up-text {
+                        margin-left: 10rpx;
+                    }
+                }
+            }
+        }
+    }
+}
+</style>

+ 24 - 4
components/uni-calendar/uni-calendar.vue

@@ -1,5 +1,5 @@
 <template>
-	<view class="uni-calendar">
+	<view class="uni-calendar" @touchstart="handleTouchstart" @touchend="handleTouchend">
 		<view v-if="!insert&&show" class="uni-calendar__mask" :class="{'uni-calendar--mask-show':aniMaskShow}" @click="clean"></view>
 		<view v-if="insert || show" class="uni-calendar__content" :class="{'uni-calendar--fixed':!insert,'uni-calendar--ani-show':aniMaskShow}">
 			<view v-if="!insert" class="uni-calendar__header uni-calendar--fixed-top">
@@ -132,7 +132,7 @@
 			},
 			showMonth: {
 				type: Boolean,
-				default: true
+				default: false
 			},
 			clearDate: {
 				type: Boolean,
@@ -153,7 +153,10 @@
 				aniMaskShow: false,
 				fold: true,
 				showMonthed: false,
-				foldIndex: -1
+				foldIndex: -1,
+				startTime: 0,
+				startX: 0,
+				startY: 0,
 			}
 		},
 		computed:{
@@ -391,7 +394,24 @@
 			foldBtnDidClick() {
 				this.fold = !this.fold
 				this.showMonthed = !this.fold
-			}
+			},
+			handleTouchstart(e) {
+			     //记录用户按下的时间
+			     this.startTime = Date.now();
+			     //记录用户按下的坐标
+			     this.startX = e.changedTouches[0].clientX;
+			     this.startY = e.changedTouches[0].clientY;
+				},
+			handleTouchend(e) {
+			    const endTime = Date.now();
+			    const endX = e.changedTouches[0].clientX;
+			    if (Math.abs(endX - this.startX) < 10) return
+			    if (endX - this.startX < 0) {
+					this.next();
+				} else {
+					this.pre();
+				}
+			},
 		}
 	}
 </script>

+ 2 - 0
main.js

@@ -2,6 +2,7 @@ import App from './App'
 import Vue from 'vue'
 
 import cuCustom from './components/colorui/components/cu-custom.vue'
+import scrollList from './components/scroll-list/scroll-list.vue'
 import uView from '@/uni_modules/uview-ui'
 import i18n from './i18n/index'
 import store from './store/store'
@@ -9,6 +10,7 @@ import request from './api/request.js'
 
 Vue.use(cuCustom)
 Vue.use(uView)
+Vue.use(scrollList)
 Vue.config.productionTip = false
 App.mpType = 'app'
 const app = new Vue({

+ 10 - 16
package.json

@@ -1,19 +1,13 @@
 {
-    "id": "htz-image-upload",
-    "name": "图片 视频上传 预览 【简单好上手】",
-    "version": "0.1.6",
-    "description": "可选择添加/删除图片/视频,可以预览,可以压缩(包括H5压缩)(解决了安卓10问题),支持上传到服务器后台,能满足大部分场景",
+    "id": "scroll-list",
+    "name": "滚动列表【自动加载,上拉加载,下拉刷新,可自定义】",
+    "version": "1.1.0",
+    "description": "滚动列表【自动加载,上拉加载,下拉刷新,可自定义】",
     "keywords": [
-        "上传",
-        "压缩图片",
-        "预览图片",
-        "删除图片",
-        "视频上传"
-    ],
-    "dcloudext": {
-        "category": [
-            "前端组件",
-            "通用组件"
-        ]
-    }
+        "自动加载",
+        "上拉加载",
+        "下拉刷新",
+        "可自定义",
+        "滚动"
+    ]
 }

+ 2 - 3
pages.json

@@ -15,8 +15,7 @@
 		{
 			"path": "pages/index/index",
 			"style": {
-				"navigationStyle":"custom",
-				"enablePullDownRefresh": true
+				"navigationStyle":"custom"
 			}
 		},
 		{
@@ -43,6 +42,6 @@
 		"navigationBarTitleText": "uni-app",
 		"navigationBarBackgroundColor": "#F8F8F8",
 		"backgroundColor": "#F8F8F8",
-		"enablePullDownRefresh": true
+		"enablePullDownRefresh": false
 	}
 }

+ 44 - 8
pages/calendar/index.vue

@@ -12,12 +12,15 @@
 		 <uni-calendar insert foldAble :selected="selected" @change="change" />
 		 
 		 <u-gap height="120"/>
-		 <button class="cu-btn block bg-red margin-tb-sm lg radio" @click="uploadAction">
-		 	<text> 上传 </text>
-		 </button>
-		 <button class="cu-btn block bg-red margin-tb-sm lg radio" @click="monitoringBtnClick">
-		 	<text> 监控 </text>
-		 </button>
+		 <scroll-list ref="list" :option="option" @load="load" @refresh="refresh">
+		             <view class="list-item" v-for="(item, index) in list" :key="index">
+		                 <view class="avatar">{{ index + 1 }}</view>
+		                 <view class="info">
+		                     <view class="info-item"></view>
+		                     <view class="info-item"></view>
+		                 </view>
+		             </view>
+		         </scroll-list>
 		
 	</view>
 </template>
@@ -38,7 +41,12 @@
 					{date: '2022-01-05', info: '签到', data: { custom: '自定义信息', name: '自定义消息头' }},
 					{date: '2022-01-09', info: '打卡', data: { custom: '自定义信息', name: '自定义消息头' }},
 					{date: '2022-02-03', info: '打卡', data: { custom: '自定义信息', name: '自定义消息头' }},
-				]
+				],
+				option: {
+				                size: 5,
+				                auto: true
+				            },
+				list: []
 			}
 		},
 		onReady() {
@@ -80,7 +88,35 @@
 				uni.navigateTo({
 					url: '../launch/index'
 				})
-			}
+			},
+			// 加载数据
+			        load(paging) {
+			            setTimeout(() => {
+			                let list = [];
+			                for (var i = 0; i < paging.size; i++) {
+			                    list.push(i);
+			                }
+			                this.list = [...this.list, ...list];
+			                // 加载成功  参数对象{list: 当前列表,total: 数据总长度(后端查询的total)}
+			                this.$refs.list.loadSuccess({ list: this.list, total: 50 });
+			                // 加载失败
+			                // this.$refs.list.loadFail()
+			            }, this.$u.random(100, 1000));
+			        },
+			        // 刷新刷剧
+			        refresh(paging) {
+			            setTimeout(() => {
+			                let list = [];
+			                for (var i = 0; i < paging.size; i++) {
+			                    list.push(i);
+			                }
+			                this.list = list;
+			                // 刷新成功  参数对象{list: 当前列表,total: 数据总长度(后端查询的total)}
+			                this.$refs.list.refreshSuccess({ list: this.list, total: 50 });
+			                // 刷新失败
+			                // this.$refs.list.refreshFail()
+			            }, this.$u.random(100, 1000));
+			        }
 		}
 	}
 </script>

+ 68 - 25
pages/message/index.vue

@@ -1,47 +1,90 @@
 <template>
-	<view>
-		<u-navbar bgColor="white" :title="$t('message')">
-			<view class="u-nav-slot" slot="left"></view>
+	<view class="calendar-page">
+		
+		<!-- 导航栏 -->
+		<u-navbar bgColor="red">
+			<view class="u-nav-slot" slot="left">
+				<text class="text-bold text-xxl text-white"> {{ $t('schedule') }} </text>
+			</view>
+			<view class="u-nav-slot" slot="right"></view>
 		</u-navbar>
 		
-		<view class="cu-bar justify-center">
-			<u-icon name="arrow-left" size="28" @click="previousMonth"></u-icon>
-			<text class="text-bold text-black"> {{ curDate }} </text>
-			<u-icon name="arrow-right" size="28" @click="nextMonth"></u-icon>
-		</view>
-		<ren-calendar ref='ren' :markDays='markDays' headerBar @onDayClick='onDayClick'></ren-calendar>
-		<view class="change">选中日期:{{curDate}}</view>
+		 <uni-calendar insert foldAble :selected="selected" @change="change" />
+		 
+		 <u-gap height="120"/>
+		 <button class="cu-btn block bg-red margin-tb-sm lg radio" @click="uploadAction">
+		 	<text> 上传 </text>
+		 </button>
+		 <button class="cu-btn block bg-red margin-tb-sm lg radio" @click="monitoringBtnClick">
+		 	<text> 监控 </text>
+		 </button>
 		
 	</view>
 </template>
 
 <script>
-	import RenCalendar from "../../components/ren-calendar/ren-calendar.vue"
+	import Api from '../../api/api.js'
+	import UniCalendar from "../../components/uni-calendar/uni-calendar.vue"
 	export default {
 		components:{
-			RenCalendar
+			UniCalendar
 		},
 		data() {
 			return {
-				curDate:'',
-				markDays:[]
+				currentDate: '',
+				show: false,
+				mode: 'range',
+				selected: [
+					{date: '2022-01-05', info: '签到', data: { custom: '自定义信息', name: '自定义消息头' }},
+					{date: '2022-01-09', info: '打卡', data: { custom: '自定义信息', name: '自定义消息头' }},
+					{date: '2022-02-03', info: '打卡', data: { custom: '自定义信息', name: '自定义消息头' }},
+				]
 			}
 		},
 		onReady() {
-			let today = this.$refs.ren.getToday().date;
-			this.curDate = today;
-			this.markDays.push(today);
+			
+		},
+		mounted() {
+			// let now = new Date()
+			// let ye = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(now)
+			// let mo = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(now)
+			// this.currentDate = `${ye}${mo}` /// 202201
+			
+			let now = new Date();
+			var year = now.getFullYear()
+			var month = now.getMonth()+1
+			this.currentDate = `${year}${month}` /// 202201
+			console.log(this.currentDate)
+			
+			this.getClassSchedule()
 		},
-		methods: {
-			onDayClick(data){
-				this.curDate = data.date;
+		methods:{
+			async getClassSchedule() {
+				Api.classSchedule(this.currentDate).then(res=>{
+					console.log(res)
+				})
+			},
+			previousBtnDidClick(){
+				console.log('previousBtnDidClick')
+			},
+			nextBtnDidClick(){
+				console.log('nextBtnDidClick')
 			},
-			previousMonth() {
-				
+			change(e) {
+				console.log(e)
 			},
-			nextMonth() {
-				
+			uploadAction() {
+				uni.navigateTo({url: '../test/upload'})
+			},
+			monitoringBtnClick() {
+				uni.navigateTo({
+					url: '../launch/index'
+				})
 			}
 		}
 	}
-</script>
+</script>
+
+
+<style scoped>
+</style>

+ 1 - 1
pages/mine/index.vue

@@ -77,7 +77,7 @@
 					url: item.url
 				})
 			}
-		}
+		},
 	}
 </script>
 

+ 2 - 2
unpackage/dist/dev/app-plus/app-config-service.js

@@ -1,8 +1,8 @@
 
 var isReady=false;var onReadyCallbacks=[];
 var isServiceReady=false;var onServiceReadyCallbacks=[];
-var __uniConfig = {"pages":["pages/launch/index","pages/login/index","pages/index/index","pages/login/env_page","pages/mine/setting","pages/test/upload"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","enablePullDownRefresh":true},"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"i2School","compilerVersion":"3.3.5","entryPagePath":"pages/launch/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
-var __uniRoutes = [{"path":"/pages/launch/index","meta":{"isQuit":true},"window":{"navigationStyle":"custom"}},{"path":"/pages/login/index","meta":{},"window":{"navigationStyle":"custom"}},{"path":"/pages/index/index","meta":{},"window":{"navigationStyle":"custom","enablePullDownRefresh":true}},{"path":"/pages/login/env_page","meta":{},"window":{"navigationBarTitleText":"开发者工具"}},{"path":"/pages/mine/setting","meta":{},"window":{"navigationBarTitleText":"设置"}},{"path":"/pages/test/upload","meta":{},"window":{"navigationBarTitleText":"上传"}}];
+var __uniConfig = {"pages":["pages/launch/index","pages/login/index","pages/index/index","pages/login/env_page","pages/mine/setting","pages/test/upload"],"window":{"navigationBarTextStyle":"black","navigationBarTitleText":"uni-app","navigationBarBackgroundColor":"#F8F8F8","backgroundColor":"#F8F8F8","enablePullDownRefresh":false},"nvueCompiler":"uni-app","nvueStyleCompiler":"uni-app","renderer":"auto","splashscreen":{"alwaysShowBeforeRender":true,"autoclose":false},"appname":"i2School","compilerVersion":"3.3.5","entryPagePath":"pages/launch/index","networkTimeout":{"request":60000,"connectSocket":60000,"uploadFile":60000,"downloadFile":60000}};
+var __uniRoutes = [{"path":"/pages/launch/index","meta":{"isQuit":true},"window":{"navigationStyle":"custom"}},{"path":"/pages/login/index","meta":{},"window":{"navigationStyle":"custom"}},{"path":"/pages/index/index","meta":{},"window":{"navigationStyle":"custom"}},{"path":"/pages/login/env_page","meta":{},"window":{"navigationBarTitleText":"开发者工具"}},{"path":"/pages/mine/setting","meta":{},"window":{"navigationBarTitleText":"设置"}},{"path":"/pages/test/upload","meta":{},"window":{"navigationBarTitleText":"上传"}}];
 __uniConfig.onReady=function(callback){if(__uniConfig.ready){callback()}else{onReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"ready",{get:function(){return isReady},set:function(val){isReady=val;if(!isReady){return}const callbacks=onReadyCallbacks.slice(0);onReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
 __uniConfig.onServiceReady=function(callback){if(__uniConfig.serviceReady){callback()}else{onServiceReadyCallbacks.push(callback)}};Object.defineProperty(__uniConfig,"serviceReady",{get:function(){return isServiceReady},set:function(val){isServiceReady=val;if(!isServiceReady){return}const callbacks=onServiceReadyCallbacks.slice(0);onServiceReadyCallbacks.length=0;callbacks.forEach(function(callback){callback()})}});
 service.register("uni-app-config",{create(a,b,c){if(!__uniConfig.viewport){var d=b.weex.config.env.scale,e=b.weex.config.env.deviceWidth,f=Math.ceil(e/d);Object.assign(__uniConfig,{viewport:f,defaultFontSize:Math.round(f/20)})}return{instance:{__uniConfig:__uniConfig,__uniRoutes:__uniRoutes,global:void 0,window:void 0,document:void 0,frames:void 0,self:void 0,location:void 0,navigator:void 0,localStorage:void 0,history:void 0,Caches:void 0,screen:void 0,alert:void 0,confirm:void 0,prompt:void 0,fetch:void 0,XMLHttpRequest:void 0,WebSocket:void 0,webkit:void 0,print:void 0}}}});

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 0 - 0
unpackage/dist/dev/app-plus/app-service.js


Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 62 - 31
unpackage/dist/dev/app-plus/app-view.js


Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov