uni,小程序解决样式修改失败的问题,重写框架tabbar样式
前言
在实际的业务要求中,我们往往会遇到当前框架无法满足ui设计要求,这时就会涉及到修改框架组件样式以此达到设计图纸的要求。
案例
该案例项目基于uni开发,采用的是view框架,根据设计图纸要求,我们需要修改tabbar样式,也就是比较常见的异性tabbar。(如下图)
根据view官方文档可知,该组件是由包裹的若干组成的,这里值得一提的是,tabbar支持最少2个,最多5个item项,这点就算是自定义tabbar也是需要遵守的。(如下图)
下面是代码:
html部分
<template>
<view class="">
<u-tabbar :value="active" :safeAreaInsetBottom="true" :placeholder="false" :fixed="fixed" :border="border"
activeColor="#F17F42" inactiveColor="#999999" @change="onChange">
<template v-for="(item, idx) in menus">
<u-tabbar-item :key="idx" :name="item.name" :text="item.text" :class="{ 'tab-big': item.isBig }">
<template #active-icon>
<u-icon :name="item.onIcon" img-mode="aspectFit" size="22" class="icon">
</u-icon>
</template>
<template #inactive-icon>
<u-icon :name="item.unIcon" img-mode="aspectFit" size="22" class="icon">
</u-icon>
</template>
</u-tabbar-item>
</template>
</u-tabbar>
</view>
</template>
JavaScript部分
<script>
export default {
name: 'LayoutTabbar',
options: {
styleIsolation: 'shared'
},
props: {
active: {
type: [String, Number],
require: true,
default: 0
},
fixed: {
type: Boolean,
default: false
},
border: {
type: Boolean,
default: false
}
},
data() {
return {
menus: [{
text: '首页',
name: 'home',
unIcon: '/static/icon/home-1.svg',
onIcon: '/static/icon/home-0.svg',
path: '/pages/index/index',
isLogin: false
},
{
text: '订单',
name: 'order',
unIcon: '/static/icon/order-0.svg',
onIcon: '/static/icon/order-1.svg',
path: '/pages/order/index',
isLogin: false
},
{
text: '发布活动',
name: 'task',
unIcon: '/static/icon/list.svg',
onIcon: '/static/icon/list.svg',
path: '/pages/activity/release',
isBig: true,
isLogin: true
},
{
text: '钱包',
name: 'wallet',
unIcon: '/static/icon/wallet-0.svg',
onIcon: '/static/icon/wallet-1.svg',
path: '/pages/wallet/index',
isLogin: false
},
{
text: '我的',
name: 'my',
unIcon: '/static/icon/my-0.svg',
onIcon: '/static/icon/my-1.svg',
path: '/pages/my/index',
isLogin: false
}
],
}
},
computed: {
usrIsLogin() {
return this.$store.state.account.usrIsLogin
}
},
methods: {
onChange(name) {
const obj = this.$arr2obj(this.menus, 'name')
const item = obj[name]
if(name == 'task' && this.usrIsLogin) {
uni.navigateTo({
url: item.path
})
}else if(name == 'task') {
this.$toast('请先登录再进行操作')
}else {
uni.switchTab({
url: item.path
})
}
}
}
}
</script>
css部分
<style lang="scss">
::v-deep .u-tabbar {
flex: none;
width: 100%;
.u-border-top {
border-color: lighten($black, 95%) !important;
}
.u-tabbar-item {
height: 100%;
.u-tabbar-item__text {
margin-top: 3px;
font-size: 11px;
line-height: 14px;
}
}
.tab-big {
.u-tabbar-item {
height: 100%;
.u-tabbar-item__icon {
height: 24px;
align-items: flex-end;
.u-icon__img {
width: 40px !important;
height: 40px !important;
}
}
.u-tabbar-item__text {
color: #FF7033 !important;
}
}
}
}
</style>
重点
这里主要说两点,我们在做了样式隔离后,有的时候使用了v-deep(深度选择器)也很难去修改到我们需要修改地方的样式。这里就需要使用一行代码来清除样式隔离
options: {
styleIsolation: 'shared'
},
它与data,生命周期等是同级的,写在script内即可,这样就能操作到组件中的样式了。
另外一点是动态样式,在js的代码中,我使用的menus来将所需要用到的数据整理,并且给center部分一个字段专门用来判断是否需要开启动态样式。即
{
text: '发布活动',
name: 'task',
unIcon: '/static/icon/list.svg',
onIcon: '/static/icon/list.svg',
path: '/pages/activity/release',
isBig: true,
isLogin: true
},
中的isBig
在html部分你可以看到
<u-tabbar-item :key="idx" :name="item.name" :text="item.text" :class="{ 'tab-big': item.isBig }">
: ‘/pages/activity/release’,
isBig: true,
isLogin: true
},
中的isBig
在html部分你可以看到
```vue
<u-tabbar-item :key="idx" :name="item.name" :text="item.text" :class="{ 'tab-big': item.isBig }">
tab-big
就是类名,而item.isBig
就是用来控制是否使用该类名样式的开关。为true就是使用,反之。