7.从0做一个vue键盘组件

文章目录

  • 1. 从0做一个键盘组件
    • 1.1. 最终效果
    • 1.2. 分析
    • 1.3. 实现
    • 1.4. 如何引用

1. 从0做一个键盘组件

首先是why的问题:为什么需要做键盘组件?

我们目前可知的场景:

  1. 在新增账单的时候,需要用到键盘
  2. 在比如从账单列表页,进行行项目编辑某笔账单的时候,也需要用到键盘

如果都是每个vue页面自己写键盘的话,就比较尴尬了,回头需要优化的时候,就要多处维护。

所以,我们需要定义一个键盘组件。

1.1. 最终效果

或者是编辑的时候:

1.2. 分析

  1. 主要是显示:item_name账单类目名称、bill_money账单金额、账单日期选择、提交账单、删除账单
  2. 如果是新增账单,就不显示”删除账单“按钮;如果是编辑账单,展示”删除账单“按钮。

1.3. 实现

整体的键盘样式都比较简单,可以直接通过布局来绘制。

直接上代码:

<template>
	<view class="keyboardbox">
		<view style="display: flex; font-size: 50rpx; justify-content: space-between; padding: 20rpx 20rpx;">
			<view style="font-size: 40rpx;">{{item_name}}</view>
			<view color = '#bbb' >{{bill_money}}</view>
		</view>
		<u-input
		    placeholder="备注: 点击填写备注"
		    :border="true"
			v-model="bill_desc"
		    clearable
		></u-input>
		<view class="numkeyboard">
			<view class="num-area">
				<view class="row" v-for="(item,index) in numKeybordList" :key="index">
					<view class="item"
						v-for="(ite,idx) in item" hover-class="active" :hover-start-time="0"
						:hover-stay-time="5" :key="idx" @tap="input(ite)">{{ite}}</view>
				</view>
			</view>
			<view class="btn-area">
				<view :class="['item','dateChoose']" hover-class="active" :hover-start-time="0" :hover-stay-time="5"
					@tap="dateVal">
						<view class="uni-input">{{choosedDateShow}}</view>
				</view>
				<view :class="['item','del']" hover-class="active" :hover-start-time="0" :hover-stay-time="5"
					@tap="deleteVal">
					<u-icon name="arrow-leftward"></u-icon>
				</view>
				<view class="confirem item" hover-class="active" :hover-start-time="0" :hover-stay-time="5"
					@tap="submit">
					完成
				</view>
				<view v-if="add_or_update=='编辑账单'" class="deletebill item" hover-class="active" :hover-start-time="0" :hover-stay-time="5"
					@tap="deleteBill">
					删除账单
				</view>
			</view>
		</view>
	</view>
	
	<u-picker mode="time"
		:default-time="date_picker_date" 
		v-model="date_picker_show" 
		:params="date_picker_params"
		@confirm="date_pick_ok"
		>
	</u-picker>
	
	<!-- <u-modal v-model="showDeleteBillModal" :content="content" negative-top=500></u-modal> -->
</template>



<script setup>
	import {
		ref, defineProps, defineEmits, watch, defineModel, computed
	} from 'vue';
	import {onLoad,onUnload,onReachBottom,onShareAppMessage,onShareTimeline} from "@dcloudio/uni-app"
	
	
	
	onLoad((e)=>{
		
	});
	
	const add_or_update = defineModel("add_or_update", { type: String, default: '' });
	const bill_id = defineModel("bill_id", { type: String, default: '' });
	const item_name = defineModel("item_name", { type: String, default: '' });
	const bill_money = defineModel("bill_money", { type: String, default: '' });
	const bill_desc = defineModel("bill_desc", { type: String, default: '' });
	const date_picker_date = defineModel("date_picker_date", {type: String, default: ''})
	
	console.log(add_or_update.value);
	console.log(date_picker_date.value);
	console.log(bill_id.value);
		
	const numKeybordList = ref([  // 键盘数值
		[1, 2, 3],
		[4, 5, 6],
		[7, 8, 9],
		[0, '.']
	]);
	
	// 默认不显示时间选择组件。在点击了“今天”之后,可以进行选择其他日期
	const date_picker_show = ref(false);
	// 选择时间时候的时间选择组件,仅展示年月日
	const date_picker_params = ref({
		year: true,
		month: true,
		day: true,
		hour: false,
		minute: false,
		second: false
	});
	
	// 监听contentId
	// watch(()=>props.item_name,(newValue, oldValue)=>{
	// 	console.log(newValue);
	//    item_name.value = newValue
	// },{ deep: true, immediate:true})
	
	
	/**
	 * 按键
	 * @param {Object}
	 */
	// const clickInfo = () => {
	const input = (val) => {
	// input(val) {
		let money = bill_money.value;
		if (money.length >= 10) {
			uni.showToast({
				title: '金额过大',
				icon: 'error'
			})
			return;
		}
		let arr = money.split('.');
		if (money == '0.00' && val != null) {
			money = val.toString();
		} else {
			let arr = money.split('.');
			if (val == '.' && arr.length > 1) {
		
			} else if (arr.length <= 1 || (arr.length > 1 && arr[1].length <= 1)) {
				if (money == '0' && val != '.') {
					money = val.toString();
				} else if (money != '0' || val != '0')
					money += val;
			}
		}
		bill_money.value = money;
		
	};
	/**
	 * 删除
	 */
	const deleteVal = () => {
	// deleteVal() {
		let money = bill_money.value; 
		console.log(money.length);
		if (money != '0.00' && money.length > 0)
			money = money.substring(0, money.length - 1)
		if (money.length <= 0)
			money = '0.00';
			
		bill_money.value = money;
	};
	const date_pick_ok = (callback_data) => {
	// date_pick_ok(callback_data) {
		date_picker_date.value = callback_data.year + '-' + callback_data.month + '-'  + callback_data.day;
		console.log('选择了:' + date_picker_date.value);
	};
	
	const dateVal = () => {
		date_picker_show.value = true;
	};
	
	const emit = defineEmits(['submit', 'deleteBill']);
	
	const submit = () => {
		emit(
		'submit',
		{
			bill_money: bill_money.value,
			bill_desc: bill_desc.value,
			date_picker_date: date_picker_date.value
		},
		(res)=>{
			//回调函数的方法体.处理自己的业务.
			console.log("获取到父组件执行结果的回调");
			console.log(res);
		 }
		);
	};
	
	const deleteBill = () => {
		
		uni.showModal({
			title: '提示',
			content: '确定要删除此账单吗?',
			success: function (res) {
				if (res.confirm) {
					console.log('用户点击确定');
					emit(
					'deleteBill',
					{
						bill_id: bill_id.value
					},
					(res)=>{
						//回调函数的方法体.处理自己的业务.
						console.log("获取到父组件执行结果的回调");
						console.log(res);
					 }
					);
				} else if (res.cancel) {
					console.log('用户点击取消');
				}
			}
		});
		
		
		
	};
	
	const getTodayDateTime = () => {
		var date = new Date();
		var Y = date.getFullYear() + '-';
		var M = (date.getMonth()+1 < 10 ? '0'+(date.getMonth()+1):date.getMonth()+1) + '-';
		var D = (date.getDate()< 10 ? '0'+date.getDate():date.getDate())+ ' ';
		var h = (date.getHours() < 10 ? '0'+date.getHours():date.getHours())+ ':';
		var m = (date.getMinutes() < 10 ? '0'+date.getMinutes():date.getMinutes()) + ':';
		var s = date.getSeconds() < 10 ? '0'+date.getSeconds():date.getSeconds();
		return Y+M+D+h+m+s;
	};
	
	// 一个计算属性 ref
	const choosedDateShow = computed(() => {
		if (date_picker_date.value == getTodayDateTime().substring(0, 10)) {
			return '今天';
		}
		else {
			return date_picker_date.value;
		}
	})
	
</script>

<style lang="scss">
.keyboardbox {
		width: 100%;
		position: absolute;
		left: 0;
		bottom: 0;
		background-color: #FFFFFF;
	
		.numkeyboard {
			height: 432rpx;
			display: flex;
			background-color: #ebedf0;
	
			.btn-area {
				width: 180rpx;
				height: 100%;
				display: flex;
				flex-direction: column;
	
				.item {
					width: 100%;
					display: flex;
					justify-content: center;
					align-items: center;
					flex-grow: 1;
				}
	
				.del {
					background-color: #ebedf0;
					color: #333;
	
					&.active {
						background-color: #f1f3f5;
					}
				}
	
				.confirem {
					background-color: #4fae70;
					color: #FFFFFF;
	
					&.active {
						background-color: #4fae70;
					}
				}
				
				.deletebill {
					background-color: #e94d26;
					color: #333;
				}
				
				.dateChoose {
					background-color: #f9db56;
					color: #2d2d2d;
						
					&.active {
						background-color: #f9db56;
					}
				}
			}
	
			.num-area {
				flex-grow: 1;
				display: flex;
				flex-wrap: wrap;
	
				.row {
					width: 100%;
					height: 25%;
					display: flex;
					margin-top: 1px;
	
					.item {
						flex-grow: 1;
						height: 100%;
						display: flex;
						justify-content: center;
						align-items: center;
						background-color: #FFFFFF;
						border-right: 1px solid #ebedf0;
						width: 33.33%;
	
						&.active {
							background-color: #ebedf0;
						}
	
						&.z {
							flex-grow: 2;
							width: 66.66%;
						}
	
						&.disabled {
							background: #FFFFFF;
							color: #B9B9B9;
						}
					}
				}
	
			}
		}
	}
</style>

1.4. 如何引用

我们选择在父组件里面,通过一个u-popup来包裹此键盘组件,并在显示之前,把要传递进去显示的数据用v-model进行绑定:

  • 如果是添加账单的场景:父组件传值给子组件;子组件要调用父组件的submit方法;子组件要知道父组件submit方法的执行结果。
<u-popup v-model="popup_show" mode="bottom" border-radius="14" height="600rpx">
		<keyboard-info 
		:item_name="item_name" 
		:bill_money="bill_money" 
		:bill_desc="bill_desc"
		:date_picker_date="date_picker_date"
		:add_or_update="'添加账单'"
		@submit="submit"
		>
		</keyboard-info>
	</u-popup>
// 上面的item_name、bill_money、bill_desc、date_picker_date要自行处理赋值。
selectItem(index) {
  this.bill_money = '0.00';// 点击弹出的金额默认还原为0
  this.bill_desc = '';// 理由同上
  this.select_item = index;
  this.popup_show = true;  // 展示u-popup,也就能展示出来键盘子组件了。
  if (this.current_type == 0) {
    this.item_name = this.expenditure_list[index-1].text
    this.item_img_path = this.expenditure_list[index-1].icon
    this.item_id = this.expenditure_list[index-1].id
  }
  else {
    this.item_name = this.income_list[index-1].text
    this.item_img_path = this.income_list[index-1].icon
    this.item_id = thisincome_list[index-1].id
  }
},
// submit方法,主要是用来给键盘组件在点击键盘的”提交“按钮时,将键盘组件录入的数据回传到父组件的submit方法中
// 这里要再说一下callback参数,其实是键盘组件为了获取到父组件执行了submit方法之后的返回值,以便在成功执行操作之后,将键盘隐藏或引导页面跳转
submit(data, callback) {
  console.log('收到键盘子组件触发submit方法');
  console.log(data);
  if (this.direction == '支出') {
    data.bill_money = -data.bill_money;
  }
  // console.log('bill_add.vue的 submit() 方法被调用');
  let bill_detail = {
    bill_id: this.direction + this.getTodayDateTime(),
    direction: this.direction,
    year: parseInt(this.date_picker_date.substring(0, 4)),
    month: parseInt(this.date_picker_date.substring(5,7)),
    day: parseInt(this.date_picker_date.substring(8,10)),
    week: this.getWeek(this.date_picker_date),
    item_name: this.item_name,
    item_img_path: this.item_img_path,
    item_id: parseInt(this.item_id),
    add_time: this.getTodayDateTime(),
    update_time: this.getTodayDateTime(),
    // 下面3个,是从键盘组件回调来的值
    bill_desc: data.bill_desc,
    bill_date: data.date_picker_date,
    bill_money: parseFloat(data.bill_money)
  }
  console.log(bill_detail);
  callback(true);
},
  • 如果是编辑账单的场景

    <u-popup v-model="popup_show" mode="bottom" border-radius="14" height="600rpx">
    			<keyboard-info 
    			:item_name="item_name" 
    			:bill_money="bill_money" 
    			:bill_desc="bill_desc"
    			:date_picker_date="date_picker_date"
    			:add_or_update="'编辑账单'"
    			:bill_id="bill_id"
    			@submit="submit"
    			@deleteBill="deleteBill"
    			>
    			</keyboard-info>
    		</u-popup>
    

    跟之前的分析是类似的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/636865.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于Kafka的日志采集

目录 前言 架构图 资源列表 基础环境 关闭防护墙 关闭内核安全机制 修改主机名 添加hosts映射 一、部署elasticsearch 修改limit限制 部署elasticsearch 修改配置文件 启动 二、部署filebeat 部署filebeat 添加配置文件 启动 三、部署kibana 部署kibana 修…

实现底部表情评价,聚焦改变颜色,点击坏评价自动变成好评价

如下&#xff0c;非常简单的一个小玩意。 废话不多说直接上代码&#xff1a; <!--* 轮子的作者: 轮子哥* Date: 2024-05-22 10:43:45* LastEditTime: 2024-05-24 10:28:53 --> <!DOCTYPE html> <html lang"en"><head><meta charset"…

51-指针_野指针,指针运算

51-1 野指针 51-1-1 什么是野指针 概念&#xff1a;野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的) 没有初始化 int main() {int* p;//p没有初始化&#xff0c;就意味着没有明确的指向//一个局部变量不初始化的话&#xff0c;放的是随机…

clickhouse 中的数组(array)和元组(Tuple)—— clickhouse 基础篇(二)

文章目录 数组判断是否为空计算数组长度获取数组元素判断某个元素是否存在数组切片数组元素展开数组元素去重删除连续重复元素连接多个数组数组倒序数组拍平数组元素映射数组元素过滤数组聚合分析计算数组交集计算数组并集计算数组差集SQL 子查询进行集合操作 元组创建元组获取…

八国多语言微盘微交易所系统源码 单控点控 K线完好

安装环境linux NGMySQL5.6PHP7.2&#xff08;函数全删&#xff09;pm2管理器&#xff08;node版本选择v12.20.0&#xff09; config/ database.php 修改数据库链接 设置运行目录 public 伪静态thinkphp

最有效的企业数据防泄漏手段 | 数据泄漏防护系统推荐

随意信息安全意识不断提高&#xff0c;企业纷纷寻求高效的数据防泄漏手段。在众多解决方案中&#xff0c;这五款软件各具特色&#xff0c;但它们的共同目标都是确保企业数据的安全性和保密性。 接下来&#xff0c;我们将逐一介绍这五款软件的特点和优势。 1、Ping 32 Ping32…

C中十进制转十六进制示例

uint8_t QR_code_RxBfr[255]{0}; uint8_t TouchCode[100];memcpy (&Sys.TouchCode[0], &QR_code_RxBfr[0], Sys.QR_code_Len);Str &Sys.TouchCode[TmpVble];Sys.Card_ID 0; while(0 ! isdigit(*Str)){Sys.Card_ID Sys.Card_ID*10 *Str - 0;Str;} 最后在通过以下…

【淘宝商品API接口】淘宝一件代发,如何找到便宜又靠谱的货源商品铺货到自己店铺?

电商商品API接口 对没有自己货源的淘宝小卖家来说&#xff0c;从1688等货源平台拿货做一件代发是最好的选择。不需要囤货&#xff0c;也不需要自己打包发货&#xff0c;投入小、风险低。 在大部分卖家眼里&#xff0c;1688上面的商品很贵&#xff0c;甚至比淘宝同行卖的都贵&…

Ceph集群RBD块存储:快照与Copy-on-Write克隆的基本操作

文章目录 1.RBD块存储镜像克隆概念2.copy-on-write克隆的基本使用2.1.在块存储中创建一个快照2.2.将快照配置成保护模式2.3.基于快照克隆出镜像2.4.使用克隆的镜像2.5.查看一个快照下有哪些克隆的镜像 1.RBD块存储镜像克隆概念 镜像克隆官方文档&#xff1a;https://docs.ceph…

Qt for android 添加自己的java包

java 包 目录 .pro 中添加 OTHER_FILES $$PWD/android/src/ScytheStudio \$$PWD/android/src/Serial 或 DISTFILES android/src/ScytheStudio \android/src/Serial \或(可以在Qt Creator中显示) DISTFILES android/src/ScytheStudio/*.java \android/src/Serial/*.java \

QQ沐个人引导页html源码

好看的QQ沐个人引导页html源码&#xff0c;鼠标移动滑出美丽的线条收缩特效&#xff0c;界面美观大气&#xff0c;源码由HTMLCSSJS组成&#xff0c;记事本打开源码文件可以进行内容文字之类的修改&#xff0c;双击html文件可以本地运行效果&#xff0c;也可以上传到服务器里面 …

【分享】3种方法取消PPT的“限制保护”

PPT如果设置了有密码的“只读方式”&#xff0c;每次打开PPT&#xff0c;都会出现对话框&#xff0c;提示需要输入密码才能修改文件&#xff0c;否则只能以“只读方式”打开。 以“只读方式”打开的PPT就会被限制&#xff0c;无法进行编辑修改等操作。那如果后续不需要“限制保…

Springboot阶段项目---《书城项目》

一 项目介绍 本项目采用集成开发平台IntelliJ IDEA开发了在线作业成绩统计系统的设计与实现&#xff0c;实现了图书商城系统的综合功能和图形界面的显示&#xff0c;可以根据每个用户登录系统后&#xff0c;动态展示书城首页图书&#xff0c;实现了分类还有分页查询&#xff0c…

MySQL -- 相关知识点

1.数据库相关介绍 数据库的选择通常取决于具体的应用需求&#xff0c;如性能、扩展性、数据一致性和易用性等因素。 1. 关系型数据库&#xff08;RDBMS&#xff09; MySQL&#xff1a; 广泛使用的开源数据库&#xff0c;支持大多数操作系统。强调易用性、灵活性和广泛的社区支…

Flutter Text导致A RenderFlex overflowed by xxx pixels on the right.

使用Row用来展示两个Text的时候页面出现如下异常,提示"A RenderFlex overflowed by xxx pixels on the right." The following assertion was thrown during layout: A RenderFlex overflowed by 4.8 pixels on the right.The relevant error-causing widget was:…

ClickHouse课件

列式存储数据库&#xff1a;hbase clickhouse 简介 ClickHouse入门 ClickHouse是俄罗斯的Yandex于2016年开源的列式存储数据库&#xff08;DBMS&#xff09;&#xff0c;使用C语言编写&#xff0c;主要用于在线分析处理查询&#xff08;OLAP&#xff09;&#xff0c;能够使用…

K8S中YAML案例

目录 案例&#xff1a;自主式创建service并关联上面的pod 案例&#xff1a;部署redis 案例&#xff1a;部署myapp 案例&#xff1a;部署MySQL数据库 总结 1.K8S集群中访问流向 K8S集群外部&#xff1a;客户端——nodeIP&#xff1a;nodeport——通过target port——podIP…

【排序算法】堆排序(Heapsort)

✨✨✨专栏&#xff1a;排序算法 &#x1f9d1;‍&#x1f393;个人主页&#xff1a;SWsunlight 目录 ​编辑 前言&#xff1a; 一、堆排序&#xff1a; 时间复杂度&#xff1a; 空间复杂度&#xff1a; 算法稳定性&#xff1a; 二、升序的实现&#xff1a;通过建大堆实…

find 几招在 Linux 中高效地查找目录

1. 介绍 在 Linux 操作系统中&#xff0c;查找目录是一项常见的任务。无论是系统管理员还是普通用户&#xff0c;都可能需要查找特定的目录以执行各种操作&#xff0c;如导航文件系统、备份数据、删除文件等。Linux 提供了多种命令和工具来帮助我们在文件系统中快速找到目标目…

百度软件测试面试经历,期望薪资27K

一面 1、 请为百度搜索框设计测试用例&#xff1f; 2、百度设计框上线前需要进行那些测试&#xff1f; 界面测试&#xff0c;功能测试&#xff0c;性能测试&#xff0c;安全性测试&#xff0c;易用性测试&#xff0c;兼容性测试&#xff0c;UI测试。 3、如何查看http状态码…