diff --git a/src/config.js b/src/config.js
index 00253d6f15a1660696196c694c476c0700126e98..d8e530a46f48038c09f83cf058ed4908daa8f37b 100644
--- a/src/config.js
+++ b/src/config.js
@@ -313,6 +313,16 @@ module.exports = {
sort: 15,
show: true,
author: 'yangxiaolu'
+ },
+ {
+ version: '3.0.0',
+ name: 'PullRefresh',
+ type: 'component',
+ cName: '下拉刷新',
+ desc: '下拉刷新',
+ sort: 16,
+ show: true,
+ author: 'yangxiaolu3'
}
]
},
diff --git a/src/packages/pullrefresh/demo.vue b/src/packages/pullrefresh/demo.vue
new file mode 100644
index 0000000000000000000000000000000000000000..302b90f7b096a3a00ad80edbbafa7c0096a29c9d
--- /dev/null
+++ b/src/packages/pullrefresh/demo.vue
@@ -0,0 +1,61 @@
+
+
+
+
+
+
我是测试数据1
+
我是测试数据2
+
我是测试数据3
+
我是测试数据4
+
我是测试数据5
+
我是测试数据6
+
我是测试数据7
+
我是测试数据8
+
我是测试数据9
+
我是测试数据10
+
我是测试数据11
+
我是测试数据12
+
我是测试数据13
+
我是测试数据14
+
我是测试数据15
+
我是测试数据16
+
我是测试数据17
+
我是测试数据18
+
我是测试数据19
+
我是测试数据20
+
我是测试数据21
+
我是测试数据22
+
我是测试数据23
+
我是测试数据24
+
+
+
+
+
+
+
+
+
diff --git a/src/packages/pullrefresh/doc.md b/src/packages/pullrefresh/doc.md
new file mode 100644
index 0000000000000000000000000000000000000000..c5f0adfda988c611f5a6a546422a5aefc7457602
--- /dev/null
+++ b/src/packages/pullrefresh/doc.md
@@ -0,0 +1,34 @@
+# pullrefresh组件
+
+ ### 介绍
+
+ 基于 xxxxxxx
+
+ ### 安装
+
+
+
+ ## 代码演示
+
+ ### 基础用法1
+
+
+
+ ## API
+
+ ### Props
+
+ | 参数 | 说明 | 类型 | 默认值 |
+ |--------------|----------------------------------|--------|------------------|
+ | name | 图标名称或图片链接 | String | - |
+ | color | 图标颜色 | String | - |
+ | size | 图标大小,如 '20px' '2em' '2rem' | String | - |
+ | class-prefix | 类名前缀,用于使用自定义图标 | String | 'nutui-iconfont' |
+ | tag | HTML 标签 | String | 'i' |
+
+ ### Events
+
+ | 事件名 | 说明 | 回调参数 |
+ |--------|----------------|--------------|
+ | click | 点击图标时触发 | event: Event |
+
\ No newline at end of file
diff --git a/src/packages/pullrefresh/index.css b/src/packages/pullrefresh/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..7319f37e7a3a9d32bbe600998f4d3f637163f638
--- /dev/null
+++ b/src/packages/pullrefresh/index.css
@@ -0,0 +1,43 @@
+view {
+ display: block;
+}
+
+.nut-pullrefresh {
+ position: relative;
+ height: 100%;
+}
+
+.nut-pullrefresh .pullrefresh-top {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ height: 50px;
+ overflow: hidden;
+ color: #969799;
+ font-size: 14px;
+ line-height: 50px;
+ text-align: center;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+}
+
+.nut-pullrefresh .pullrefresh-content {
+ height: 100%;
+ overflow: auto;
+ background: #fff;
+}
+
+.nut-pullrefresh .pullrefresh-bottom {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 0px;
+ overflow: hidden;
+ color: #969799;
+ font-size: 14px;
+ line-height: 50px;
+ text-align: center;
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+}
diff --git a/src/packages/pullrefresh/index.min.css b/src/packages/pullrefresh/index.min.css
new file mode 100644
index 0000000000000000000000000000000000000000..f095de3c2c839ed52b697c1a0eaf452fee2abfb2
--- /dev/null
+++ b/src/packages/pullrefresh/index.min.css
@@ -0,0 +1 @@
+view{display:block}.nut-pullrefresh{position:relative;height:100%}.nut-pullrefresh .pullrefresh-top{position:absolute;left:0;width:100%;height:50px;overflow:hidden;color:#969799;font-size:14px;line-height:50px;text-align:center;-webkit-transform:translateY(-100%);transform:translateY(-100%)}.nut-pullrefresh .pullrefresh-content{height:100%;overflow:auto;background:#fff}.nut-pullrefresh .pullrefresh-bottom{position:absolute;left:0;bottom:0;width:100%;height:0px;overflow:hidden;color:#969799;font-size:14px;line-height:50px;text-align:center;-webkit-transform:translateY(100%);transform:translateY(100%)}
diff --git a/src/packages/pullrefresh/index.scss b/src/packages/pullrefresh/index.scss
new file mode 100644
index 0000000000000000000000000000000000000000..e7accfbc610cba11efff2f4b58342aefda61ee5f
--- /dev/null
+++ b/src/packages/pullrefresh/index.scss
@@ -0,0 +1,43 @@
+view {
+ display: block;
+}
+
+.nut-pullrefresh {
+ position: relative;
+ height: 100%;
+
+ .pullrefresh-top {
+ position: absolute;
+ left: 0;
+ width: 100%;
+ height: 50px;
+ overflow: hidden;
+ color: #969799;
+ font-size: 14px;
+ line-height: 50px;
+ text-align: center;
+ -webkit-transform: translateY(-100%);
+ transform: translateY(-100%);
+ }
+
+ .pullrefresh-content {
+ height: 100%;
+ overflow: auto;
+ background: #fff;
+ }
+
+ .pullrefresh-bottom {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+ width: 100%;
+ height: 0px;
+ overflow: hidden;
+ color: #969799;
+ font-size: 14px;
+ line-height: 50px;
+ text-align: center;
+ -webkit-transform: translateY(100%);
+ transform: translateY(100%);
+ }
+}
diff --git a/src/packages/pullrefresh/index.vue b/src/packages/pullrefresh/index.vue
new file mode 100644
index 0000000000000000000000000000000000000000..5d2f4257f82ab91687f01c7dd9260eb955d72acf
--- /dev/null
+++ b/src/packages/pullrefresh/index.vue
@@ -0,0 +1,231 @@
+
+
+
+
+ 加载中...
+
+
+ 下拉刷新...
+
+
+ 释放刷新...
+
+
+
+
+
+
+
+
+ 加载中...
+
+
+ 下拉刷新...
+
+
+ 释放刷新...
+
+
+
+
+
+
+
+
diff --git a/src/packages/pullrefresh/use-touch.ts b/src/packages/pullrefresh/use-touch.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7f7929ffbb4d6e3d6b530fb6313a57beb4312a7b
--- /dev/null
+++ b/src/packages/pullrefresh/use-touch.ts
@@ -0,0 +1,69 @@
+import { ref } from 'vue';
+
+const MIN_DISTANCE = 10;
+
+type Direction = '' | 'vertical' | 'horizontal';
+
+function getDirection(x: number, y: number) {
+ if (x > y && x > MIN_DISTANCE) {
+ return 'horizontal';
+ }
+ if (y > x && y > MIN_DISTANCE) {
+ return 'vertical';
+ }
+ return '';
+}
+
+export function useTouch() {
+ const startX = ref(0);
+ const startY = ref(0);
+ const deltaX = ref(0);
+ const deltaY = ref(0);
+ const offsetX = ref(0);
+ const offsetY = ref(0);
+ const direction = ref('');
+
+ const isVertical = () => direction.value === 'vertical';
+ const isHorizontal = () => direction.value === 'horizontal';
+
+ const reset = () => {
+ deltaX.value = 0;
+ deltaY.value = 0;
+ offsetX.value = 0;
+ offsetY.value = 0;
+ direction.value = '';
+ };
+
+ const start = ((event: TouchEvent) => {
+ reset();
+ startX.value = event.touches[0].clientX;
+ startY.value = event.touches[0].clientY;
+ }) as EventListener;
+
+ const move = ((event: TouchEvent) => {
+ const touch = event.touches[0];
+ deltaX.value = touch.clientX - startX.value;
+ deltaY.value = touch.clientY - startY.value;
+ offsetX.value = Math.abs(deltaX.value);
+ offsetY.value = Math.abs(deltaY.value);
+
+ if (!direction.value) {
+ direction.value = getDirection(offsetX.value, offsetY.value);
+ }
+ }) as EventListener;
+
+ return {
+ move,
+ start,
+ reset,
+ startX,
+ startY,
+ deltaX,
+ deltaY,
+ offsetX,
+ offsetY,
+ direction,
+ isVertical,
+ isHorizontal
+ };
+}
diff --git a/src/packages/pullrefresh/util.ts b/src/packages/pullrefresh/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3b26f9d0664071280da80d812493bbcfb6a93232
--- /dev/null
+++ b/src/packages/pullrefresh/util.ts
@@ -0,0 +1,14 @@
+export function preventDefault(event: Event, isStopPropagation?: boolean) {
+ /* istanbul ignore else */
+ if (typeof event.cancelable !== 'boolean' || event.cancelable) {
+ event.preventDefault();
+ }
+
+ if (isStopPropagation) event.stopPropagation();
+}
+
+export function trigger(target: Element, type: string) {
+ const inputEvent = document.createEvent('HTMLEvents');
+ inputEvent.initEvent(type, true, true);
+ target.dispatchEvent(inputEvent);
+}