uniapp 样式相关
文字居中
对于单行文本,使用text-align 和line-height就能使文本居中
.outer_box{
width: 100%;
height: 40px;
}
.text{
text-align: center;
line-height: 40px;
}
另: text-align: center
(不平对齐) 可用于的无素有(一般为行内元素)
- 文本
- span ,a 标签
- input, img 标签
注意:如果需要让以上元素水平居中,text-align需要给以上元素的父元素设置(行内元素给父元素设置)
vertical-align
可用于竖直对齐,同样对以上元素有效,没有实测过
多行文本,可以利用flex的居中
布局中多层居中
在某个父居中,使用绝对定位,可以实现居中,之中再再居中。绝对定位可以无限叠层
实现如下图一个标、样式:
.view-fhr { //最外层布局
display: flex;
width: 100%;
margin-left: 20rpx;
margin-right: 20rpx;
flex-direction: column;
justify-content: center;
.position-pan { //需要控制方位子控件的父容器,貌似也可以没有,晚些试试
position: relative;
width: 100%;
height: 306rpx;
@mixin center { // 居中展示共用变量,采用scss,免得写很多重样式
position: absolute;
width: 300rpx;
height: 264rpx;
left: 0;
right: 0;
top: 4rpx;
margin: auto;
}
.center-image { //中心背景图片
@include center;
}
.text-center { //中心文字,文字在图片的正中心,采用叠加即可实现
@include center;
text-align: center;
line-height: 264rpx;
}
.box-left { // 图片左边的一个展示控件
position: absolute;
left: 80rpx;
bottom: 30rpx;
min-width: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.box-right { // 图片右边展示控件
position: absolute;
right: 80rpx;
bottom: 30rpx;
min-width: 160rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
}
}
css 重用
less
主要用到两点:
- 层级嵌套
- 样式继承(复用)
开始,本来是要找scss 的,不知道怎么百度出了个less,然后也就直接用了。
层级嵌套如上居中部分,这部分内容和SCSS,几乎一致
.container {
display: flex;
width: 100%;
margin-left: 20rpx;
margin-right: 20rpx;
flex-direction: column;
justify-content: center;
.position-pan {
position: relative;
width: 100%;
height: 306rpx;
}
}
样式继承
见如下代码,目的,还是为了少写重复的代码
.text {
font-size: 36rpx;
}
.text_white:extend(.text) {
font-weight: 700;
color: white;
}
.text_white_margin:extend(.text) {
font-weight: 700;
color: white;
margin-left: 15rpx;
}
.text_black:extend(.text) {
margin-left: 15rpx;
color: #3C3C3C;
font-weight: 700;
}
uniapp 中虽然支持less,感觉代码高亮不够,感觉在写文本一样。
sscs
这玩意就同上面了。目前用到的就以下几个特性
- 变量
- mixin 样式重用(类似less的继承)
- 样式嵌套
依次举个例子,主要是为了记录一下(不是搞前端的,这玩意儿不用就忘了):
变量
uniapp 创建的项目里就有定义一套scss 的变量主题
$uni-color-primary: #FF3b79;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
mixin 样式重用
这个在居中里已经有使用过了,这里再列一下
@mixin center { // 居中展示共用变量,采用scss,免得写很多重样式
position: absolute;
width: 300rpx;
height: 264rpx;
left: 0;
right: 0;
top: 4rpx;
margin: auto;
}
.center-image { //中心背景图片
@include center;
}
.text-center { //中心文字,文字在图片的正中心,采用叠加即可实现
@include center;
text-align: center;
line-height: 264rpx;
}
由于变量只能定义单个属性,有的时候,我们样式80% 是重复的,我们就可以将整个样式提取为共用变量。
样式嵌套
.container {
display: flex;
width: 100%;
margin-left: 20rpx;
margin-right: 20rpx;
flex-direction: column;
justify-content: center;
.position-pan {
position: relative;
width: 100%;
height: 306rpx;
}
}
使用样式嵌套,在写样式,不用花太多心思去考虑class 样式的名称
uniapp tabbar 拦截
在项目中使用到uniapp 官方控件tabbar,来做几个基本页面的导航。首页tab中,有一个页面需要做一些数据的录入,在录入过程中,不建议切换选项卡,以免带来各种可以要处理的逻辑。
官方并没有直接给出相关禁用点击的API。只能百度大法。搜索到如下方法,尝试之
uni.addIntercepter
先找到的并不是,这个添加拦截器的方案,而是下面的方案。但感觉先试试官方的API,会不会更优雅且方便,而现实就是不停的打脸。
先来看一下这个方法(不对,js 中应该叫函数)官方的介绍。
**uni.addInterceptor(STRING, OBJECT) **
添加拦截器
STRING 参数说明
需要拦截的api
名称,如:uni.addInterceptor('request', OBJECT)
,将拦截 uni.request()
注意:仅支持异步接口,如:uni.setStorage(OBJECT)
,暂不支持同步接口如:uni.setStorageSync(KEY,DATA)
OBJECT 参数说明
参数名 | 类型 | 必填 | 默认值 | 说明 | 平台差异说明 |
---|---|---|---|---|---|
invoke | Function | 否 | 拦截前触发 | ||
success | Function | 否 | 成功回调拦截 | ||
fail | Function | 否 | 失败回调拦截 | ||
complete | Function | 否 | 完成回调拦截 |
注意:拦截uni.switchTab (opens new window)本身没有问题。但是在微信小程序端点击tabbar
的底层逻辑并不是触发uni.switchTab
。所以误认为拦截无效,此类场景的解决方案是在tabbar
页面的页面生命周期onShow
中处理。
代码中实验的处理逻辑
在onShow() 中添加拦截器,在onHide() 中移除拦截器,如下代码
onShow() {
console.log("index onShow");
// 添加拦截器,并判断是在资料录制中
let that = this;
uni.addInterceptor("switchTab", {
invoke(e) {
if (that.recorded) {
return false;
} else {
return true;
}
}
})
},
onHide() {
// 页面隐藏时,移除拦截器
console.log("index onhide")
uni.removeInterceptor("switchTab")
},
实验的结果:如上文档所说。页面的切换的确是失效了。但tabbar按钮的切换生效了,也就是出现了按钮和页面不对应的情况。planB 失效,只能继续CV PlanA 了
添加一个原生view,遮挡住事件
这个主要参考:
uniapp tabBar 事件屏蔽 点击屏蔽
uniapp App 关键代码如下:
使用 plus.nativeObj.View 创建一个 原生的元素;用于遮罩 tabBar;同样拦截tabBar; 执行自己的方法
let maskView = null
export default {
showMask() {
if (!maskView) {
maskView = new plus.nativeObj.View('maskTabarCar', {
bottom: '0px',
left: '50%',
height: '50px',
width: '25%'
})
// color: 'rgba(26, 84, 159, 1)' 有颜色
// color: 'rgba(255, 255, 255, 0.0)'无色
maskView.drawRect({
color: 'rgba(255, 255, 255, 0.0)'
})
maskView.addEventListener('click', () => {
this.jumpDestination()
}, false)
maskView.show()
} else {
maskView.show()
}
},
hideMask() {
if (maskView) {
maskView.hide()
}
},
jumpDestination() {
console.log('--------------->遮罩被电击了')
uni.navigateTo({
url: '/pages/login/login'
})
// uni.switchTab({
// url: '/main/myHome/myHome'
// })
}
}
原来页面还可以添加原生View,又Get 到了新技能。
屏幕适配,媒体查询
在按照UI蓝湖界面实现完成之后,发现在小屏手机上适配完美。但是在大屏手机上,会有很大一段空白,主要是竖直方向上。
记忆中,记得css 有一个媒体查询适配不同尺寸屏幕的功能。便又开始百度大法
查询到了,别人对uniapp 官方文档的一段复制。
详细内容见官网match-media 的介绍
示例如下:
<template>
<view>
<match-media :min-width="375" :max-width="800" >
<view>当页面最小宽度 375px, 页面宽度最大 800px 时显示</view>
</match-media>
<match-media :min-height="400" :orientation="landscape">
<view>当页面高度不小于 400px 且屏幕方向为横向时展示这里</view>
</match-media>
</view>
</template>
开始在手机上尝试很久,一直没起作用,猜测应该是没有设置上合适的 min-width 和 min-height,
于是通过 uni.getSystemInfoSync(); 获取手机的尺寸。
如下:(有省略部分信息)
{"safeArea": {
"left": 0,
"right": 360,
"top": 0,
"bottom": 522,
"width": 360,
"height": 522
},
"safeAreaInsets": {
"top": 0,
"right": 0,
"bottom": 0,
"left": 0
},
"screenHeight": 640,
"screenWidth": 360,
"statusBarHeight": 24,
"system": "Android 8.0.0",
"ua": "Mozilla/5.0 (Linux; Android 8.0.0; MI 5 Build/OPR1.170623.032; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/68.0.3440.91 Mobile Safari/537.36 uni-app (Immersed/24.0)",
"uniCompileVersion": "3.5.3",
"uniPlatform": "app",
"uniRuntimeVersion": "3.5.3",
"version": "1.9.9.81428",
"windowBottom": 0,
"windowHeight": 522,
"windowTop": 0,
"windowWidth": 360
}
使用 "screenHeight": 640,
"screenWidth": 360,
信息来做判断,发现还是不行。
最终经过多次尝试,发现这里的媒体查询是对比的safeArea 里的 right 和 height