使用uniapp在列表渲染的数字键盘中给每个键位写入点击事件点击改变颜色0.15s后有还原成原来的颜色且不使用:class

36 篇文章 0 订阅
36 篇文章 1 订阅

再写数字键盘的时候遇到了一个问题就是我已经通过:calss渲染了不同键位的样式,但是点击键位为了和用户有交互,那么点击时改变颜色就显得比较重要了,但是以及使用了:class了在使用一次改变样式的话就是报错,所以这次改变键位样式且0.15s恢复的这个功能将不使用:class来实现使用:style来实现。

由于代码太长我就写一个简洁版的内容吧主要算法就是这样:

使用uni-app编写一个列表渲染,其中包含三个元素,并实现点击其中一个元素时改变其颜色样式,同时不使用:class属性。

在uni-app中,可以使用条件判断和动态绑定style属性来实现此需求。代码如下:

  1. 在页面的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的情况下也能实现盒子样式的改变

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值