better-scroll技术总结

China☆狼群 提交于 2019-12-11 06:52:35

在这里插入图片描述

需要实现的功能:
1 从首页跳进列表页,传入index参数,nav要根据index值滚动到对应的dom位置
2 点击 nav => 触发点击的dom滚动到顶部,(每次点击nav,data和title都需要初始化滚动位置)
3 data数据更新,title数据更新
4 点击 title => title 可以横向滚动,data数据也要滚动到与title对应的数据位置

npm:
npm install better-scroll --save
页面中引入:
import BScroll from ‘better-scroll’

页面布局

<template>
    <div class="content">
        <!-- 1. nav -->
        <div class="nav_Warp">
            <ul>
                <li ref="nav_li" :class="{nav_active:nav_active == index}" @click="change_nav_active(index)" v-for="(item,index) in nav_list" :key="index">{{item}}</li>
            </ul>
        </div>
        
        <!-- 2. title + data -->
        <dataWarp :list="data_list"></dataWarp>
    </div>
</template>
<style scoped lang="less">
    .content{
        display: flex;
        .nav_Warp {
            width: 20%;
            background: #f4f4f4;
            height: 95vh;
            overflow: hidden;
            ul {
                overflow: scroll;
                padding-bottom: 50px;
                li {
                    padding-left: 10px;
                    border-left: 2px solid #f4f4f4;
                    text-align: left;
                    height: 50px;
                    line-height: 50px;
                    border-bottom: 1px solid #e8e9e8;
                    font-size: 12px;
                }
                .left_active{
                    border-left: 2px solid #3cb963;
                    font-size: 12px;
                    font-weight: bold;
                    color: #333333;
                    background: #fff;
                }
            }
        }
    }

</style>
// nav 初始化
<script>
    import BScroll from 'better-scroll' // 引入BScroll 
    import dataWarp from './dataWarp ' // 引入 dataWarp组件
    export default {
        components: {
            dataWarp,
        },
        data() {
            return {
                nav_list:[],// nav 列表数据
                data_list:[],// data + title 商品数据
                nav_active:0,// nav 高亮位置,默认第一索引0
            }
        },
        mounted() {
            // 初始化数据
            this._initData();
            // 如果首页跳转到列表页面 路由携带有参数,则200毫秒后触发nav滚动事件
            if(this.$route.query.currentIndex){
                setTimeout(()=>{
                    this.change_nav_active(this.$route.query.currentIndex)
                },200)
            }
        },
        methods: {
            // 1. 初始化操作(数据和界面)
            _initData() {
                this.$nextTick(() => {
                    if (!this.leftScroll) {
                        this.leftScroll = new BScroll('.nav_Warp', {
                            probeType: 3,
                            click: true,
                            scrollY: true,
                            tap: true
                        });
                    } else {
                        this.leftScroll.refresh();//重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
                    }
                });
                // 1.1 这里发送axios请求获取nav data 列表 默认数据
                this.nav_list = ['推荐','新鲜水果','新鲜蔬菜','方便速食','书房用品','厨房用品'];
                this.data_list = [
                    {
                        title:"猜你喜欢",
                        list:['推荐','新鲜水果','新鲜蔬菜','方便速食','调味品','厨房用品','网红菜'],
                    },
                    {
                        title:"我的最爱",
                        list:['我的最爱'],
                    },
                ];
                
            },
            
            // 2. 点击nav,切换高亮,页面滚动到点击的dom位置
            change_nav_active(i){
                if(i != this.nav_active){
                    this.nav_active = i;//改变当前nav高亮
                    let nav_li = this.$refs.nav_li; //获取nav整个li数组
                    let el = nav_li[i]; //需要滚动到el位置
                    this.leftScroll.scrollToElement(el, 500);//开始滚动
                    
                    // 2.1 根据nav点击项 发送axios请求data对应的数据,向子组件传值。
                    this.data_list = [
                        {
                            title:"猜你喜欢"+i,
                            list:['推荐'+i,'新鲜水果'+i,'新鲜蔬菜'+i,'方便速食'+i,'书房用品',],
                        },
                        {
                            title:"我的最爱"+i,
                            list:['推荐'+i,'新鲜水果'+i,'新鲜蔬菜'+i,'方便速食'+i],
                        },
                    ];
                }
            },
        },
    }
</script>

dataWarp组件页面布局

<template>
    <div class="Warp">
        
        <!-- title -->
        <div class="title_Wrap" ref="title_Wrap">
            <ul ref="title_ulContent">
                <li class="item" ref="title_item" v-for="(item,index) in list" :key="index" :class="{ac:title_active == index}" @click="change_title_active(index)">{{item.title}}</li>
            </ul>
        </div>
        
        <!-- data -->
        <div class="data_Warp"> 
            <div class="content">
                <div class="item" v-for="(item,index) in list" :key="index" ref="data_item">
                    <div class="title">{{item.title}}</div>
                    <ul>
                        <li ref="left_li" v-for="(val,i) in item.list" :key="i">{{val}}</li>
                    </ul>
                </div>
            </div>
        </div>
        
    </div>
</template>
<style scoped lang="less">
    .Warp{
        width: 80%;
        .title_Wrap{
            width: 100%;
            white-space: nowrap;
            background: #e8e9e8;
            overflow: hidden;
            ul{
                display: flex;
                li{
                    text-align: center;
                    height: 50px;
                    line-height: 50px;
                    font-size: 12px;
                    margin-right: 15px;
                }
                .ac{
                    color: #3cb963;
                }
            }
        }
        .data_Warp {
            width: 100%;
            height: 85vh;
            overflow: hidden;
            .item{
                .title{
                    padding-left: 10px;
                    height: 50px;
                    line-height: 50px;
                    background: #f4f4f4;
                }
                ul {
                    overflow: scroll;

                    li {
                        padding-left: 10px;
                        border-left: 2px solid #f4f4f4;
                        text-align: left;
                        height: 100px;
                        line-height: 100px;
                        border-bottom: 1px solid #e8e9e8;
                        font-size: 12px;
                    }
                }
            }

        }
    }
</style>
// data title 逻辑部分
<script>
    import BScroll from 'better-scroll'
	export default{
        props:{
            //  接收父组件传过来的data数据
            list: {
                type: Array,
                default: null
            },
        },
		data(){
			return{
                title_active:0, // title 当前高亮,默认索引0
			}
		},
		mounted(){
            // 初始化更新滑动组件
            this.$nextTick(() => {
                this._initTitleScroll(); // 初始化title
                this._initProductScroll(); // 初始化data
            });
            
		},
		methods:{
            // 1. title 滚动初始化
            _initTitleScroll() {
                let contentWrapperWidth = 120;//ul盒子宽度默认120
                let el = this.$refs.title_item;//获取所有导航ul下的li
                for (let i = 0; i < el.length; i++) {
                    contentWrapperWidth += el[i].clientWidth;//导航li宽度相加设置给ul
                }
                // 1.1给ul设置宽度,保证可以横向滚动
                this.$refs.title_ulContent.style.width = contentWrapperWidth + 'px';//给ul设置宽度
                if (!this.titleScroll) {
                    this.titleScroll = new BScroll('.title_Wrap', {
                        probeType: 3,
                        startX: 0,
                        click: true,
                        scrollX: true,
                    });
                } else {
                    this.titleScroll.refresh();//重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
                }
            },
            
            // 2. 商品滚动初始化
            _initProductScroll() {
                this.$nextTick(() => {
                    if (!this.rightScroll) {
                        this.rightScroll = new BScroll('.data_Warp', {
                            probeType: 3,
                            click: true
                        });
                    } else {
                        this.rightScroll.refresh();//重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。
                        // 2.1 进入默认商品列表滚到顶部
                        this.rightScroll.scrollToElement(this.$refs.right_item[0], 10, 0, 0);//滚动到dom位置
                        // 2.2 title默认索引位置0
                        this.title_active = 0;
                    }
                });
            },
            
            // 3. title 切换
            change_title_active(i){
                this.title_active = i;//高亮显示
                // 3.1 商品列表滚动
                let data_item = this.$refs.data_item; //获取data的整个item数组
                let el = data_item[i]; //需要滚动到el位置
                this.rightScroll.scrollToElement(el, 500);//开始滚动
                // 3.2 title 滚动
                let els = this.$refs.title_item[i];//获取所有title的item
                this.titleScroll.scrollToElement(els, 500);//开始滚动
            },

		},
        watch: {
        	//list数据改变需要重新初始化组件
            list() {
                this.$nextTick(() => {
                    this._initTitleScroll();
                    this._initProductScroll();
                });
            }
        },
	}
</script>

better-scroll:参数说明:

probeType
可选值:1、2、3
作用:有时候我们需要知道滚动的位置。
当 probeType 为 1 的时候,会非实时(屏幕滑动超过一定时间后)派发scroll 事件;
当 probeType 为 2 的时候,会在屏幕滑动的过程中实时的派发 scroll 事件;
当 probeType 为 3 的时候,不仅在屏幕滑动的过程中,而且在 momentum 滚动动画运行过程中实时派发 scroll 事件。
如果没有设置该值,其默认值为 0,即不派发 scroll 事件。

click
默认值:false
作用:better-scroll 默认会阻止浏览器的原生 click 事件。当设置为 true,
better-scroll 会派发一个 click 事件,我们会给派发的 event 参数加一个私有属性 _constructed,值为 true。

scrollX
默认值: false
作用:当设置为 true 的时候,可以开启横向滚动。
备注:当设置 eventPassthrough 为 ‘horizontal’ 的时候,该配置无效。

scrollY
默认值:true
作用:当设置为 true 的时候,可以开启纵向滚动。
备注:当设置 eventPassthrough 为 ‘vertical’ 的时候,该配置无效。

tap
默认值:false
作用:因为 better-scroll 会阻止原生的 click 事件,我们可以设置 tap 为 true,它会在区域被点击的时候派发一个 tap 事件,你可以像监听原生事件那样去监听它,如 element.addEventListener(‘tap’, doSomething, false);。
如果 tap 设置为字符串, 那么这个字符串就作为自定义事件名称。如 tap: ‘myCustomTapEvent’。

refresh()
作用:重新计算 better-scroll,当 DOM 结构发生变化的时候务必要调用确保滚动的效果正常。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!