u-list.vue 5 KB
   1
   2
   3
   4
   5
   6
   7
   8
   9
  10
  11
  12
  13
  14
  15
  16
  17
  18
  19
  20
  21
  22
  23
  24
  25
  26
  27
  28
  29
  30
  31
  32
  33
  34
  35
  36
  37
  38
  39
  40
  41
  42
  43
  44
  45
  46
  47
  48
  49
  50
  51
  52
  53
  54
  55
  56
  57
  58
  59
  60
  61
  62
  63
  64
  65
  66
  67
  68
  69
  70
  71
  72
  73
  74
  75
  76
  77
  78
  79
  80
  81
  82
  83
  84
  85
  86
  87
  88
  89
  90
  91
  92
  93
  94
  95
  96
  97
  98
  99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
<template>
<!-- #ifdef APP-NVUE -->
<list
class="u-list"
:enableBackToTop="enableBackToTop"
:loadmoreoffset="lowerThreshold"
:showScrollbar="showScrollbar"
:style="[listStyle]"
:offset-accuracy="Number(offsetAccuracy)"
@scroll="onScroll"
@loadmore="scrolltolower"
>
<slot />
</list>
<!-- #endif -->
<!-- #ifndef APP-NVUE -->
<scroll-view
class="u-list"
:scroll-into-view="scrollIntoView"
:style="[listStyle]"
scroll-y
:scroll-top="Number(scrollTop)"
:lower-threshold="Number(lowerThreshold)"
:upper-threshold="Number(upperThreshold)"
:show-scrollbar="showScrollbar"
:enable-back-to-top="enableBackToTop"
:scroll-with-animation="scrollWithAnimation"
@scroll="onScroll"
@scrolltolower="scrolltolower"
@scrolltoupper="scrolltoupper"
>
<view>
<slot />
</view>
</scroll-view>
<!-- #endif -->
</template>

<script>
import props from './props.js';
// #ifdef APP-NVUE
const dom = uni.requireNativePlugin('dom')
// #endif
/**
* List 列表
* @description 该组件为高性能列表组件
* @tutorial https://www.uviewui.com/components/list.html
* @property {Boolean} showScrollbar 控制是否出现滚动条,仅nvue有效 (默认 false )
* @property {String | Number} lowerThreshold 距底部多少时触发scrolltolower事件 (默认 50 )
* @property {String | Number} upperThreshold 距顶部多少时触发scrolltoupper事件,非nvue有效 (默认 0 )
* @property {String | Number} scrollTop 设置竖向滚动条位置(默认 0 )
* @property {String | Number} offsetAccuracy 控制 onscroll 事件触发的频率,仅nvue有效(默认 10 )
* @property {Boolean} enableFlex 启用 flexbox 布局。开启后,当前节点声明了display: flex就会成为flex container,并作用于其孩子节点,仅微信小程序有效(默认 false )
* @property {Boolean} pagingEnabled 是否按分页模式显示List,(默认 false )
* @property {Boolean} scrollable 是否允许List滚动(默认 true )
* @property {String} scrollIntoView 值应为某子元素id(id不能以数字开头)
* @property {Boolean} scrollWithAnimation 在设置滚动条位置时使用动画过渡 (默认 false )
* @property {Boolean} enableBackToTop iOS点击顶部状态栏、安卓双击标题栏时,滚动条返回顶部,只对微信小程序有效 (默认 false )
* @property {String | Number} height 列表的高度 (默认 0 )
* @property {String | Number} width 列表宽度 (默认 0 )
* @property {String | Number} preLoadScreen 列表前后预渲染的屏数,1代表一个屏幕的高度,1.5代表1个半屏幕高度 (默认 1 )
* @property {Object} customStyle 定义需要用到的外部样式
*
* @example <u-list @scrolltolower="scrolltolower"></u-list>
*/
export default {
name: 'u-list',
mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
watch: {
scrollIntoView(n) {
this.scrollIntoViewById(n)
}
},
data() {
return {
// 记录内部滚动的距离
innerScrollTop: 0,
// vue下,scroll-view在上拉加载时的偏移值
offset: 0,
sys: uni.$u.sys()
}
},
computed: {
listStyle() {
const style = {},
addUnit = uni.$u.addUnit
if (this.width != 0) style.width = addUnit(this.width)
if (this.height != 0) style.height = addUnit(this.height)
// 如果没有定义列表高度,则默认使用屏幕高度
if (!style.height) style.height = addUnit(this.sys.windowHeight, 'px')
return uni.$u.deepMerge(style, uni.$u.addStyle(this.customStyle))
}
},
provide() {
return {
uList: this
}
},
created() {
this.refs = []
this.children = []
this.anchors = []
},
mounted() {},
methods: {
updateOffsetFromChild(top) {
this.offset = top
},
onScroll(e) {
let scrollTop = 0
// #ifdef APP-NVUE
scrollTop = e.contentOffset.y
// #endif
// #ifndef APP-NVUE
scrollTop = e.detail.scrollTop
// #endif
this.innerScrollTop = scrollTop
this.$emit('scroll', Math.abs(scrollTop))
},
scrollIntoViewById(id) {
// #ifdef APP-NVUE
// 根据id参数,找到所有u-list-item中匹配的节点,再通过dom模块滚动到对应的位置
const item = this.refs.find(item => item.$refs[id] ? true : false)
dom.scrollToElement(item.$refs[id], {
// 是否需要滚动动画
animated: this.scrollWithAnimation
})
// #endif
},
// 滚动到底部触发事件
scrolltolower(e) {
uni.$u.sleep(30).then(() => {
this.$emit('scrolltolower')
})
},
// #ifndef APP-NVUE
// 滚动到底部时触发,非nvue有效
scrolltoupper(e) {
uni.$u.sleep(30).then(() => {
this.$emit('scrolltoupper')
// 这一句很重要,能绝对保证在性功能障碍的webview,滚动条到顶时,取消偏移值,让页面置顶
this.offset = 0
})
}
// #endif
},
}
</script>

<style lang="scss" scoped>
@import "../../libs/css/components.scss";

.u-list {
@include flex(column);

}
</style>