美文网首页
Vue中的数据更新了但UI没有刷新2

Vue中的数据更新了但UI没有刷新2

作者: 光明程辉 | 来源:发表于2020-03-12 16:16 被阅读0次

    这次是我们封装的一个scroll.vue组件

    <!--
     * @Author: liangcs
     * @Date: 2020-03-03 13:36:09
     * @LastEditors: liangcs
     * @LastEditTime: 2020-03-05 17:17:02
     * @FilePath: /h5-dev-mobile-sales-components/src/components/scroller/index.vue
     -->
    <template>
        <div ref="scroll" class="wrapper">
            <div class="scroll-content" ref="content">
                <slot></slot>
            </div>
            <div name="pull-down" v-if="pullDown">
              <slot name="pullDown" 
                :pullDownStyle="pullDownStyle"
                :beforePullDown="beforePullDown"
                :isPullingDown="isPullingDown"
                :readyPullDown="readyPullDown"
                >
                <div :style="pullDownStyle" class="pull-down" >{{pullDownLabel}}</div>
              </slot>
            </div>
        </div>
    </template>
    <script>
    let clickVal = (function(){
                        if (/iPhone|iPad|iPod|Macintosh/i.test(navigator.userAgent)) return false;
                        if (/Chrome/i.test(navigator.userAgent)) return (/Android/i.test(navigator.userAgent));
                        if (/Silk/i.test(navigator.userAgent)) return false;
                        if (/Android/i.test(navigator.userAgent)) {
                            var s=navigator.userAgent.substr(navigator.userAgent.indexOf('Android')+8,3);
                            return parseFloat(s[0]+s[3]) < 44 ? false : true}
                    }())
    const DEFAULT_OPTIONS = {
        probeType: 3,//probeType:1对性能没有影响。在滚动事件被触发时,滚动轴是不是忙着做它的东西。probeType:2总执行滚动,除了势头,反弹过程中的事件。这类似于原生的onscroll事件。probeType:3发出的滚动事件与到的像素精度。注意,滚动被迫requestAnimationFrame(即:useTransition:假)。
        scrollbars: false,//有滚动条
        mouseWheel: false,//允许滑轮滚动
        fadeScrollbars: false,//滚动时显示滚动条,默认影藏,并且是淡出淡入效果
        bounce: true,//边界反弹
        click: clickVal,
        disablePointer: true,
        disableTouch : false,
        disableMouse : true,
        eventPassthrough: 'horizontal',
        pullDownRefresh: false
    }
    const DEFAULT_PULLDOWN_OPTIONS = {
        threshold: 50,
        stop: 40
    }
    const SCROLL_EVENTS = ['scrollStart', 'scroll', 'scrollEnd']
    import BScroll from 'better-scroll'
    export default {
        data() {
            return {
                beforePullDown: true,
                readyPullDown: false,//到达下拉阀值
                isPullingDown: false,//触发下拉回调
                isPullingUp: false,
                pullDownStyle: ""
            }
        },
        props: {
            data: {
                type: Array,
                default () {
                    return []
                }
            },
            options: {
                type: Object,
                default () {
                    return {}
                }
            },
            // 是否仅需要滚动
            onlyScroll: {
                type: Boolean,
                default: false
            },
            // 是否启动无限加载
            pullUp: {
                type: Boolean,
                default: true
            },
            // 是否启动下拉
            pullDown: {
                type: Boolean,
                default: true
            },
            // 是否监听滚动事件
            listenScroll: {
                type: Boolean,
                default: false
            },
            hasLoading: {
                type: Boolean,
                default: true
            }
        },
        computed: {
          pullDownLabel() {
            if(this.isPullingDown) {
              return '正在加载';
            } else if(this.readyPullDown) {
              return '松开刷新'
            } else {
              return '下拉刷新'
            }
          }
        },
        mounted() {
            this._initScroll();
            // console.log(this.scroller.wrapperHeight);
            // 
        },
        watch: {
            data() { // 监听数据改变时直接刷新,不知道会不会有坑
                setTimeout(this.refresh,20)
            },
            pullDown(newVal, oldVal) {
                if(newVal) {
                    this.scroller.openPullDown(DEFAULT_PULLDOWN_OPTIONS)
                    if(!oldVal) {
                        this._onPullDownRefresh();
                        this._onPullDownScrollHandle();
                    }
                }
                if(!newVal && oldVal) {
                    this.scroller.closePullDown();
                    this._offPullDownScroll();
                    this._offPullDownRefresh();
                }
            },
            pullUp(newVal, oldVal) {
                if(newVal && !oldVal) {
                    this._onPullUpRefresh();
                }
                if(!newVal && oldVal) {
                    this._offPullUpRefresh();
                }
            }
        },
        methods: {
            _initScroll() {
                this._calMinHeight();
                var options = Object.assign({}, DEFAULT_OPTIONS, {
                    pullDownRefresh : this.pullDown ? DEFAULT_PULLDOWN_OPTIONS : false
                }, this.options)
                this.scroller = new BScroll(this.$refs.scroll, options)
                if(this.listenScroll) {
                  this._listenScroll();
                }
                //下拉刷新
                if(this.pullDown){
                    this._onPullDownRefresh();
                    this._onPullDownScroll();
                }
                if(this.pullUp) {
                    this._onPullUpRefresh();
                }
                
            },
            //解决内部元素小于scroll高度无法滑动的bug
            _calMinHeight() {
                this.$refs.content.style.minHeight = (this.$refs.scroll.offsetHeight+ 1)+'px';
            },
            refresh() {
                this.$nextTick(()=>{
                    if(this.isPullingDown) {
                        this.beforePullDown = true;
                        this.isPullingDown = false;
                        this.scroller.finishPullDown();
                    }
                    
                    this.isPullingUp = false;
                    this.scroller.refresh();
                })
            },
            _onPullDownRefresh() {
                this.scroller.on('pullingDown', this._pullDownHandle);
            },
            _onPullDownScroll() {
                this.scroller.on('scroll', this._pullDownScrollHandle);
            },
            _offPullDownRefresh() {
                this.scroller.off('pullingDown', this._pullDownHandle);
            },
            _offPullDownScroll() {
                this.scroller.off('scroll', this._pullDownScrollHandle);
            },
            _pullDownScrollHandle(pos) {
                if(this.beforePullDown) {
                    this.pullDownStyle = `top:${Math.min(pos.y - 40, 0)}px`
                } else {
                    this.pullDownStyle = `top:${Math.min(pos.y - 40, 0)}px`
                }
                if(pos.y>=50) {
                  this.readyPullDown = true;
                } else {
                  this.readyPullDown = false;
                }
            },
            _pullDownHandle() {
                this.beforePullDown = false;
                this.readyPullDown = false;
                this.isPullingDown = true;
                this.$emit('pullDown');
            },
            _onPullUpRefresh() {
                this.scroller.on('scroll', this.pullUpRefreshHandle)
            },
            _offPullUpRefresh() {
                this.scroller.off('scroll', this.pullUpRefreshHandle)
            },
            pullUpRefreshHandle(pos) {
                if(this.scroller.y < 0 && this.scroller.maxScrollY - this.scroller.y > -100 && !this.isPullingUp && !this.isPullingDown) {
                    this.isPullingUp = true;
                    this.$emit('pullup')
                }
            },
            _listenScroll() {
              SCROLL_EVENTS.forEach(v => {
                this.scroller.on(v, (...arg) => {
                  this.$emit(v, ...arg)
                })
              })
            },
            enable() {
              this.scroller && this.scroller.enable();
            },
            disable() {
              this.scroller && this.scroller.disable();
            },
            scrollTo() {
              this.scroller && this.scroller.scrollTo.apply(this.scroll, arguments)
            },
            scrollToElement() {
              this.scroller && this.scroller.scrollToElement.apply(this.scroll, arguments)
            }
    
        }
    }
    </script>
    <style lang="less" scoped>
        .wrapper {
          position: relative;
          height: 100%;
          .pull-down {
            position: absolute;
            width: 100%;
            line-height: 40px;
            text-align: center;
          }
        }
        
    </style>
    

    使用:

     <scroller ref="scroller" class="my-scroller" style="position:absolute;top:306px;bottom:10px;left:0;right:0" :pullDown="true" @pullDown="downLoading()" :pullUp="page.isMore" @pullUp='upLoading()'>
    </scroller>
    

    但是发现下拉刷新的时候,没反应,“下拉刷新” 不显示!

    因为么有,刷新!
    

    使用到一个方法

    // 刷新一下表
      this.$nextTick(()=>{
          this.$refs.scroller.refresh();
      });
    

    补充:
    上篇是

    这里是

    this.$nextTick

    在Vue生命周期的created()钩子函数进行的DOM操作一定要放在Vue.nextTick()的回调函数中。

    官网有说到这2者的区别:

    https://cn.vuejs.org/v2/api/index.html#Vue-nextTick

    相关文章

      网友评论

          本文标题:Vue中的数据更新了但UI没有刷新2

          本文链接:https://www.haomeiwen.com/subject/wpipjhtx.html