Override component tabbar style

uni, a small program that solves the problem of style modification failure and rewrites the frame tabbar style

Preface

​ In actual business requirements, we often encounter that the current framework cannot meet the UI design requirements, which will involve modifying the frame component style to meet the requirements of the design drawings.

Case

​ This case project is developed based on uni and uses the view framework. According to the design drawing requirements, we need to modify the tabbar style, which is the more common opposite-sex tabbar. (As shown below)

Insert image description here

According to the official documentation of view, this component is composed of several packages. It is worth mentioning here that the tabbar supports at least 2 and up to 5 items. Even a custom tabbar needs to comply with this. (As shown below)

Insert image description here

Here is the code:

html part

<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 part

<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 part

<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>

focus

​ Here are two main points. After we implement style isolation, sometimes it is difficult to modify the style where we need to modify it even when using v-deep (depth selector). Here you need to use one line of code to clear style isolation

options: {
    
    
	styleIsolation: 'shared'
},

It is at the same level as data, life cycle, etc., and can be written in script, so that the styles in the component can be manipulated.

​ Another point is dynamic style. In the js code, I use the menu to organize the required data, and give the center part a field specifically to determine whether dynamic style needs to be turned on. Right now

{
	text: '发布活动',
	name: 'task',
	unIcon: '/static/icon/list.svg',
	onIcon: '/static/icon/list.svg',
	path: '/pages/activity/release',
	isBig: true,
	isLogin: true
},

isBig in

In the html section you can see

<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-bigIt is the class name, and item.isBigit is the switch used to control whether to use the class name style. If it is true, it is used, and vice versa.

Guess you like

Origin blog.csdn.net/Chanyto/article/details/132816448