Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
京东前端
nutui
提交
b53e028f
N
nutui
项目概览
京东前端
/
nutui
通知
37
Star
4
Fork
1
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
nutui
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b53e028f
编写于
1月 27, 2021
作者:
Y
yangxiaolu3
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: infiniteloading 开发完成
上级
a64d79e2
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
444 addition
and
46 deletion
+444
-46
src/packages/infiniteloading/demo.vue
src/packages/infiniteloading/demo.vue
+127
-4
src/packages/infiniteloading/doc.md
src/packages/infiniteloading/doc.md
+141
-29
src/packages/infiniteloading/index.scss
src/packages/infiniteloading/index.scss
+10
-0
src/packages/infiniteloading/index.vue
src/packages/infiniteloading/index.vue
+166
-13
未找到文件。
src/packages/infiniteloading/demo.vue
浏览文件 @
b53e028f
...
...
@@ -2,24 +2,147 @@
<div
class=
"demo"
>
<h2>
基础用法
</h2>
<nut-cell>
<nut-temp
name=
"wifi"
></nut-temp>
<nut-temp
name=
"mail"
txt=
"test txt"
></nut-temp>
<ul
class=
"infiniteUl"
id=
"scroll"
>
<nut-infiniteloading
containerId=
"scroll"
:useWindow=
"false"
:isLoading=
"isLoading"
:hasMore=
"hasMore"
@
scrollChange=
"scrollChange"
@
loadMore=
"loadMore"
>
<li
class=
"infiniteLi"
v-for=
"(item, index) in defultList"
:key=
"index"
>
{{
item
}}
</li
>
</nut-infiniteloading>
</ul>
</nut-cell>
<h2>
自定义加载文案
</h2>
<nut-cell>
<ul
class=
"infiniteUl"
id=
"customScroll"
>
<nut-infiniteloading
containerId=
"customScroll"
:useWindow=
"false"
:isLoading=
"customIsLoading"
:hasMore=
"customHasMore"
@
loadMore=
"customLoadMore"
>
<li
class=
"infiniteLi"
v-for=
"(item, index) in customList"
:key=
"index"
>
{{
item
}}
</li
>
<template
v-slot:loading
>
<div
class=
"loading"
>
<span>
加载中...
</span>
</div>
</
template
>
<
template
v-slot:unloadMore
>
<div
class=
"unload-more"
>
没有数据啦 ~~
</div>
</
template
>
</nut-infiniteloading>
</ul>
</nut-cell>
</div>
</template>
<
script
lang=
"ts"
>
import
{
onMounted
,
ref
,
reactive
,
toRefs
}
from
'
vue
'
;
import
{
createComponent
}
from
'
@/utils/create
'
;
const
{
createDemo
}
=
createComponent
(
'
infiniteloading
'
);
export
default
createDemo
({
props
:
{},
setup
()
{
return
{};
const
isLoading
=
ref
(
false
);
const
hasMore
=
ref
(
true
);
const
customIsLoading
=
ref
(
false
);
const
customHasMore
=
ref
(
true
);
const
data
=
reactive
({
defultList
:
[
''
],
customList
:
[
''
]
});
const
scrollChange
=
dis
=>
{
console
.
log
(
'
滚动的距离
'
,
dis
);
};
const
loadMore
=
()
=>
{
isLoading
.
value
=
true
;
setTimeout
(()
=>
{
const
curLen
=
data
.
defultList
.
length
;
for
(
let
i
=
curLen
;
i
<
curLen
+
10
;
i
++
)
{
data
.
defultList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
isLoading
.
value
=
false
;
if
(
data
.
defultList
.
length
>
30
)
hasMore
.
value
=
false
;
},
500
);
};
const
customLoadMore
=
()
=>
{
customIsLoading
.
value
=
true
;
setTimeout
(()
=>
{
const
curLen
=
data
.
customList
.
length
;
for
(
let
i
=
curLen
;
i
<
curLen
+
10
;
i
++
)
{
data
.
customList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
customIsLoading
.
value
=
false
;
if
(
data
.
customList
.
length
>
30
)
customHasMore
.
value
=
false
;
},
500
);
};
const
init
=
()
=>
{
for
(
let
i
=
0
;
i
<
10
;
i
++
)
{
data
.
defultList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
data
.
customList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
};
onMounted
(()
=>
{
init
();
});
return
{
scrollChange
,
loadMore
,
isLoading
,
hasMore
,
customIsLoading
,
customHasMore
,
customLoadMore
,
...
toRefs
(
data
)
};
}
});
</
script
>
<
style
lang=
"scss"
scoped
>
.nut-temp
{
.infiniteUl
{
height
:
300px
;
width
:
100%
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
}
.infiniteLi
{
margin-top
:
10px
;
font-size
:
14px
;
color
:
rgba
(
100
,
100
,
100
,
1
);
}
</
style
>
src/packages/infiniteloading/doc.md
浏览文件 @
b53e028f
# infiniteloading组件
### 介绍
基于 xxxxxxx
### 安装
## 代码演示
### 基础用法1
### 介绍
列表滚动到底部自动加载更多数据。
### 安装
```
javascript
import
{
createApp
}
from
'
vue
'
;
import
{
InfiniteLoading
}
from
'
@nutui/nutui
'
;
const
app
=
createApp
();
app
.
use
(
InfiniteLoading
);
```
## 代码演示
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| name | 图标名称或图片链接 | String | - |
| color | 图标颜色 | String | - |
| size | 图标大小,如 '20px' '2em' '2rem' | String | - |
| class-prefix | 类名前缀,用于使用自定义图标 | String | 'nutui-iconfont' |
| tag | HTML 标签 | String | 'i' |
### Events
| 事件名 | 说明 | 回调参数 |
|--------|----------------|--------------|
| click | 点击图标时触发 | event: Event |
### 基础用法
```
html
<ul
class=
"infiniteUl"
id=
"scroll"
>
<nut-infiniteloading
containerId =
'scroll'
:useWindow=
'false'
:isLoading=
"isLoading"
:hasMore=
"hasMore"
@
scrollChange=
"scrollChange"
@
loadMore=
"loadMore"
>
<li
class=
"infiniteLi"
v-for=
"(item, index) in defultList"
:key=
"index"
>
{{item}}
</li>
</nut-infiniteloading>
</ul>
```
```
javascript
setup
()
{
const
isLoading
=
ref
(
false
);
const
hasMore
=
ref
(
true
);
const
data
=
reactive
({
defultList
:
[]
});
const
scrollChange
=
(
dis
)
=>
{};
const
loadMore
=
()
=>
{
isLoading
.
value
=
true
;
setTimeout
(()
=>
{
const
curLen
=
data
.
defultList
.
length
;
for
(
let
i
=
curLen
;
i
<
curLen
+
10
;
i
++
)
{
data
.
defultList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
isLoading
.
value
=
false
;
if
(
data
.
defultList
.
length
>
30
)
hasMore
.
value
=
false
;
},
500
);
};
const
init
=
()
=>
{
for
(
let
i
=
0
;
i
<
10
;
i
++
)
{
data
.
defultList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
}
onMounted
(()
=>
{
init
()
});
return
{
scrollChange
,
loadMore
,
isLoading
,
hasMore
,
...
toRefs
(
data
)
};
}
```
### 自定义加载文案
```
html
<ul
class=
"infiniteUl"
id=
"customScroll"
>
<nut-infiniteloading
containerId =
'customScroll'
:useWindow=
'false'
:isLoading=
"customIsLoading"
:hasMore=
"customHasMore"
@
loadMore=
"customLoadMore"
>
<li
class=
"infiniteLi"
v-for=
"(item, index) in customList"
:key=
"index"
>
{{item}}
</li>
<template
v-slot:loading
>
<div
class=
"loading"
>
<span>
加载中...
</span>
</div>
</template>
<template
v-slot:unloadMore
>
<div
class=
"unload-more"
>
没有数据啦 ~~
</div>
</template>
</nut-infiniteloading>
</ul>
```
```
javascript
setup
()
{
const
customIsLoading
=
ref
(
false
);
const
customHasMore
=
ref
(
true
);
const
data
=
reactive
({
customList
:
[
''
]
});
const
customLoadMore
=
()
=>
{
customIsLoading
.
value
=
true
;
setTimeout
(()
=>
{
const
curLen
=
data
.
customList
.
length
;
for
(
let
i
=
curLen
;
i
<
curLen
+
10
;
i
++
)
{
data
.
customList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
customIsLoading
.
value
=
false
;
if
(
data
.
customList
.
length
>
30
)
customHasMore
.
value
=
false
;
},
500
);
};
const
init
=
()
=>
{
for
(
let
i
=
0
;
i
<
10
;
i
++
)
{
data
.
customList
.
push
(
`
${
i
}
-- 塑像本来就在石头里,我只是把不要的部分去掉`
);
}
}
onMounted
(()
=>
{
init
()
});
return
{
customIsLoading
,
customHasMore
,
customLoadMore
,...
toRefs
(
data
)
};
}
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
|--------------|----------------------------------|--------|------------------|
| hasMore | 是否还有更多数据 | Boolean | true |
| isLoading | 是否加载中 | Boolean | false |
| threshold | 距离底部多远加载 | Number | 200 |
| useWindow | 将滚动侦听器添加到 window 否则侦听组件的父节点 | Boolean | true |
| useCapture | 是否使用捕获模式 true 捕获 false 冒泡 | Boolean | false |
| containerId | 在 useWindow 属性为 false 的时候,自定义设置节点ID | String | '' |
| unloadMoreTxt | “没有更多数”据展示文案 | String | '哎呀,这里是底部了啦' |
### Slot
| name | 说明 |
|--------|----------------|
| loading | 自定义“加载中”的展示形式 |
| unloadMore | 自定义“没有更多数据”的展示形式 |
### Events
| 事件名 | 说明 | 回调参数 |
|--------|----------------|--------------|
| loadMore | 继续加载的回调函数 | - |
| scrollChange | 实时监听滚动高度 | 滚动高度 |
\ No newline at end of file
src/packages/infiniteloading/index.scss
浏览文件 @
b53e028f
.nut-infiniteloading
{
display
:
block
;
width
:
100%
;
.nut-infinite-bottom
{
display
:
block
;
width
:
100%
;
padding-top
:
16px
;
font-size
:
12px
;
color
:
rgba
(
200
,
200
,
200
,
1
);
text-align
:
center
;
}
}
src/packages/infiniteloading/index.vue
浏览文件 @
b53e028f
<
template
>
<view
:class=
"classes"
@
click=
"handleClick"
>
<view>
{{
name
}}
</view>
<view>
{{
txt
}}
</view>
<view
class=
"nut-infiniteloading"
ref=
"scroller"
>
<view
class=
"nut-infinite-top"
></view>
<view
class=
"nut-infinite-container"
><slot></slot></view>
<view
class=
"nut-infinite-bottom"
>
<template
v-if=
"isLoading"
>
<nut-icon
name=
"refresh"
v-if=
"!slotLoading"
></nut-icon>
<slot
name=
"loading"
v-else
></slot>
</
template
>
<
template
v-else-if=
"!hasMore"
>
<view
class=
"tips"
v-if=
"!slotUnloadMore"
>
{{
unloadMoreTxt
}}
</view>
<slot
name=
"unloadMore"
v-else
></slot>
</
template
>
</view>
</view>
</template>
<
script
lang=
"ts"
>
import
{
toRefs
}
from
'
vue
'
;
import
{
ref
,
toRefs
,
onMounted
,
onUnmounted
}
from
'
vue
'
;
import
{
createComponent
}
from
'
@/utils/create
'
;
const
{
componentName
,
create
}
=
createComponent
(
'
infiniteloading
'
);
export
default
create
({
props
:
{
name
:
{
hasMore
:
{
type
:
Boolean
,
default
:
true
},
isLoading
:
{
type
:
Boolean
,
default
:
false
},
threshold
:
{
type
:
Number
,
default
:
200
},
unloadMoreTxt
:
{
type
:
String
,
default
:
''
default
:
'
哎呀,这里是底部了啦
'
},
txt
:
{
useWindow
:
{
type
:
Boolean
,
default
:
true
},
containerId
:
{
type
:
String
,
default
:
''
},
useCapture
:
{
type
:
Boolean
,
default
:
false
}
},
components
:
{},
emits
:
[
'
click
'
],
emits
:
[
'
scrollChange
'
,
'
loadMore
'
],
setup
(
props
,
{
emit
})
{
setup
(
props
,
{
emit
,
slots
})
{
console
.
log
(
'
componentName
'
,
componentName
);
const
{
name
,
txt
}
=
toRefs
(
props
);
const
{
hasMore
,
isLoading
,
threshold
,
containerId
,
useWindow
,
useCapture
}
=
toRefs
(
props
);
const
handleClick
=
(
event
:
Event
)
=>
{
emit
(
'
click
'
,
event
);
let
scrollEl
:
Window
|
HTMLElement
=
window
;
const
scroller
=
ref
<
null
|
HTMLElement
>
(
null
);
const
beforeScrollTop
=
ref
(
0
);
const
slotLoading
=
ref
(
false
);
const
slotUnloadMore
=
ref
(
false
);
/** 获取监听自定义滚动节点 */
const
getParentElement
=
el
=>
{
if
(
containerId
.
value
!=
''
)
{
return
document
.
querySelector
(
`#
${
containerId
.
value
}
`
);
}
return
el
&&
el
.
parentNode
;
};
const
requestAniFrame
=
()
=>
{
return
(
window
.
requestAnimationFrame
||
window
.
webkitRequestAnimationFrame
||
function
(
callback
)
{
window
.
setTimeout
(
callback
,
1000
/
60
);
}
);
};
/** 获取滚动条高度 */
const
getWindowScrollTop
=
()
=>
{
return
window
.
pageYOffset
!==
undefined
?
window
.
pageYOffset
:
(
document
.
documentElement
||
document
.
body
.
parentNode
||
document
.
body
).
scrollTop
;
};
return
{
name
,
txt
,
handleClick
};
const
calculateTopPosition
=
el
=>
{
if
(
!
el
)
{
return
0
;
}
return
el
.
offsetTop
+
calculateTopPosition
(
el
.
offsetParent
);
};
/** 判断是否滚动到底部 */
const
isScrollAtBottom
=
()
=>
{
let
offsetDistance
=
0
;
let
resScrollTop
=
0
;
let
direction
=
'
down
'
;
// 滚动的方向
const
windowScrollTop
=
getWindowScrollTop
();
if
(
useWindow
.
value
)
{
if
(
scroller
.
value
)
{
offsetDistance
=
calculateTopPosition
(
scroller
.
value
)
+
scroller
.
value
.
offsetHeight
-
windowScrollTop
-
window
.
innerHeight
;
}
resScrollTop
=
windowScrollTop
;
}
else
{
const
{
scrollHeight
,
clientHeight
,
scrollTop
}
=
scrollEl
as
HTMLElement
;
offsetDistance
=
scrollHeight
-
clientHeight
-
scrollTop
;
resScrollTop
=
scrollTop
;
}
if
(
beforeScrollTop
.
value
>
resScrollTop
)
{
direction
=
'
up
'
;
}
else
{
direction
=
'
down
'
;
}
beforeScrollTop
.
value
=
resScrollTop
;
emit
(
'
scrollChange
'
,
resScrollTop
);
return
offsetDistance
<=
threshold
.
value
&&
direction
==
'
down
'
;
};
/** 滚动函数 */
const
handleScroll
=
()
=>
{
requestAniFrame
()(()
=>
{
if
(
!
isScrollAtBottom
()
||
!
hasMore
.
value
||
isLoading
.
value
)
{
return
false
;
}
else
{
emit
(
'
loadMore
'
);
}
});
};
/** 滚动监听 */
const
scrollListener
=
()
=>
{
scrollEl
.
addEventListener
(
'
scroll
'
,
handleScroll
,
useCapture
.
value
);
};
/** 生命周期 首次加载 */
onMounted
(()
=>
{
const
parentElement
=
getParentElement
(
scroller
);
let
scrollElCopy
=
window
;
if
(
useWindow
.
value
===
false
)
{
scrollElCopy
=
parentElement
;
}
scrollEl
=
scrollElCopy
;
scrollListener
();
slotUnloadMore
.
value
=
slots
.
unloadMore
?
true
:
false
;
slotLoading
.
value
=
slots
.
loading
?
true
:
false
;
});
/** 移除监听 */
onUnmounted
(()
=>
{
scrollEl
.
removeEventListener
(
'
scroll
'
,
handleScroll
,
useCapture
.
value
);
});
return
{
scroller
,
slotLoading
,
slotUnloadMore
};
}
});
</
script
>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录