@minix-iot/ui
Version:
基于Vue的移动端轻量级UI组件库
176 lines (171 loc) • 5.31 kB
JSX
import { Namespace } from "../../utils/namespace"
import { DOMExtension } from "../../utils/extensions/dom";
import { throttle } from "../../utils/throttle";
const namespace = Namespace.Create('list')
import Loading from '../loading/loading.jsx'
export default {
name: namespace.name,
components:{
Loading,
},
data() {
return {
scrollParent: null,
check: null,
distanceY: -1,
}
},
props: {
loadingText: {
type: String,
},
loading: {
type: Boolean,
default: false
},
finished: {
type: Boolean,
default: false
},
finishedText: {
type: String,
default: '没有更多了'
},
error: {
type: Boolean,
default: false
},
errorText: {
type: String,
default: '加载失败,点击重试'
},
offset:{
type: Number,
default: 50
},
loadingType:{
type: String,
default: 'spinner'
},
immediateCheck: {
type: Boolean,
default: true
},
direction: {
type: String,
default: 'up'
},
laodingType: {
type: String,
default: 'spinner'
}
},
computed: {
cls () {
return namespace.derive();
},
tipCls() {
return namespace.derive(['tip'])
},
},
methods:{
getElementTop(element) {
return DOMExtension.GetBoundingClientRect(element).top + DOMExtension.GetScrollTop(window)
},
checkScroll() {
const el = this.$el;
// 当前元素的上拥有滚动条元素的高度
const scrollerEleHeight = DOMExtension.GetBoundingClientRect(this.scrollParent).height;
// 当前元素的高度
const docHeight = DOMExtension.GetBoundingClientRect(el).height;
// 当前元素拥有滚动条上元素的滚动高度
const scrollTop = DOMExtension.GetScrollTop(this.scrollParent);
const totalHeight = scrollTop + scrollerEleHeight;
let isScrollFlag = false;
if (el === this.scrollParent) {
isScrollFlag = this.scrollParent.scrollHeight - totalHeight <= this.offset && scrollTop > this.distanceY;
} else {
isScrollFlag = docHeight - totalHeight <= this.offset && scrollTop > this.distanceY;
}
this.distanceY = scrollTop;
if (isScrollFlag) {
this.$emit('input',true)
this.$emit('load')
}
}
},
mounted() {
this.scrollParent = DOMExtension.GetScrollParent(this.$el);
this.check = throttle(this.checkScroll, 500, 2)
DOMExtension.AddEventListener(this.scrollParent,'scroll', this.check);
if(this.immediateCheck) {
this.checkScroll();
}
},
destroyed() {
DOMExtension.RemoveEventListener(this.scrollParent, 'scroll', this.check)
},
render() {
const onClick = () => {
this.$emit('input',false);
this.$emit('load');
this.checkScroll();
}
const renderLoadingText = () => {
if (this.loading && !this.finished) {
return (
<div>
{
this.$slots.loading ? this.$slots.loading :
<p class={this.tipCls}>
<mx-loading type={this.laodingType}>{this.loadingText}</mx-loading>
</p>
}
</div>
)
}
}
const renderFinishedText = () =>{
if(this.finished) {
return (
<div>
{
this.$slots.finished ? this.$slots.finished :
<p class={this.tipCls}>{this.finishedText}</p>
}
</div>
)
}
}
const renderDefaultText = () =>{
if (!this.loading && !this.finished && !this.error) {
return (
<div>
<p class={this.tipCls}>上拉加载更多</p>
</div>
)
}
}
const renderErrorText = () => {
if (this.error) {
return (
<div>
{
this.$slots.error ? this.$slots.error :
<p class={this.tipCls} vOn:click={onClick}>{ this.errorText}</p>
}
</div>
)
}
}
return (
<div class={this.cls}>
{this.$slots.default}
{renderDefaultText()}
{renderLoadingText()}
{renderFinishedText()}
{renderErrorText()}
</div>
)
}
}