Browse Source

feat(keyboard): 添加数字键盘组件并优化z-index层级

添加新的数字键盘组件用于商品数量输入,包含数字输入、清空、删除和确认功能
统一调整多个组件的z-index值以优化页面层级显示
master
wei 2 days ago
parent
commit
60fe173086
  1. 2
      components/custom-tab-bar/my-tab-bar.vue
  2. 189
      components/keyboard/keyboard copy.vue
  3. 205
      components/keyboard/keyboard.vue
  4. 2
      components/navigation/navigation.vue
  5. 34
      pages/allDish/allDish.scss
  6. 22
      pages/home/home.vue
  7. 18
      pages/joinEnterprise/joinEnterprise.scss
  8. 18
      pages/recipeOrder/recipeOrder.scss
  9. 6
      pages/shoppingCart/shoppingCart.scss

2
components/custom-tab-bar/my-tab-bar.vue

@ -141,7 +141,7 @@ onLoad(() => {
padding-bottom: env(safe-area-inset-bottom);
pointer-events: auto;
padding-top: 5px;
z-index: 10003;
z-index: 10;
box-shadow: 0rpx -2rpx 21rpx 0rpx rgba(29,51,17,0.1);
display: flex;
.tab-bar-item {

189
components/keyboard/keyboard copy.vue

@ -0,0 +1,189 @@
<script setup>
import { defineEmits, ref } from "vue";
const emit = defineEmits(["confirm", "cancel"]);
const inputValue = ref("1");
function onTap(key) {
if (key === "confirm") {
//
emit("confirm", Number(inputValue.value));
}
else if (key === "cancel") {
//
emit("cancel");
}
else if (key === "clear") {
//
inputValue.value = "";
}
else if (key === "delete") {
//
inputValue.value = inputValue.value.slice(0, -1);
}
else {
//
inputValue.value += key;
}
}
</script>
<template>
<view class="keyboard">
<view class="keyboard-body">
<input class="select-num-top" placeholder="限0~999" disabled :value="inputValue">
<view class="key" @tap="() => onTap('1')">
1
</view>
<view class="key" @tap="() => onTap('2')">
2
</view>
<view class="key" @tap="() => onTap('3')">
3
</view>
<view class="key action delete" @tap="() => onTap('delete')">
</view>
<view class="key" @tap="() => onTap('4')">
4
</view>
<view class="key" @tap="() => onTap('5')">
5
</view>
<view class="key" @tap="() => onTap('6')">
6
</view>
<view class="key action clear" @tap="() => onTap('clear')">
清空
</view>
<view class="key" @tap="() => onTap('7')">
7
</view>
<view class="key" @tap="() => onTap('8')">
8
</view>
<view class="key" @tap="() => onTap('9')">
9
</view>
<view class="key action confirm" @tap="() => onTap('confirm')">
确定
</view>
<view class="key zero span-2" @tap="() => onTap('0')">
0
</view>
<view class="key cancel" @tap="() => onTap('cancel')">
取消
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.keyboard {
width: 100%;
height: 100%;
position: fixed;
left: 0;
bottom: 0;
z-index: 999999;
background: rgba(0, 0, 0, 0.2);
}
/* Grid 容器:3列数字 + 1列操作 */
.keyboard-body {
box-sizing: border-box;
background: #f2f3f5;
padding: 20rpx 20rpx env(safe-area-inset-bottom) 20rpx;
left: 0;
bottom: 0;
display: grid;
position: fixed;
width: 100%;
grid-template-columns: repeat(3, 1fr) 1fr; /* 四列 */
/* 顶部输入占一整行 + 下方4行按键 */
grid-template-rows: 100rpx repeat(4, 84rpx);
gap: 12rpx;
}
/* 键通用样式 */
.key {
background-color: #fff;
border-radius: 12rpx;
// border: 1px solid #d8d8d8;
display: flex;
align-items: center;
justify-content: center;
font-size: $text-4xl;
font-weight: 430;
&:active {
background-color: #e0e2e7;
}
}
/* 0 跨两列:第4行的第1-2列 */
.span-2 {
grid-column: 1 / span 2;
}
/* 取消:第4行第3列 */
.cancel {
grid-column: 3;
grid-row: 4;
background-color: #e0e2e7;
&:active {
background-color: #fff;
}
}
/* 右侧操作列(第4列) */
.action {
background-color: #e0e2e7;
&:active {
background-color: #fff;
}
}
/* 删除:第1行第4列 */
.action.delete {
grid-column: 4;
grid-row: 2;
}
/* 清空:第2行第4列 */
.action.clear {
grid-column: 4;
grid-row: 3;
}
/* 确定:第3行开始,跨两行占第3-4行第4列 */
.action.confirm {
grid-column: 4;
grid-row: 4 / span 2;
}
/* 取消:第5行第3列 */
.cancel {
grid-column: 3;
grid-row: 5;
}
/* 顶部输入:跨4列、位于第1行 */
.keyboard .select-num-top {
height: 100rpx;
border: none;
font-size: 32rpx;
font-weight: bold;
color: #000;
padding: 0rpx 10rpx;
text-align: center;
border-radius: 12rpx;
background: #fff;
/* 关键定位 */
grid-column: 1 / -1;
grid-row: 1;
}
</style>

205
components/keyboard/keyboard.vue

@ -0,0 +1,205 @@
<script setup>
import { defineEmits, ref } from "vue";
const emit = defineEmits(["confirm", "cancel"]);
const inputValue = ref("");
function onTap(key) {
if (key === "confirm") {
//
if (inputValue.value === "") {
uni.showToast({
title: "请输入数量",
icon: "none",
});
return;
}
emit("confirm", Number(inputValue.value));
}
else if (key === "cancel") {
//
emit("cancel");
}
else if (key === "clear") {
//
inputValue.value = "";
}
else if (key === "delete") {
//
inputValue.value = inputValue.value.slice(0, -1);
}
else {
//
const nextValue = inputValue.value + key;
if (nextValue > 999) {
uni.showToast({
title: "数量不能超过999",
icon: "none",
});
return;
}
inputValue.value = `${Number(nextValue)}`;
}
}
</script>
<template>
<view class="keyboard">
<view class="keyboard-body">
<input class="select-num-top" placeholder="限0~999" disabled :value="inputValue">
<view class="key" @tap="() => onTap('1')">
1
</view>
<view class="key" @tap="() => onTap('2')">
2
</view>
<view class="key" @tap="() => onTap('3')">
3
</view>
<view class="key action delete" @tap="() => onTap('delete')">
</view>
<view class="key" @tap="() => onTap('4')">
4
</view>
<view class="key" @tap="() => onTap('5')">
5
</view>
<view class="key" @tap="() => onTap('6')">
6
</view>
<view class="key action clear" @tap="() => onTap('clear')">
清空
</view>
<view class="key" @tap="() => onTap('7')">
7
</view>
<view class="key" @tap="() => onTap('8')">
8
</view>
<view class="key" @tap="() => onTap('9')">
9
</view>
<view class="key action confirm" @tap="() => onTap('confirm')">
确定
</view>
<view class="key zero span-2" @tap="() => onTap('0')">
0
</view>
<view class="key cancel" @tap="() => onTap('cancel')">
取消
</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.keyboard {
width: 100%;
height: 100%;
position: fixed;
left: 0;
bottom: 0;
z-index: 11;
background: rgba(0, 0, 0, 0.2);
}
/* Grid 容器:3列数字 + 1列操作 */
.keyboard-body {
box-sizing: border-box;
background: #f2f3f5;
padding: 20rpx 20rpx env(safe-area-inset-bottom) 20rpx;
left: 0;
bottom: 0;
display: grid;
position: fixed;
width: 100%;
grid-template-columns: repeat(3, 1fr) 1fr; /* 四列 */
/* 顶部输入占一整行 + 下方4行按键 */
grid-template-rows: 100rpx repeat(4, 84rpx);
gap: 12rpx;
}
/* 键通用样式 */
.key {
background-color: #fff;
border-radius: 12rpx;
// border: 1px solid #d8d8d8;
display: flex;
align-items: center;
justify-content: center;
font-size: $text-4xl;
font-weight: 430;
&:active {
background-color: #e0e2e7;
}
}
/* 0 跨两列:第4行的第1-2列 */
.span-2 {
grid-column: 1 / span 2;
}
/* 取消:第4行第3列 */
.cancel {
grid-column: 3;
grid-row: 4;
background-color: #e0e2e7;
&:active {
background-color: #fff;
}
}
/* 右侧操作列(第4列) */
.action {
background-color: #e0e2e7;
&:active {
background-color: #fff;
}
}
/* 删除:第1行第4列 */
.action.delete {
grid-column: 4;
grid-row: 2;
}
/* 清空:第2行第4列 */
.action.clear {
grid-column: 4;
grid-row: 3;
}
/* 确定:第3行开始,跨两行占第3-4行第4列 */
.action.confirm {
grid-column: 4;
grid-row: 4 / span 2;
}
/* 取消:第5行第3列 */
.cancel {
grid-column: 3;
grid-row: 5;
}
/* 顶部输入:跨4列、位于第1行 */
.keyboard .select-num-top {
height: 100rpx;
border: none;
font-size: 32rpx;
font-weight: bold;
color: #000;
padding: 0rpx 10rpx;
text-align: center;
border-radius: 12rpx;
background: #fff;
/* 关键定位 */
grid-column: 1 / -1;
grid-row: 1;
}
</style>

2
components/navigation/navigation.vue

@ -104,7 +104,7 @@ function gotoBack() {
left: 0;
top: 0;
width: 100%;
z-index: 999;
z-index: 10;
.left {
display: flex;
align-items: center;

34
pages/allDish/allDish.scss

@ -3,7 +3,7 @@
position: relative;
box-sizing: border-box;
background-color: #fff;
z-index: 99999999;
z-index: 10;
.box {
margin-left: 14rpx;
margin-right: 14rpx;
@ -65,7 +65,7 @@ page {
background-color: #fff;
/* position: fixed; */
/* top: 0; left: 0; */
z-index: 99;
z-index: 10;
font-size: $text-base;
}
@ -102,7 +102,7 @@ page {
.all {
width: 10%;
position: relative;
z-index: 10;
// z-index: 10;
display: flex;
.border {
@ -129,7 +129,7 @@ page {
position: fixed;
width: 100%;
height: 100%;
z-index: 999999;
z-index: 100;
background-color: #000;
opacity: .4;
}
@ -309,7 +309,7 @@ page {
.footer {
height: 100rpx;
position: fixed;
z-index: 99999;
z-index: 10;
bottom: 0;
width: 100%;
background: #ffffff;
@ -374,7 +374,7 @@ page {
.big-type {
position: fixed;
z-index: 999999;
z-index: 10;
background-color: #fff;
width: 100%;
padding: 30rpx 30rpx 20rpx 30rpx;
@ -449,7 +449,7 @@ page {
flex-direction: row;
padding: 6px 0;
position: relative;
z-index: 9999999;
z-index: 10;
background-color: #fff;
}
@ -457,7 +457,7 @@ page {
position: absolute;
right: 110rpx;
top: 32rpx;
z-index: 2222222;
z-index: 10;
text-align: center;
}
@ -465,7 +465,7 @@ page {
position: absolute;
right: 144rpx;
top: 24rpx;
z-index: 222222;
z-index: 10;
width: 28rpx;
height: 28rpx;
@ -544,12 +544,12 @@ page {
background: #000;
opacity: 0.2;
overflow: hidden;
z-index: 100000;
z-index: 100;
color: #fff;
}
.commodity_screen_languge {
z-index: 100001;
z-index: 100;
}
/* 对话框 */
@ -560,7 +560,7 @@ page {
position: fixed;
bottom: 0;
left: 0;
z-index: 100000;
z-index: 101;
background: #fff;
padding-top: 20rpx;
}
@ -573,14 +573,14 @@ page {
position: fixed;
bottom: 0;
left: 0;
z-index: 100002;
z-index: 101;
background: #fff;
padding-top: 20rpx;
}
.cart_pop {
max-height: 65%;
z-index: 9999;
z-index: 101;
margin-bottom: 47px;
padding: 20rpx 0;
}
@ -737,7 +737,7 @@ page {
.top-bar {
position: relative;
z-index: 9999999;
z-index: 10;
background-color: #fff;
}
@ -839,14 +839,14 @@ page {
height: 100%;
left: 0;
top: 0;
z-index: 999999;
z-index: 100;
background-color: #000;
opacity: .4;
}
.first-big-type {
position: fixed;
z-index: 999999999;
z-index: 100;
background-color: #fff;
width: 100%;
padding: 30rpx 30rpx 20rpx 30rpx;

22
pages/home/home.vue

@ -3,6 +3,7 @@ import { onLoad, onShow } from "@dcloudio/uni-app";
// import moment from "moment";
import { ref } from "vue";
import customTabBar from "@/components/custom-tab-bar/my-tab-bar.vue";
import keyboard from "@/components/keyboard/keyboard.vue";
import navv from "@/components/nav/nav.vue";
import {
addCartApi,
@ -312,6 +313,15 @@ function changeSwiper(e) {
const index = e.detail.current;
swiperCurrent.value = index;
}
/**
* 点击确认按钮时将输入框的值赋值给商品项的sum属性
* @param e 事件对象
*/
function determine(value, item) {
console.log(value, 333);
isShowkeyboard.value = false;
}
/**
* 选择地址
*/
@ -363,11 +373,6 @@ function onEnterPage() {
uni.navigateTo({
url: "/pages/home/enterKing/enterKing",
});
// enterVegetableKing
// uni.showToast({
// title: "",
// icon: "none",
// });
}
/**
* 打开招聘求职
@ -800,10 +805,15 @@ onShow(async () => {
<text
class="input"
@tap="() => showKeyboard(item.specs[0], index, childsIndex, tabActive)"
@tap="() => isShowkeyboard = true"
>
{{ item.specs[0].sum }}
</text>
<keyboard
v-if="isShowkeyboard"
@confirm="(val) => determine(val, item.specs[0])"
@cancel="() => isShowkeyboard = false"
/>
<!-- <input
:value="item.specs[0].sum"
class="input"

18
pages/joinEnterprise/joinEnterprise.scss

@ -56,7 +56,7 @@
background: #000;
opacity: 0.2;
overflow: hidden;
z-index: 1000;
z-index: 100;
color: #fff;
}
@ -68,7 +68,7 @@
position: fixed;
bottom: 0;
left: 0;
z-index: 2000;
z-index: 101;
background: #fff;
}
@ -130,7 +130,7 @@ checkbox .wx-checkbox-input {
bottom: 0;
width: 100%;
height: 100%;
z-index: 999;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
@ -328,7 +328,7 @@ checkbox .wx-checkbox-input {
background: #000;
opacity: 0.6;
overflow: hidden;
z-index: 1000;
z-index: 100;
}
.join-pop {
@ -338,7 +338,7 @@ checkbox .wx-checkbox-input {
top: 0;
left: 0;
overflow: hidden;
z-index: 2000;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
@ -348,7 +348,7 @@ checkbox .wx-checkbox-input {
width: 80%;
background-color: #fff;
position: relative;
z-index: 2000;
z-index: 100;
border-radius: 14rpx;
overflow: hidden;
padding-bottom: 80rpx;
@ -411,7 +411,7 @@ checkbox .wx-checkbox-input {
background: #000;
opacity: 0.6;
overflow: hidden;
z-index: 1000;
z-index: 100;
}
.phone-pop {
@ -421,7 +421,7 @@ checkbox .wx-checkbox-input {
top: 0;
left: 0;
overflow: hidden;
z-index: 2000;
z-index: 100;
display: flex;
align-items: center;
justify-content: center;
@ -431,7 +431,7 @@ checkbox .wx-checkbox-input {
width: 80%;
background-color: #fff;
position: relative;
z-index: 2000;
z-index: 100;
border-radius: 14rpx;
overflow: hidden;
padding-bottom: 80rpx;

18
pages/recipeOrder/recipeOrder.scss

@ -233,7 +233,7 @@
.footer {
height: 100rpx;
position: fixed;
z-index: 99999;
z-index: 10;
bottom: 0;
width: 100%;
background: #ffffff;
@ -309,7 +309,7 @@
position: absolute;
right: 110rpx;
top: 32rpx;
z-index: 2222222;
z-index: 10;
text-align: center;
}
@ -317,7 +317,7 @@
position: absolute;
right: 144rpx;
top: 24rpx;
z-index: 222222;
z-index: 10;
width: 28rpx;
height: 28rpx;
}
@ -413,12 +413,12 @@
background: #000;
opacity: 0.2;
overflow: hidden;
z-index: 100000;
z-index: 100;
color: #fff;
}
.commodity_screen_languge {
z-index: 100001;
z-index: 100;
}
/*对话框 */
@ -429,7 +429,7 @@
position: fixed;
bottom: 0;
left: 0;
z-index: 100000;
z-index: 100;
background: #fff;
padding-top: 20rpx;
}
@ -442,14 +442,14 @@
position: fixed;
bottom: 0;
left: 0;
z-index: 100002;
z-index: 100;
background: #fff;
padding-top: 20rpx;
}
.cart_pop {
max-height: 65%;
z-index: 9999;
z-index: 100;
margin-bottom: 47px;
padding: 20rpx 0;
}
@ -478,7 +478,7 @@
top: 0;
left: 0;
right: 0;
z-index: 9999;
z-index: 10;
}

6
pages/shoppingCart/shoppingCart.scss

@ -59,7 +59,7 @@
height: 100%;
background: #FFFFFF;
opacity: 0.6;
z-index: 999;
z-index: 9;
}
.image-box {
width: 174rpx;
@ -83,7 +83,7 @@
padding: 16rpx 24rpx;
width: 40%;
text-align: center;
z-index: 999;
z-index: 9;
}
.info {
height: 100%;
@ -226,7 +226,7 @@
width: 100%;
// bottom: 90rpx;
background: #fff;
z-index: 999;
z-index: 9;
/* padding-bottom: 20rpx; */
padding: 0 14rpx 10rpx;
box-sizing: border-box;

Loading…
Cancel
Save