<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> 
 |