UNIAPP 宽屏适配 响应式

文章介绍了如何在uniapp中实现响应式布局,以适应不同尺寸的屏幕,包括手机和平板。作者通过监听窗口大小变化并使用Vuex存储数据,以及自定义w-row和w-col组件,实现了类似Bootstrap的栅格系统。由于uniapp不支持媒体查询,作者采用了动态类名的方式来处理不同屏幕尺寸的样式。同时,文章提到了在不同高度屏幕中的适配问题以及为何未选择uniapp的多window方案。
摘要由CSDN通过智能技术生成

UNIAPP 响应式

目的

由于公司老项目只适用于安卓 ios手机端,完全按照 750px 做的适配,现如今公司特殊屏幕需要使用1280*720。
需要进行适配,工期比较端 中间可能还会有各种平板电脑的适配,因此采用的bootstrap 响应式布局,但是uniapp 无法使用媒体查询 故自己实现了响应式布局

思路

使用 uni.onWindowResize(this.onsize) 在app.vue 监听屏幕大小发生变化的是动态响应并把值存储在vuex中方便后续使用

onsize(res) {
    if(res) {
        this.$store.commit("setScreenSize", {
            screenWidth: res.size.windowWidth,
            screenHeight: res.size.windowHeight
        })
        
    } else {
        this.$store.commit("setScreenSize", {
            screenWidth:  uni.getSystemInfoSync().screenWidth,
            screenHeight: uni.getSystemInfoSync().screenHeight
        })
    
    }
},

由于初次进入 app.vue 监听并不会触发 故主动调用一次 根据传入的值来判断是主动调用的还是动态响应的

封装 w-row

<template>
<view class="w-Row" :class="activeClass">
    <slot></slot>
</view>
</template>

<script>
    export default {
        name: 'w-row',
        props: {
            // 两个子item 的间距
            gutter: {
                type: Number,
                default: 0
            }
        },
        data() {
            return {
                screenWidth: 360,
                screenHeight: 360,
            }
        },
        computed: {
            rowStyle() {
                let data = {}
                data.width = this.$store.state.screenWidth + 'px'
                return data
            },
            
            activeClass() {
                // xs	<768px 响应式栅格数或者栅格属性对象
                // sm	≥768px 响应式栅格数或者栅格属性对象
                // md	≥992px 响应式栅格数或者栅格属性对象
                // lg	≥1200px 响应式栅格数或者栅格属性对象
                // xl	≥1920px 响应式栅格数或者栅格属性对象x
                const w = this.$store.state.screenWidth;
                console.log(w)
                if(w < 768) {
                    return "xs"
                } else if(w >= 768 && w < 992) {
                    return "sm"
                } else if(w >= 992 && w < 1200) {
                    return "md"
                } else {
                    return "lg"
                }
            }
            
        },
    
        mounted() {
    
        },
        
        methods: {
        
        }
    }
</script>

<style lang="scss">
    .w-Row {
        width: 100%;
        display: flex;
        flex-wrap: wrap;
        box-sizing: border-box;
    }
    
</style>

w-col 封装

<template>
	<view class="w-Col" :style="colStyle">
		<slot></slot>
	</view>
</template>

<script>
	// xs	<768px 响应式栅格数或者栅格属性对象
	// sm	≥768px 响应式栅格数或者栅格属性对象
	// md	≥992px 响应式栅格数或者栅格属性对象
	// lg	≥1200px 响应式栅格数或者栅格属性对象
	// xl	≥1920px 响应式栅格数或者栅格属性对象
	
	export default {
		props: {
			xs: {
				type: Number
			},
			sm: {
				type: Number
			},
			md: {
				type: Number
			},
			lg: {
				type: Number
			},
			// xl: {
			// 	type: Number
			// }
		},
		data() {
			return {
				screenWidth: 360,
				screenHeight: 360,
				gutter: 0
			}
		},
		computed: {
			colStyle() {
				let data = {}
				const w = this.$store.state.screenWidth;
				let objWidth = 0;
				
				// xs	<768px 响应式栅格数或者栅格属性对象
				// sm	≥768px 响应式栅格数或者栅格属性对象
				// md	≥992px 响应式栅格数或者栅格属性对象
				// lg	≥1200px 响应式栅格数或者栅格属性对象
				// xl	≥1920px 响应式栅格数或者栅格属性对象
				if(w < 768) {
					objWidth = this.xs / 24 * 100
				} else if(w >= 768 && w < 992) {
					objWidth = this.sm / 24 * 100
				} else if(w >= 992 && w < 1200) {
					objWidth = this.md / 24 * 100
				} else {
					objWidth = this.lg / 24 * 100
				}
				data.width = objWidth + '%'
				// #ifdef APP-PLUS
				data.paddingLeft = (this.$parent.gutter || 0 )/ 2 + 'px'
				data.paddingRight = (this.$parent.gutter || 0 )/ 2  + 'px'
				// #endif
				
				// #ifdef H5
				data.paddingLeft = (this.$parent.$parent.gutter || 0 )/ 2 + 'px'
				data.paddingRight = (this.$parent.$parent.gutter || 0 )/ 2  + 'px'
				// #endif
				
				return data
			}
			
			
		},
		
		methods: {
			
		}
	}
</script>

<style lang="scss">
	.w-Col{
		box-sizing: border-box;
	}
</style>

遇到的坑 在 uniapp 中 显示在浏览器时获取父节点gutter时需要往上找两个父节点,在app 中只需要找一个父节点就能找到 父节点的 gutter 代码如下

// #ifdef APP-PLUS
data.paddingLeft = (this.$parent.gutter || 0 )/ 2 + 'px'
data.paddingRight = (this.$parent.gutter || 0 )/ 2  + 'px'
// #endif

// #ifdef H5
data.paddingLeft = (this.$parent.$parent.gutter || 0 )/ 2 + 'px'
data.paddingRight = (this.$parent.$parent.gutter || 0 )/ 2  + 'px'
// #endif

部分屏幕 针对高度也要进行对应的适配 比如登陆,注册时用户协议勾选,在比较低的屏幕中没办法定位在底部,要随着页面进行滚动, 在适当高度的时候需要定位到底部,故我在 vuex 中留了 页面高度进行在不同界面的时候做出更丝滑的操作

为什么没有采用uniapp的多window方案

能快速对app进行横竖屏的适配,因为时间紧凑 能更快的满足公司的业务,比较适合前端响应式布局的理念,使用vuex管理屏幕尺寸 使用动态类名快速解决不同屏幕动态样式的目的

uniapp 推出了多window方案但是对于我们这种屏幕过多页面过于工业复杂的界面不适合使用多window的效果

参考资料

bootstarp

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值