uniapp 菜单栏左右滑动自动居中

<template>
    <view class="center-cut-menu">
        <scroll-view scroll-x="true" scroll-with-animation="true" class="scroll-view" :scroll-left="scrollLeft">
            <view class="scroll-item" v-for="(item, index) in list" :key="index" @click="changeMenu(index)">
                <text class="item-text" :class="curIndex == index? 'active' : ''">{{item.name}}</text>
            </view>
        </scroll-view>
    </view>
</template>
 
<script>
    export default {
        data() {
            return {
                list: [{
                        id: 1,
                        name: '星期一'
                    },
                    {
                        id: 2,
                        name: '星期二'
                    },
                    {
                        id: 3,
                        name: '星期三'
                    },
                    {
                        id: 4,
                        name: '星期四'
                    },
                    {
                        id: 5,
                        name: '星期五'
                    },
                    {
                        id: 6,
                        name: '星期六'
                    },
                    {
                        id: 7,
                        name: '星期七'
                    },
                    {
                        id: 8,
                        name: '星期八'
                    },
                    {
                        id: 9,
                        name: '星期九'
                    },
                    {
                        id: 10,
                        name: '星期十'
                    }
                ],
                contentScrollW: 0, // 导航区宽度
                curIndex: 0, // 当前选中
                scrollLeft: 0, // 横向滚动条位置
            }
        },
        mounted() {
            // 获取标题区域宽度,和每个子元素节点的宽度
            this.getScrollW()
        },
        methods: {
            // 获取标题区域宽度,和每个子元素节点的宽度以及元素距离左边栏的距离
            getScrollW() {
                let query = uni.createSelectorQuery().in(this);
                query.select('.scroll-view').boundingClientRect(data => {
                    // 拿到 scroll-view 组件宽度
                    this.contentScrollW = data.width
                }).exec();
 
                query.selectAll('.scroll-item').boundingClientRect(data => {
                    let dataLen = data.length;
                    for (let i = 0; i < dataLen; i++) {
                        //  scroll-view 子元素组件距离左边栏的距离
                        this.list[i].left = data[i].left;
                        //  scroll-view 子元素组件宽度
                        this.list[i].width = data[i].width
                        console.log(this.list[i].left,"left")
                        console.log(this.list[i].width,"width")
                    }
                }).exec()
            },
 
            // 选择标题
            changeMenu(index) {
                this.curIndex = index;
 
                // 效果一(当前点击子元素靠左展示)  局限性:子元素宽度相同
                // this.scrollLeft = index * this.list[index].width
 
                // 效果一(当前点击子元素靠左展示)  子元素宽度不相同也可实现
                // this.scrollLeft = 0;
                // for (let i = 0; i < index; i++) {
                //     this.scrollLeft += this.list[i].width
                // };
 
 
                // 效果二(当前点击子元素靠左留一展示)  局限性:子元素宽度相同
                // this.scrollLeft = (index - 1)  * this.list[index].width
 
                // 效果二(当前点击子元素靠左留一展示)  子元素宽度不相同也可实现
                // this.scrollLeft = 0;
                // for (let i = 0; i < index - 1; i++) {
                //     this.scrollLeft += this.list[i].width
                // };
 
 
                // 效果三(当前点击子元素居中展示)  不受子元素宽度影响
                this.scrollLeft = this.list[index].left - this.contentScrollW / 2 + this.list[index].width / 2;
 
            }
        }
    }
</script>
 
<style lang="scss">
    .center-cut-menu {
        width: 100%;
        height: 100rpx;
        box-sizing: border-box;
 
        .scroll-view {
            height: 100rpx;
            white-space: nowrap;
 
            .scroll-item {
                height: 100rpx;
                padding: 0 20rpx;
                display: inline-block;
                text-align: center;
 
                .item-text {
                    font-size: 30rpx;
                    line-height: 100rpx;
 
                    &.active {
                        color: #1468FF;
                    }
                }
            }
        }
    }
</style>

### UniApp 平板适配方法和最佳实践 #### 1. 自动适配机制 Uniapp 内置了强大的多平台适配功能,能够根据不同的设备类型自动调整应用的样式和布局。这意味着开发者不需要为每种设备单独编写大量适配代码。当检测到平板设备时,框架会自动处理屏幕尺寸、分辨率等因素,确保界面元素的比例和谐统一[^2]。 #### 2. 使用 Flexbox 和 Grid 布局 为了进一步优化平板上的用户体验,建议采用响应式的 CSS 技术如 Flexbox 或者 Grid 来构建页面结构。这些技术可以更灵活地控制组件之间的排列方式以及它们相对于容器边界的离,从而更好地利用大屏空间并保持良好的交互体验。 ```css .container { display: flex; justify-content: space-between; /* 水平分布 */ align-items: center; /* 垂直居中 */ } .item { flex-grow: 1; } ``` #### 3. 定义媒体查询规则 针对特定宽度范围内的平板设备设置专门的设计方案也是一种常见做法。通过定义媒体查询条件来改变某些属性值(比如字体大小、间等),可以让应用程序在各种类型的屏幕上都呈现出最优的效果。 ```css @media only screen and (min-width: 768px) { .header h1 { font-size: 2em !important; } nav ul li a { padding-left: 20px !important; padding-right: 20px !important; } } ``` #### 4. 考虑触摸操作特性 由于平板通常配备触控屏而非传统鼠标指针输入法,因此还需要特别注意手势识别和支持手指点击事件等功能模块的设计。例如,在菜单栏或其他可滑动区域增加相应的监听器以便于用户轻松导航浏览整个网站或APP内容。 ```javascript // 监听 touchstart/touchend 事件实现简单的翻页效果 document.addEventListener('touchstart', function(event){ startX = event.touches[0].clientX; }, false); document.addEventListener('touchend', function(event){ endX = event.changedTouches[0].clientX; if(startX - endX > 50){ // 向左划过一定离触发下一页逻辑 nextPage(); }else if(endX - startX > 50){// 反之则返回上一页 prevPage(); } }); ``` #### 5. 测试与调试工具的应用 最后但同样重要的是要充分利用好官方提供的模拟器和其他第三方插件来进行充分测试。这样可以帮助发现潜在问题所在之处进而及时修正完善最终产品版本前的质量把控工作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值