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 @@ + + + + + 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); +}