基於 vue +better scroll滑動切換頁面 並支持下拉刷新案例

也是公司項目 ,內部app的資訊模塊整改,改是不可能改的,之前還是用jquery。感覺越改越混亂,還是重做。就仿着今日頭條、等資訊頁面做了一個dome,話不多說,先看效果!

 微信掃碼預覽

效果看完,感覺還行的話,接着就往下看開啓爬坑之路!

先打一個無償廣告 上圖的gif 是通過LICEcap 軟件錄屏製作的!下載地址:官網地址,支持window mac ,無插件 無廣告 完全免費!確實好用,比起國內的動不動就要會員才能導出的***軟件要好的多

一、效果分析

看起來好像很常見,但是這個整體效果完成,對better scroll就比較熟悉了 做平常的滾動導航列表、輪播圖、下拉刷新、上拉加載等ui模板都應該小kiss了。頁面主要也就三個功能

  1. 頂部的可滑動導航列表
  2. 中間的可滑動切換頁 和導航列表有聯動效果
  3. 每頁列表頁都支持下拉刷新、上拉加載

二、功能實現

1.插件安裝

基於vue 和better scroll的項目,用vue cli 安裝vue的環境搭建 這一塊就不多說

better scroll的安裝

npm install better-scroll@next -S 

使用的話就比較簡單

 import BScroll from 'better-scroll';

  mounted() {
            this.initBscroll()
        },
  methods: {
           initBscroll() {
                this.bscroll = new BScroll(this.$refs.bsWrapper, {
                    scrollY: true,
                    bounceTime: TIME_BOUNCE,
                    pullDownRefresh: {
                        threshold: THRESHOLD,
                        stop: STOP
                    }
                })           
               this.bscroll.on('scroll', this.scrollHandler)
            },
            scrollHandler(pos) {
                console.log(pos.y)
            },     
       }  

使用的話也就是配置參數 對於這些參數詳細解釋就 分享一下api鏈接http://ustbhuangyi.github.io/better-scroll/doc/api.html

重要的標記一下:

一類是屬性 在new的時候傳入的 如scrollY:true 設置豎直方向可以滾動

一類是方法 就是在用戶操作過程中可以調用該方法 如scroll 就是頁面滾動中觸發的,調用語法如下

this.bscroll.on('scroll', this.scrollHandler)
            
scrollHandler(pos) {
                console.log(pos.y)
            },

上面爲實時打印滾動的位置案例

  • eventPassthrough

在屬性上 這裏要着重介紹 eventPassthrough屬性!該屬性默認值爲'' 可以設置'vertical'、'horizontal'簡單解釋一下  當eventPassthrough 設置vertical 時 該實例 只會相應水平的滑動事件 豎直方向事件將不會影響它如咱們案例中的 左右切換和下拉刷新就必須設置該屬性 ,不讓相互影響 整個頁面滑動效果就很卡頓

  • scrollToElement(el, time, offsetX, offsetY, easing)

在放方法上也介紹一下scrollToElement,就是滾動到指定元素 ,五個參數(滾動到哪個對象 所需時間 x偏移 y偏移 動畫效果)x偏移和y偏移 設置爲true是 就會滾動到該元素中心位置

2.頂部滾動導航實現

也提一下滾動原理  雖然黃佚老師講的很詳細了,但是還是提一下,這個主要就是爲了頁面如何佈局,內容區域大於wepper 纔可以觸發滾動,因此必須控制wrpper的大小,不能讓它的大小讓子元素撐開

 先是進行頁面佈局吧

頂部這一塊紅色標出的就是wrapper 大小固定 ,綠色的就是內容部分 可滾動;

而紅色區域的大小就是屏幕的寬度減去兩邊的寬度 這個實現可以用flex 實現 可以用aclc實現 個人還是傾向於flex

佈局完成之後就是 進行better scroll的初始化 對於這個實現就是 需要在激活狀態下滾動至該元素的最中間直接用scrollToElement實現 整體代碼如下:

<template>
    <div class="page" >
        <div class="topcontent">
            <div class="tranbox"></div>
            <div class="tab" ref="linescoll">
                <div class="tabitems" ref="picList">
                    <div v-for="(item,index) in navlist" class="tabitem" :class="item.id==activeitem.id?'tabactived':''" @click="changtab(item)" :key="index">{{item.title}}</div>
                </div>
            </div>
            <div class="additem">+</div>
        </div>
    </div>
</template>

<script>
    import BScroll from 'better-scroll';

    export default {
        data() {
            return {

                navlist:[
                    {title:'要聞', action:'', type:'', from:'ezx',id:1},
                    {title:'7*24', action:'', type:'', from:'ezx',id:2},
                    {title:'自選股', action:'', type:'', from:'ezx',id:3},
                    {title:'公司研報', action:'', type:'', from:'zz',id:4},
                    {title:'行業研究', action:'', type:'', from:'zz',id:5},
                    {title:'新三板新聞', action:'', type:'', from:'zz',id:6},
                    {title:'期貨研究', action:'', type:'', from:'zz',id:7},
                ],
                activeitem: {},
            };
        },
        watch:{
            activeitem:function(val) {
                let idx;
                this.navlist.map((item,index)=>{
                        if(item.id == val.id){
                            idx =  index
                        }
                    }
                );
                this.changetitle(val,idx);
            }
        },
        mounted(){
            this.init();
            this.activeitem =  {title:'7*24', action:'', type:'', from:'ezx',id:2};
        },
        methods: {
            init() {
                this.$nextTick(()=>{
                    //設置頂部滾動 navlist
                    this.scrollmethod = new BScroll(this.$refs.linescoll, {
                        bounce: true,
                        eventPassthrough: 'vertical',
                        scrollX: true,
                        scrollY: false,
                        preventDefault: false
                    });
                });
            },
            changetitle(item,index){
                let idx = index+1;
                let dom = document.querySelector('.tabitems .tabitem:nth-child(' + idx + ')');
                this.$nextTick(() => {
                    //標題滾動到對應位置
                    // 五個參數 滾動到元素 時間  水平偏移 豎直偏移  後兩個爲true 則是中心位置 最後一個 設置動畫效果
                    this.scrollmethod.scrollToElement(dom, null, true, true);
                })
            },
            changtab(item) {
                this.activeitem = item;
            }
        }

    };
</script>

<style lang="scss"  scoped>
    .page{
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-color: rgba(247, 247, 247, 1);
        .topcontent {
            z-index: 999;
            display: flex;
            .tranbox{
                width: 10px;
                background-color: #fff;
                z-index: 999;
            }
            .tab{
                background-color: #fff;
                flex: 1;
                overflow: hidden;
                .tabitems{
                    display: inline-flex;
                    width: auto;
                    .tabitem{
                        flex: 1;
                        font-size: 15px;
                        line-height: 24px;
                        padding:10px 17px;
                        color: #333333;
                        text-align: center;
                        display: inline-flex;
                        justify-content: center;
                        box-sizing: border-box;
                        flex-wrap: nowrap;
                        white-space: nowrap;
                    }
                    .tabactived{
                        color:#F14D44;
                        position: relative;
                        font-size: 17px;
                        line-height: 24px;
                        &:after{
                            position: absolute;
                            content: "";
                            bottom: 0;
                            left: 20%;
                            width: 60%;
                            height: 3px;
                            background-color: #F14D44;
                        }
                    }
                }
            }
            .additem{
                height: 100%;
                width: 45px;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: #fff;
                font-size: 20px;
                line-height: 24px;
                padding:10px 0;
                color: #888;
                box-shadow: 0 -5px 5px #ddd;
                z-index: 999;

            }
        }
    }
</style>

複製代碼就可以實現以下效果 算是一個 簡單的滾動導航條了吧

2. 滑動切換slider實現

用better scroll實現slider也是相當方便 直接就slider這個對象屬性,初始化時候添加進來就好,而這個頁面佈局如下

 根據咱們的項目 添加一些初始數據 在init 中在初始化一下 slider

<template>
    <div class="page" >
        <div class="topcontent">
            <div class="tranbox"></div>
            <div class="tab" ref="linescoll">
                <div class="tabitems" ref="picList">
                    <div v-for="(item,index) in navlist" class="tabitem" :class="item.id==activeitem.id?'tabactived':''" @click="changtab(item)" :key="index">{{item.title}}</div>
                </div>
            </div>
            <div class="additem">+</div>
        </div>
        <div class="center">
            <div class="slide-banner-scroll" ref="slide">
                <div class="slide-banner-wrapper">
                    <div class="slide-item"  v-for="item in navlist" :key="item.id">
                        <div class="zxlinelistbox" :class="'page'+item.id">
                            <div class="zxcontentbox">
                                <zxlist :zxlist="listdata" :readId="readId" @zxitemclick="zxitemclick"></zxlist>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import BScroll from 'better-scroll';
    import zxlist from '../components/zxlist'
    export default {
        components:{
            zxlist:zxlist
        },
        data() {
            return {
                listdata:[],
                navlist:[
                    {title:'要聞', action:'', type:'', from:'ezx',id:1},
                    {title:'7*24', action:'', type:'', from:'ezx',id:2},
                    {title:'自選股', action:'', type:'', from:'ezx',id:3},
                    {title:'公司研報', action:'', type:'', from:'zz',id:4},
                    {title:'行業研究', action:'', type:'', from:'zz',id:5},
                    {title:'新三板新聞', action:'', type:'', from:'zz',id:6},
                    {title:'期貨研究', action:'', type:'', from:'zz',id:7},
                ],
                activeitem: {},
            };
        },
        watch:{
            activeitem:function(val) {
                let idx;
                this.navlist.map((item,index)=>{
                        if(item.id == val.id){
                            idx =  index
                        }
                    }
                );
                this.changetitle(val,idx);
            }
        },
        created(){
            let data = {"code":0,
                "message":"SUCCESS",
                "data":[
                    {"item_title":"央行開展1年期MLF操作3000億元 操作利率3.25%","author":["吳曉輝"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 10:03:57","news_type":"11","item_id":"552942","label":[]},
                    {"item_title":"2019年業績續虧跌停 時代萬恆打響保殼戰","author":["孫憲超"],"img":["https://resource-e2-oss.egsea.com/upload/2020/0115/09/20130419044553.jpg?x-oss-process=image/resize,m_fixed,h_150,w_200"],"is_original":"1","is_top":"0","is_red":"0","is_recom":"1","creat_time":"2020-01-15 10:03:44","news_type":"11","item_id":"552945","label":["600241"]},
                    {"item_title":"上海:將完善居轉戶政策 加快建設國際人才高地","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:59:13","news_type":"11","item_id":"552965","label":[]},{"item_title":"上海市市長應勇:加快建設全球性人民幣產品創新、交易、定價和清算中心","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:58:12","news_type":"11","item_id":"552949","label":[]},{"item_title":"【e公司微訪談】雄塑科技:“小管道”有大商機 市政工程打開新增長空間","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:56:41","news_type":"11","item_id":"552824","label":["300599"]},{"item_title":"區塊鏈概念股盤中拉昇 聯絡互動、智度股份等漲停","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:55:41","news_type":"11","item_id":"552959","label":["000676","002280","603888"]},{"item_title":"上海市市長應勇:全面實施集成電路、人工智能、生物醫藥“上海方案”","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:55:28","news_type":"11","item_id":"552962","label":["000975"]},{"item_title":"上海市市長應勇:2019年科創板70家企業成功上市 籌資額達到824億元","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"1","creat_time":"2020-01-15 09:51:34","news_type":"11","item_id":"552848","label":[]},{"item_title":"上海市市長應勇:上海房地產市場保持平穩健康發展","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:51:19","news_type":"11","item_id":"552872","label":[]},{"item_title":"上海市市長應勇:支持和鼓勵更多科創企業上市","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:51:02","news_type":"11","item_id":"552932","label":[]}],
                "pageinfo":{"pageNum":1,"pageSize":10,"totalCount":3497,"totalPages":350}
            }
            this.listdata = data.data
        },
        mounted(){
            this.init();
            this.activeitem =  {title:'7*24', action:'', type:'', from:'ezx',id:2};
        },
        methods: {
            init() {
                this.$nextTick(()=>{
                    //設置頂部滾動 navlist
                    this.scrollmethod = new BScroll(this.$refs.linescoll, {
                        bounce: true,
                        eventPassthrough: 'vertical',
                        scrollX: true,
                        scrollY: false,
                        preventDefault: false
                    });

                    //設置輪播頁面
                    this.slide = new BScroll(this.$refs.slide, {
                        scrollX: true,
                        scrollY: false,
                        slide: {
                            loop: false,
                            threshold: 100
                        },
                        eventPassthrough:"vertical",
                        momentum: false,
                        // bounce: true,
                    })
                    this.slide.on('scrollEnd', this._onScrollEnd)
                });
            },

            _onScrollEnd() {
                console.log('endssssss')
                let index = this.slide.getCurrentPage().pageX;
                let item  =  this.navlist[index];
                this.activeitem = item;
            },

            changetitle(item,index){
                let idx = index+1;
                let dom = document.querySelector('.tabitems .tabitem:nth-child(' + idx + ')');
                this.$nextTick(() => {
                    //標題滾動到對應位置
                    // 五個參數 滾動到元素 時間  水平偏移 豎直偏移  後兩個爲true 則是中心位置 最後一個 設置動畫效果
                    this.scrollmethod.scrollToElement(dom, null, true, true);
                    this.scrollmethod.refresh();
                    //詳情頁滾動到對應頁面
                    this.slide.goToPage(index);
                })
            },
            changtab(item) {
                this.activeitem = item;
            }
        }

    };
</script>

<style lang="scss"  scoped>
    .page{
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-color: rgba(247, 247, 247, 1);
        .topcontent {
            z-index: 999;
            display: flex;
            .tranbox{
                width: 10px;
                background-color: #fff;
                z-index: 999;
            }
            .tab{
                background-color: #fff;
                flex: 1;
                overflow: hidden;
                .tabitems{
                    display: inline-flex;
                    width: auto;
                    .tabitem{
                        flex: 1;
                        font-size: 15px;
                        line-height: 24px;
                        padding:10px 17px;
                        color: #333333;
                        text-align: center;
                        display: inline-flex;
                        justify-content: center;
                        box-sizing: border-box;
                        flex-wrap: nowrap;
                        white-space: nowrap;
                    }
                    .tabactived{
                        color:#F14D44;
                        position: relative;
                        font-size: 17px;
                        line-height: 24px;
                        &:after{
                            position: absolute;
                            content: "";
                            bottom: 0;
                            left: 20%;
                            width: 60%;
                            height: 3px;
                            background-color: #F14D44;
                        }
                    }
                }
            }
            .additem{
                height: 100%;
                width: 45px;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: #fff;
                font-size: 20px;
                line-height: 24px;
                padding:10px 0;
                color: #888;
                box-shadow: 0 -5px 5px #ddd;
                z-index: 999;

            }
        }
        .center {
            flex: 1;
            overflow-y: auto;
            margin-top: -1px;
            -webkit-overflow-scrolling: touch;
            .slide-banner-scroll{
                width: 100%;
                height: 100%;
                touch-action: none;
                .slide-banner-wrapper{
                    height: 100%;
                    .slide-item{
                        width: 100%;
                        height: 100%;
                        display: inline-block;
                        position: relative;
                        .zxlinelistbox{
                            height: 100%;
                            .zxcontentbox{
                                padding-bottom: 20px;
                            }
                        }
                    }
                }
            }
        }
    }
</style>

其中silder有個方法就是 goToPage

this.slide.goToPage(index);

傳入頁碼 自動滾動至對應頁數 所用的變化都在watch 中實現,這樣保證了數據變化就可以觸發 實現了上下聯動效果 效果如下

 4.實現下拉刷新 上拉加載更多

現在是水平方向有多個頁面 要實現下拉刷新 上拉加載,爲了保證每個頁面的獨立性,在每個頁面激活後 給該頁面增加該效果,就在watch中添加,爲了防止其他頁面干擾 切換前先清除下拉 scroll 爲了防止和slider干擾 設置一下eventPassthrough:"horizontal" 保證水平方向不干擾別人 slider 也設置eventPassthrough:"vertical", 保證豎直方向不干擾別人。

實現下拉效果和加載更多效果在初始化的時候還需要設置pullUpLoad 和 pullDownRefresh

初始化如下

this.bscroll = new BScroll(scldom, {
                        click: true,
                        scrollX: false,
                        scrollY: true,
                        // momentum:false,
                        bounceTime: 800,
                        pullUpLoad:{
                            threshold: 70,
                        },
                        pullDownRefresh: {
                            threshold: 20,
                            stop:56
                        },
                        eventPassthrough:"horizontal"
                    });
                }
this.bscroll.on('pullingDown', this.pullingDownHandler)
this.bscroll.on('pullingUp', this.pullingUpHandler)

修復問題:在頁面來回切換過程中 發現下拉刷新 的定時器沒有清除 導致 下拉刷新沒有重置 因此在初始化時加了一下判斷

    initscrldata(){
                this.loadingtxt='下拉刷新';
                this.dragTip={
                    text:"釋放刷新",
                        translate:-50,
                        showLoding:false
                },
                this.beforePullDown=true;
                this.isPullingDown= false;
                this.isPullUpLoad=true;
                this.canloading=true;
                if(this.bscroll){
                    this.bscroll.finishPullDown()
                    this.bscroll.finishPullUp();
                    this.bscroll.destroy();
                }
                if(this.timer2){
                    let vm = this;
                    clearTimeout(vm.timer2)
                }
                if(this.timer){
                    let vm = this;
                    clearTimeout(vm.timer)
                }
                if(this.timer1){
                    let vm = this;
                    clearTimeout(vm.timer1)
                }
                this.bscroll = null;
            },

 最終代碼如下。複製即可使用!

<template>
    <div class="page" ref="page">
        <div class="topcontent" style="">
            <div class="tranbox"></div>
            <div class="tab" ref="linescoll">
                <!--11 快訊(e 線)、12 解讀、13 情報(131 早知道、132 漲停板、133 龍虎榜、134 數 說 A 股)、21 新三板、22 科創板-->
                <div class="tabitems" ref="picList">
                    <div v-for="(item,index) in navlist" class="tabitem" :class="item.id==activeitem.id?'tabactived':''" @click="changtab(item)" :key="index">{{item.title}}</div>
                </div>
            </div>
            <div class="additem">+</div>
        </div>
        <div class="center">
            <div class="slide-banner-scroll" ref="slide">
                <div class="slide-banner-wrapper">
                    <div class="slide-item"  v-for="item in navlist" :key="item.id">
                        <div class="zxlinelistbox" :class="'page'+item.id">
                            <div class="zxcontentbox">
                                <div class="pulldown-wrapper">
                                    <div v-show="beforePullDown">
                                        <span>鬆開刷新</span>
                                    </div>
                                    <div v-show="!beforePullDown">
                                        <div v-show="isPullingDown">
                                            <span>刷新中...</span>
                                        </div>
                                        <div v-show="!isPullingDown"><span>刷新成功</span></div>
                                    </div>
                                </div>
                                <div class="zxcollist">
                                    <div class="zxcolitem" v-for="(item,index) in listdata" :key="index">
                                        <label :class="readId.indexOf(item.item_id)!=-1?'readed':''">
                                            <div v-if="item.item_title && item.item_title.length<30">{{item.item_title}}</div>
                                            <div v-else>{{item.item_title.slice(0,30)}}...</div>
                                            <div>{{item.creat_time}}</div>
                                        </label>
                                        <label v-if="item.img && item.img[0]" class="itemimg">
                                            <img :src="item.img[0]">
                                        </label>
                                    </div>
                                </div>
                                <div class="pullup-wrapper" v-if="canloading && listdata.length>0">
                                    <div v-if="!isPullUpLoad" class="before-trigger">
                                        <span class="pullup-txt">上拉加載更多</span>
                                    </div>
                                    <div v-else class="after-trigger">
                                        <span class="pullup-txt">加載中...</span>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                </div>
            </div>
        </div>
    </div>
</template>

<script>
    import BScroll from 'better-scroll';
    export default {
        data() {
            return {
                loadingtxt:'下拉刷新',
                dragTip:{
                    text:"釋放刷新",
                    translate:-50,
                    showLoding:false
                },
                beforePullDown: true,
                isPullingDown: false,
                isPullUpLoad:true,
                canloading:true,
                navlist:[
                    {title:'要聞', action:'', type:'', from:'ezx',id:1},
                    {title:'7*24', action:'', type:'', from:'ezx',id:2},
                    {title:'自選股', action:'', type:'', from:'ezx',id:3},
                    {title:'公司研報', action:'', type:'', from:'zz',id:4},
                    {title:'行業研究', action:'', type:'', from:'zz',id:5},
                    {title:'新三板新聞', action:'', type:'', from:'zz',id:6},
                    {title:'期貨研究', action:'', type:'', from:'zz',id:7},
                ],
                activeitem: {},
                listdata:[],  //數據
                readId:['552942']
            };
        },
        watch:{
            activeitem:function(val) {
                let idx;
                this.navlist.map((item,index)=>{
                        if(item.id == val.id){
                            idx =  index
                        }
                    }
                );
                this.changetitle(val,idx);
            }
        },
        created(){
            let data = {"code":0,
                "message":"SUCCESS",
                "data":[
                    {"item_title":"央行開展1年期MLF操作3000億元 操作利率3.25%","author":["吳曉輝"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 10:03:57","news_type":"11","item_id":"552942","label":[]},
                    {"item_title":"2019年業績續虧跌停 時代萬恆打響保殼戰","author":["孫憲超"],"img":["https://resource-e2-oss.egsea.com/upload/2020/0115/09/20130419044553.jpg?x-oss-process=image/resize,m_fixed,h_150,w_200"],"is_original":"1","is_top":"0","is_red":"0","is_recom":"1","creat_time":"2020-01-15 10:03:44","news_type":"11","item_id":"552945","label":["600241"]},
                    {"item_title":"上海:將完善居轉戶政策 加快建設國際人才高地","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:59:13","news_type":"11","item_id":"552965","label":[]},{"item_title":"上海市市長應勇:加快建設全球性人民幣產品創新、交易、定價和清算中心","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:58:12","news_type":"11","item_id":"552949","label":[]},{"item_title":"【e公司微訪談】雄塑科技:“小管道”有大商機 市政工程打開新增長空間","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:56:41","news_type":"11","item_id":"552824","label":["300599"]},{"item_title":"區塊鏈概念股盤中拉昇 聯絡互動、智度股份等漲停","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:55:41","news_type":"11","item_id":"552959","label":["000676","002280","603888"]},{"item_title":"上海市市長應勇:全面實施集成電路、人工智能、生物醫藥“上海方案”","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:55:28","news_type":"11","item_id":"552962","label":["000975"]},{"item_title":"上海市市長應勇:2019年科創板70家企業成功上市 籌資額達到824億元","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"1","creat_time":"2020-01-15 09:51:34","news_type":"11","item_id":"552848","label":[]},{"item_title":"上海市市長應勇:上海房地產市場保持平穩健康發展","author":["彭飛"],"img":[],"is_original":"1","is_top":"0","is_red":"0","is_recom":"0","creat_time":"2020-01-15 09:51:19","news_type":"11","item_id":"552872","label":[]},{"item_title":"上海市市長應勇:支持和鼓勵更多科創企業上市","author":["陳文斌"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 09:51:02","news_type":"11","item_id":"552932","label":[]}],
                "pageinfo":{"pageNum":1,"pageSize":10,"totalCount":3497,"totalPages":350}
            }
            this.listdata = data.data
        },
        mounted(){
            this.init();
            this.activeitem =  {title:'7*24', action:'', type:'', from:'ezx',id:2};
        },
        methods: {
            init() {
                this.$nextTick(()=>{
                    //設置頂部滾動 navlist
                    this.scrollmethod = new BScroll(this.$refs.linescoll, {
                        bounce: true,
                        eventPassthrough: 'vertical',
                        scrollX: true,
                        scrollY: false,
                        preventDefault: false
                    });
                    //設置輪播頁面
                    this.slide = new BScroll(this.$refs.slide, {
                        scrollX: true,
                        scrollY: false,
                        slide: {
                            loop: false,
                            threshold: 100
                        },
                        eventPassthrough:"vertical",
                        momentum: false,
                        // bounce: true,
                    })
                    this.slide.on('scrollEnd', this._onScrollEnd)
                });
            },
            _onScrollEnd() {
                console.log('endssssss')
                let index = this.slide.getCurrentPage().pageX;
                let item  =  this.navlist[index];
                this.activeitem = item;
            },
            initscrldata(){
                this.loadingtxt='下拉刷新';
                this.dragTip={
                    text:"釋放刷新",
                    translate:-50,
                    showLoding:false
                },
                    this.beforePullDown=true;
                this.isPullingDown= false;
                this.isPullUpLoad=true;
                this.canloading=true;
                if(this.bscroll){
                    this.bscroll.finishPullDown()
                    this.bscroll.finishPullUp();
                    this.bscroll.destroy();
                }
                if(this.timer2){
                    let vm = this;
                    clearTimeout(vm.timer2)
                }
                if(this.timer){
                    let vm = this;
                    clearTimeout(vm.timer)
                }
                if(this.timer1){
                    let vm = this;
                    clearTimeout(vm.timer1)
                }
                this.bscroll = null;
            },
            _initScroll() {
                var refstr  =  'page'+ this.activeitem.id;
                console.log(refstr)
                this.initscrldata();
                var scldom = document.querySelector('.'+refstr);
                if(this.bscroll){
                    this.bscroll.finishPullDown()
                    this.bscroll.finishPullUp();
                    this.bscroll.refresh();
                }else {
                    console.log('nesssssss')
                    this.bscroll = new BScroll(scldom, {
                        click: true,
                        scrollX: false,
                        scrollY: true,
                        // momentum:false,
                        bounceTime: 800,
                        pullUpLoad:{
                            threshold: 70,
                        },
                        pullDownRefresh: {
                            threshold: 20,
                            stop:56
                        },
                        eventPassthrough:"horizontal"
                    });
                }
                this.bscroll.on('pullingDown', this.pullingDownHandler)
                this.bscroll.on('pullingUp', this.pullingUpHandler)
            },
            async pullingUpHandler() {
                // if(!this.canloading || this.zxlist.length ===0){
                //     return
                // }
                console.log("babababaabaaaaa");
                this.isPullUpLoad = true;
                // this.page++;
                // await this.getzxdata();
                setTimeout(()=>{
                    this.listdata.push({"item_title":"央行開展1年期MLF操作3000億元 操作利率3.25%","author":["吳曉輝"],"img":[],"is_original":"1","is_top":"0","is_red":"1","is_recom":"1","creat_time":"2020-01-15 10:03:57","news_type":"11","item_id":"552942","label":[]})
                    this.listdata.push({"item_title":"2019年業績續虧跌停 時代萬恆打響保殼戰","author":["孫憲超"],"img":["https://resource-e2-oss.egsea.com/upload/2020/0115/09/20130419044553.jpg?x-oss-process=image/resize,m_fixed,h_150,w_200"],"is_original":"1","is_top":"0","is_red":"0","is_recom":"1","creat_time":"2020-01-15 10:03:44","news_type":"11","item_id":"552945","label":["600241"]})
                    this.$nextTick(()=>{
                        this.bscroll.finishPullUp();
                        this.bscroll.refresh();
                        this.isPullUpLoad = false
                    });
                } ,1000)

            },
            async pullingDownHandler() {
                this.beforePullDown = false
                this.isPullingDown = true
                // STEP += 10
                this.timer =  setTimeout(() =>{
                    this.isPullingDown = false;
                    this.finishPullDown()
                },5000);

                // await this.getzxdata();
                // this.getbannerdata().then(() =>{
                //     this.getkjzxdata()
                // }).then(() =>{
                //     this.loadIcons();
                //     this.isPullingDown = false;
                //     this.finishPullDown()
                // });

            },
            async finishPullDown() {
                let vm =this;
                const stopTime = 600
                await new Promise(resolve => {
                    vm.timer1 =   setTimeout(() => {
                        this.bscroll.finishPullDown()
                        resolve()
                    }, stopTime)
                })
                vm.timer2 = setTimeout(() => {
                    console.log("刷新完成!!!!!!!!!!!!")
                    this.beforePullDown = true
                    this.bscroll.refresh()
                }, 600)
            },
            changetitle(item,index){
                let idx = index+1
                let dom = document.querySelector('.tabitems .tabitem:nth-child(' + idx + ')');
                this.$nextTick(() => {
                    //標題滾動到對應位置
                    // 五個參數 滾動到元素 時間  水平偏移 豎直偏移  後兩個爲true 則是中心位置 最後
                    this.scrollmethod.scrollToElement(dom, null, true, true);
                    this.scrollmethod.refresh();
                    //詳情頁滾動到對應頁面
                    this.slide.goToPage(index);
                    //對應頁加載 上拉下拉事件

                    this._initScroll();
                })
            },

            changtab(item) {
                this.activeitem = item;
            }
        }

    };
</script>

<style lang="scss"  scoped>
    .page{
        display: flex;
        flex-direction: column;
        width: 100%;
        height: 100%;
        overflow: hidden;
        background-color: rgba(247, 247, 247, 1);
        .topcontent {
            z-index: 999;
            display: flex;
            .tranbox{
                width: 10px;
                background-color: #fff;
                z-index: 999;
            }
            .tab{
                background-color: #fff;
                flex: 1;
                width: calc(100% - 60px);
                /*display: flex;*/
                /*flex-wrap: nowrap;*/
                .tabitems{
                    display: inline-flex;
                    width: auto;
                    .tabitem{
                        flex: 1;
                        font-size: 15px;
                        line-height: 24px;
                        padding:10px 17px;
                        color: #333333;
                        text-align: center;
                        /*min-width: 22vw;*/
                        display: inline-flex;
                        justify-content: center;
                        box-sizing: border-box;
                        flex-wrap: nowrap;
                        white-space: nowrap;
                    }
                    .tabactived{
                        color: #f14d44;
                        position: relative;
                        font-size: 17px;
                        line-height: 24px;
                        &:after{
                            position: absolute;
                            content: "";
                            bottom: 0;
                            left: 20%;
                            width: 60%;
                            height: 3px;

                            background-color: #f14d44;
                        }
                    }
                }

            }
            .additem{
                height: 100%;
                width: 45px;
                display: flex;
                justify-content: center;
                align-items: center;
                background-color: #fff;
                font-size: 20px;
                line-height: 24px;
                padding:10px 0;
                color: #888;
                box-shadow: 0 -5px 5px #ddd;
                z-index: 999;
            }
        }
        .center {
            flex: 1;
            overflow-y: auto;
            margin-top: -1px;
            -webkit-overflow-scrolling: touch;
            .slide-banner-scroll{
                width: 100%;
                height: 100%;
                touch-action: none;
                .slide-banner-wrapper{
                    height: 100%;
                    .slide-item{
                        width: 100%;
                        height: 100%;
                        display: inline-block;
                        position: relative;
                        .zxlinelistbox{
                            height: 100%;
                            .zxcontentbox{
                                padding-bottom: 20px;
                            }
                            .zxcollist{
                                padding: 0 15px;
                                /*margin-top: 15px;*/
                                .zxcolitem{
                                    margin-top: 10px;
                                    background-color: #fff;
                                    border-radius:8px;
                                    display: flex;
                                    align-items: flex-start;
                                    padding: 15px;
                                    box-sizing: border-box;
                                    label:first-child{
                                        /*padding-right: 20px;*/
                                        box-sizing: border-box;
                                        flex: 1;
                                        color:rgba(33,32,41,1);
                                        display: flex;
                                        flex-direction: column;
                                        justify-content: space-between;
                                        height:75px;
                                        div:first-child{
                                            margin-top: -2px;
                                            font-size:17px;
                                            font-family:PingFang-SC-Medium;
                                            line-height:24px;
                                            letter-spacing:0;
                                            /*text-align: justify;*/
                                        }
                                        div:last-child{
                                            font-size:12px;
                                            font-family:PingFang-SC-Medium;
                                            color:rgba(153,153,153,1);
                                            line-height:12px;
                                            margin-bottom: 2px;
                                        }
                                    }
                                    .itemimg{
                                        width: 120px;
                                        height:75px;
                                        padding-left: 20px;
                                        img{
                                            width:100%;
                                            height:75px;
                                            border-radius:4px;
                                            background-color: #eee;
                                            border: solid 1px #eee;
                                            /*border: none;*/
                                        }
                                    }
                                    .readed{
                                        div:first-child{
                                            color:#888;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        .pulldown-wrapper{
            position: absolute;
            width: 100%;
            padding: 20px;
            box-sizing: border-box;
            transform: translateY(-100%) translateZ(0);
            text-align: center;
            color: #999}
        .pullup-wrapper{
            .before-trigger, .after-trigger{
                padding: 8px;
                font-size:14px;
                color: #888;
                text-align: center;
            }
        }
        .pulldown,.pullup{
            width:100%;
            position:relative;
            div.clear{
                padding:10px 0px;
                font-size:.28rem;
                position:absolute;
                left:50%;
                top:5px;
                transform:translate(-50%,0);
                .list-donetip{
                    text-align:center;
                    line-height:50px;
                    font-size:.28rem;
                }}}
    }
</style>

用的sass 作爲css的預編譯,作爲demo 就沒分模塊化,也方便快速實現功能 和改造,本來想弄githup上 但是一想光pull 和npm 一下就很費時間 直接貼代碼好了 ,只要有sass 和 npm 一下better scroll 創建一個vue 複製進去就可以跑起來 感覺更方便一些!

 

發佈了28 篇原創文章 · 獲贊 18 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章