小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
uniapp 打造自用组件库 (五) 九宫格按钮组
前言
本文将带领读者使用uniapp封装一些常用组件,方便日后开发时重复使用,当然文中封装的组件不可能适配所有应用场景,但是我希望读者可以跟着我的思路实现出来,然后可以在此基础上优化改进为自己合适的,本人一个前端小菜鸡,希望大佬们可以不吝赐教,也是对我的技术水平的提升
九宫格按钮组
需求
在平时的开发中,经常会用到按钮组的功能,例如三行三列的九宫格,又或者商城等应用的按钮组,所以就封装了一个按钮组的组件,只需要传入名称,icon,就可以迅速生成按钮组,同时可以快速调整每行按钮个数,有效应对客户的需求变更
效果展示
应用效果
应用代码
<view>
<Ybtns :lineNum='lineNum' :data='btnList' @change='change'></Ybtns>
</view>
export default {
data() {
return {
lineNum:4,//每行按钮个数
btnList:[ //按钮信息
{
icon:'../../static/icon.png',//按钮图标 必填
name:'按钮1', //按钮标题 可不填
id:1, //其他任意自定义字段
},
{
icon:'../../static/icon.png',
name:'按钮2',
},
{
icon:'../../static/icon.png',
name:'按钮3',
},
{
icon:'../../static/icon.png',
name:'按钮4',
},
{
icon:'../../static/icon.png',
name:'按钮5',
},
{
icon:'../../static/icon.png',
name:'按钮6',
},
{
icon:'../../static/icon.png',
name:'按钮7',
},
{
icon:'../../static/icon.png',
name:'按钮8',
},
{
icon:'../../static/icon.png',
name:'按钮9',
}
],
}
},
methods: {
change(item){
uni.showToast({
title:`你点击了${item.name}`
})
},
}
}
实现思路
利用grid布局实现,便于可以快速切换每行个数,同时点击后可以触发事件,返回被点击的项
完整实现代码
/**
* change事件 返回被点击项的全部数据
*/
<template>
<view class="list" :style="{gridTemplateColumns: `repeat(${lineNum},1fr)`}" >
<view class="item" v-for="icon_item in data">
<view class="item_box" :style="{opacity:showimg?'1':'0'}" @tap="tap_item(icon_item)">
<image :src="icon_item.icon" mode="widthFix"></image>
<view v-if="icon_item.name">{{icon_item.name}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
props: {
/**
* 每行显示几个按钮
*/
lineNum: {
type: Number,
default: 4
},
/**
* 按钮数组
* [{icon:'按钮图片地址',name:'按钮标题文字/可不写'}]
*/
data: {
type: Array,
default: []
}
},
data() {
return {
showimg: false,
};
},
created() {
// 解决图片不设置高度导致的页面跳动
setTimeout(() => {
this.showimg = true
}, 800)
},
methods: {
tap_item(item) {
this.$emit('change',item)
}
}
}
</script>
<style lang="scss">
.list {
display: grid;
.item {
.item_box {
display: flex;
flex-direction: column;
padding: 30rpx;
align-items: center;
transition: 0.2s;
image {
width: 100%;
transition: 0.3s;
&:active {
transform:scale(0.9);
opacity: 0.7;
}
}
view {
color: #2B2F33;
font-size: 14px;
text-align: center;
margin-top: 10rpx;
white-space: nowrap
}
}
}
}
</style>