再写数字键盘的时候遇到了一个问题就是我已经通过:calss渲染了不同键位的样式,但是点击键位为了和用户有交互,那么点击时改变颜色就显得比较重要了,但是以及使用了:class了在使用一次改变样式的话就是报错,所以这次改变键位样式且0.15s恢复的这个功能将不使用:class来实现使用:style来实现。
由于代码太长我就写一个简洁版的内容吧主要算法就是这样:
使用uni-app编写一个列表渲染,其中包含三个元素,并实现点击其中一个元素时改变其颜色样式,同时不使用:class
属性。
在uni-app中,可以使用条件判断和动态绑定style
属性来实现此需求。代码如下:
-
在页面的data中定义列表数据和当前选中的元素索引:
data() {
return {
list: [
{ name: '元素1', color: 'black' },
{ name: '元素2', color: 'black' },
{ name: '元素3', color: 'black' }
],
currentIndex: -1
};
},
2、在模板中使用v-for
指令渲染列表,并为每个元素绑定单击事件
<template>
<view>
<view v-for="(item, index) in list" :key="index" @tap="changeColor(index)" :style="getListItemStyle(index)">
{{ item.name }}
</view>
</view>
</template>
3、在方法中定义点击事件处理函数,用于改变选中元素的颜色然后通过时间函数0.15s后返回原来的颜色及currentIndex的值:
methods: {
changeColor(index) {
this.list.forEach((item, idx) => {
if (idx === index) {
item.color = 'red'; // 修改选中元素的颜色
setTimeout(()=>{
item.background = '#ffffff';
},150)
} else {
item.color = 'black'; // 恢复其他元素的颜色
}
});
this.currentIndex = index; // 更新选中元素的索引
},
getListItemStyle(index) {
return {
color: this.list[index].color
};
}
}
4、最后随便设一个样式:
<style>
.view {
font-size: 16px;
padding: 10px;
}
</style>
这样就实现点击盒子后盒子就会改变样式然后过一段时间又会恢复原样,其他盒子也是如此。
最后源代码如下:
<template>
<view>
<view class="Classify">
<view :class="[showCode ? 'Expenditurelv':'Expenditure']" @click="expendituer()">支出</view>
<view :class="[showCodeR ? 'ExpenditureH':'Expenditure']" @click="ExpenditureH()">入账</view>
<view :class="[showCodeL ? 'ExpenditureL': 'Expenditure']" @click="ExpenditureL()">不计入收支</view>
<view class="Expendituretime" :style="timeColor" @click="time()">
<view style="width: auto;height: 60rpx; ">
{{model.type.time}}
</view>
<view
style=" width: auto; height: 60rpx; display: flex; justify-content: center; align-items: center; ">
<image src="/static/image/downward.png" mode="aspectFit"
style="width: 30rpx; height: 30rpx;margin: 7rpx 0 0 4rpx"></image>
</view>
</view>
</view>
<view v-show="value == 0">
<view class="money-input">
<view class="input-container" @click="toggleBox">
<view class="input-wrapper">
<view class="input-iconone">
<image src="/static/Tall-Book-Images/rmb.png" mode="aspectFit"
style="width: 60rpx; height: 60rpx;"></image>
</view>
<view class="input-icon" :class="{active: showBox}"></view>
<!-- <view class="small-box" v-if="showBox"></view> -->
<view class="input-field" @tap="focusInput">{{nums}}</view>
</view>
</view>
</view>
<view class="Type">
<!-- <image src="/static/image/traffic.png" mode=""></image> -->
<view class="Type-box" v-for="(item,index) in box " :key="index">
<view class="inctiveclass" :class="{activeclass: activeIndex === index}" @click="select(index)">
<image :src="item.showimg ? item.imgs : item.img" mode="aspectFit"
style="width: 50rpx; height: 50rpx;"></image>
</view>
<view style="width: 100%; margin-top: 10rpx; height: 40rpx; text-align: center; font-size: 24rpx;">
{{item.name}}
</view>
</view>
</view>
<view class="remark">
<view
style="width: 140rpx; height: auto; display: flex; justify-content: center; align-items: center; ">
添加备注
</view>
</view>
<view class="numbers">
<view style=" display: flex; flex-flow: row wrap; justify-content: flex-start; align-content: flex-start; width: 72%; height: auto;">
<view @click="changeNums(item,index)" :class="item.class" :style="getListitemstyle(index)" v-for="(item,index) in numbers" >
{{item.text}}
</view>
</view>
<view style="width: 28%; height: auto; display: flex; flex-flow: column wrap; ">
<view @click="jianshao()" class="oner" :style="styleos">
<image src="/static/Tall-Book-Images/qc.png" mode="aspectFit"
style="width: 50rpx; height: 50rpx;"></image>
</view>
<view class="onerplus" @click="ok()" :style="stylelv">
确认
</view>
</view>
</view>
</view>
<view v-show="value == 1">
<gold></gold>
</view>
<view v-show="value == 2">
<gambridge></gambridge>
</view>
<u-calendar @close="close" :maxDate="maxDate" :defaultDate="defaultDateMultiple" :show="showtime"
color="#3db273" round="10" mode="single" @confirm="confirm"></u-calendar><!--日期-->
</view>
</template>
<script>
const d = new Date()
const year = d.getFullYear()
let month = d.getMonth() + 1
month = month < 10 ? `0${month}` : month
const date = d.getDate()
export default {
data() {
return {
styleos:{
background:'#ffffff'
},
stylelv:{
background: '#9cd7b7' //确认按钮颜色初始
},
showBox: false,//是否显示‘|’
nums: '',
showtime: false, //日历弹窗
value: 0, //支出、入账、不计入收支改变颜色的初始值
showCode: true, //支出分类
showCodeR: false, //入账分类
showCodeL: false, //不计入收支
activeIndex: 0, //默认选中索引
sumindex:-1,//数字键盘索引
maxDate: `${2023}-${12}-${20 + 10}`, //最大日期
defaultDateMultiple: [`${year}-${month}-${date}`, `${year}-${month}-${date + 1}`,
`${year}-${month}-${date + 2}`
], //默认日期
timeColor: {
background: '#f7f7f7' //记一笔时间点击前颜色
},
model: {
type: {
time: '9月3日'
}
},
boxIndex: '',
box: [{
name: '餐饮',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/cy.png',
imgs: '/static/Tall-Book-Images/cy1.png',
showimg: true
},
{
name: '交通',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/jt.png',
imgs: '/static/Tall-Book-Images/jt1.png',
showimg: false
},
{
name: '服饰',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/yf.png',
imgs: '/static/Tall-Book-Images/yf1.png',
showimg: false
},
{
name: '餐饮',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/gw.png',
imgs: '/static/Tall-Book-Images/gw1.png',
showimg: false
},
{
name: '服务',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/sd.png',
imgs: '/static/Tall-Book-Images/sd1.png',
showimg: false
},
{
name: '教育',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/jy.png',
imgs: '/static/Tall-Book-Images/jy1.png',
showimg: false
},
{
name: '娱乐',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/ht.png',
imgs: '/static/Tall-Book-Images/ht1.png',
showimg: false
},
{
name: '运动',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/lq.png',
imgs: '/static/Tall-Book-Images/lq1.png',
showimg: false
},
{
name: '生活质量',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/fz.png',
imgs: '/static/Tall-Book-Images/fz1.png',
showimg: false
},
{
name: '旅行',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/lx.png',
imgs: '/static/Tall-Book-Images/lx1.png',
showimg: false
},
{
name: '宠物',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/cw.png',
imgs: '/static/Tall-Book-Images/cw1.png',
showimg: false
},
{
name: '医疗',
avtive: 'activeclass',
inctive: 'inctiveclass',
img: '/static/Tall-Book-Images/yl.png',
imgs: '/static/Tall-Book-Images/yl1.png',
showimg: false
}
],
numbers: [
{
text: '1',
class: 'oner',
background: '#ffffff'
},
{
text: '2',
class: 'oner',
background: '#ffffff'
},
{
text: '3',
class: 'oner',
background: '#ffffff'
},
{
text: '4',
class: 'oner',
background: '#ffffff'
},
{
text: '5',
class: 'oner',
background: '#ffffff'
},
{
text: '6',
class: 'oner',
background: '#ffffff'
},
{
text: '7',
class: 'oner',
background: '#ffffff'
},
{
text: '8',
class: 'oner',
background: '#ffffff'
},
{
text: '9',
class: 'oner',
background: '#ffffff'
},
{
text: '0',
class: 'big',
background: '#ffffff'
},
{
text: '.',
class: 'oner',
background: '#ffffff'
},
]
}
},
methods: {
ok() {
let obj = {
nums: this.nums,
image: this.box[this.boxIndex || 0]
}
this.stylelv.background='#3bab6f'
setTimeout(()=>{
this.stylelv.background='#9cd7b7'
},150)
uni.setStorageSync('aaa', obj)
uni.getStorageSync('aaa')
console.log(uni.getStorageSync('aaa'))
},
jianshao() {
this.styleos.background='#f7f7f7'
setTimeout(()=>{
this.styleos.background='#ffffff'
},150)
if (this.nums) {
this.nums = this.nums.substring(0, this.nums.length - 1)
}
},
changeNums(item,index) {
this.numbers.forEach((item, idx)=>{
if(idx === index){
item.background = '#f7f7f7';
setTimeout(()=>{
item.background = '#ffffff';
},150)
}
});
this.sumindex = index
console.log('this.sumindex', this.sumindex)
if (item.text == '.') {
console.log(this.nums.indexOf(".") != -1)
if (this.nums.indexOf(".") != -1) {
return false
}
}
if (this.nums.split('.') && this.nums.split('.')[1]) {
if (this.nums.split('.')[1].length >= 2) {
return false
}
}
this.nums = this.nums + item.text
},
getListitemstyle(index){
return{
background: this.numbers[index].background
};
},
close() {
this[`show${this.showtime}`] = false
},
confirm(e) {
console.log(e);
this.showtime = false
},
select(index) {
console.log(index)
this.box.forEach((item, i)=>{
if(i === index)
{
item.showimg = true;
} else{
item.showimg = false;
}
});
this.activeIndex = index; //选择
},
time() {
this.timeColor.background = '#dedede' //点击中记一笔时间的颜色
setTimeout(() => {
this.timeColor.background = '#f7f7f7' //点击后记一笔时间的颜色
}, 200)
this.showtime = true
},
expendituer() { //点击支出
this.value = 0,
console.log(this.value);
this.showCode = true;
this.showCodeL = false;
this.showCodeR = false;
},
ExpenditureH() { //点击入账
this.value = 1,
console.log(this.value);
this.showCode = false;
this.showCodeR = true;
this.showCodeL = false;
},
ExpenditureL() { //点击不计入收支
this.value = 2,
console.log(this.value);
this.showCode = false;
this.showCodeR = false;
this.showCodeL = true;
},
focusInput() {
// 点击输入框时触发的方法
// 可以在此方法中处理获取焦点、跳转到输入界面等逻辑
},
toggleBox() {
this.showBox = true //点击后输入框出现“|”每隔一段时间闪动
}
}
}
</script>
<style lang="scss" scoped>
.Classify {
width: 100%;
display: flex;
height: 120rpx;
margin-top: 10rpx;
padding-left: 30rpx;
align-items: center;
margin-bottom: -12rpx;
justify-self: flex-start;
}
.Expenditure {
width: auto;
height: 60rpx;
color: #c7c7c7;
font-size: 30rpx;
text-align: center;
line-height: 60rpx;
margin-left: 20rpx;
border-radius: 10rpx;
background-color: #f7f7f7;
padding: 0rpx 20rpx 0rpx 20rpx;
}
.Expendituretime {
width: auto;
color: black;
display: flex;
height: 60rpx;
font-size: 30rpx;
line-height: 60rpx;
margin-left: 20rpx;
margin-left: 80rpx;
align-items: center;
border-radius: 10rpx;
background-color: #f7f7f7;
justify-content: space-evenly;
padding: 0rpx 15rpx 0rpx 20rpx;
}
.Expenditurelv {
width: auto;
height: 60rpx;
color: #3eb575;
font-size: 30rpx;
text-align: center;
line-height: 60rpx;
margin-left: 20rpx;
border-radius: 10rpx;
background-color: #ebf7f1;
padding: 0rpx 20rpx 0rpx 20rpx;
}
.ExpenditureH {
width: auto;
height: 60rpx;
color: #f5c53a;
font-size: 30rpx;
text-align: center;
line-height: 60rpx;
margin-left: 20rpx;
border-radius: 10rpx;
background-color: #fdf8eb;
padding: 0rpx 20rpx 0rpx 20rpx;
}
.ExpenditureL {
width: auto;
height: 60rpx;
color: #8c8bc3;
font-size: 30rpx;
text-align: center;
line-height: 60rpx;
margin-left: 20rpx;
border-radius: 10rpx;
background-color: #f1f3f6;
padding: 0rpx 20rpx 0rpx 20rpx;
}
.money-input {
width: 100%;
height: 150rpx;
padding: 0 40rpx 0 40rpx;
}
.Type {
width: 100%;
height: auto;
display: flex;
margin-top: 20rpx;
align-items: center;
flex-flow: row wrap;
justify-content: flex-start;
}
.Type-box {
display: flex;
width: 120rpx;
height: 140rpx;
align-items: center;
flex-flow: column wrap;
justify-content: center;
margin: 0 0rpx 10rpx 5rpx;
}
.inctiveclass {
width: 80rpx;
display: flex;
height: 80rpx;
font-size: 22rpx;
border-radius: 50%;
align-items: center;
justify-content: center;
background-color: #f7f7f7;
}
.activeclass {
width: 80rpx;
display: flex;
height: 80rpx;
border-radius: 50%;
align-items: center;
justify-content: center;
background-color: #3eb575;
}
.numbers {
width: 100%;
display: flex;
height: 480rpx;
margin-top: 10rpx;
background-color: #fafafa;
justify-content: flex-start;
}
.remark {
width: 100%;
color: #50648a;
height: 100rpx;
font-size: 32rpx;
padding: 20rpx 0 0 30rpx;
}
.oner {
display: flex;
width: 165rpx;
height: 100rpx;
font-size: 34rpx;
font-weight: bold;
align-items: center;
border-radius: 10rpx;
justify-content: center;
margin: 15rpx auto 5rpx;
background-color: #ffffff;
}
.onerplus {
display: flex;
width: 165rpx;
color: #ffffff;
height: 338rpx;
font-size: 34rpx;
font-weight: bold;
align-items: center;
border-radius: 10rpx;
justify-content: center;
margin: 15rpx auto 5rpx;
background-color: #9cd7b7;
}
.big {
display: flex;
width: 342rpx;
height: 100rpx;
font-size: 34rpx;
font-weight: bold;
align-items: center;
border-radius: 10rpx;
margin: 15rpx auto 5rpx;
justify-content: center;
background-color: #ffffff;
}
.input-container {
position: relative;
width: 100%;
height: 156rpx;
}
.input-wrapper {
position: relative;
width: 100%;
height: 100%;
border-bottom: 1px solid #ccc;
padding: 0 20rpx;
box-sizing: border-box;
}
.input-icon {
position: absolute;
top: 50%;
left: 84rpx;
height: 106rpx;
width: 1rpx;
transform: translateY(-50%);
background-color: #cbcbcb;
display: none;
}
.active {
display: block;
animation: blink 1s infinite; //点击后|出现
}
@keyframes blink {
0% { opacity: 0; }
50% { opacity: 1; }
100% { opacity: 0; }
}
.input-iconone {
position: absolute;
top: 50%;
left: 2rpx;
transform: translateY(-50%);
color: #666;
}
.input-field {
width: 100%;
height: 100%;
line-height: 156rpx;
padding-left: 80rpx;
font-size: 80rpx;
color: #333;
}
</style>
运行效果如下:
主要是实现不使用:class的情况下也能实现盒子样式的改变