童鞋们好,我是【考拉搞AI】,一个专注于 VibeCoding 分享 & AI 工程化 的博主。
上一期我们盘点了 7 套登录页 和 5 种自定义 TabBar,不少童鞋在评论区追问:
"登录页里的输入框能不能也做成统一组件?" "每个登录页自己写输入框样式太累了,圆角、边框、清除按钮、密码显隐切换……" "搜索页的搜索栏也是五花八门,能不能也统一?"
是的——表单是 App 中最高频也最碎片化的组件之一:6
登录页有账号密码、有手机号验证码 注册页有姓名、邮箱、邀请码 设置页有只读字段、禁用字段 反馈页有 textarea 带字数统计 搜索页有胶囊、小圆角、扁平、嵌入式、迷你胶囊……
每页都自己手撸一套输入框?Token还要不要了?
于是,这期直接肝出:
通用输入 8 种场景(login / verify / feedback / disabled / icon-prefix / icon-suffix / otp / floating) 搜索栏 6 种独立形态(pill / card / bubble / flat / embed / mini) **登录页技能全面接入 base-input**(不再用base-card模拟输入框)每个场景独立成 HTML + MD,按形态检索复用
任何是组合技:
uniapp-theme-skill —— 统一样式变量,换风格一行搞定 icon-catch-skill —— 抓专业图标,拒绝丑 emoji image-catch-skill —— 抓真实图片,拒绝大白块 uniapp-style-skill —— 设计系统审查,保证单页面合规 frontend-style-harmonizer-skill —— 跨页面样式治理,保证项目整体一致
还是那句老话,与直接让 AI 手搓相比,用技能来写这些页面有这些优势:
风格统一:登录、注册、设置、反馈……全站输入框一套参数调到底 节省 Token:省去 AI 反复思考圆角、边框、清除按钮的样式 技能矩阵:结合主题、样式、图片/icon 技能,效果显著
废话不多说,开整。
不知不觉,感觉快肝出一整个组件库~~~~~~~~
一、base-input 与 base-card
为啥单独搞个 base-input?直接用 base-card 套 <input> 不就行了?
行,但是会出现几个问题:
<!-- 用 base-card 模拟输入框:每个登录页都得重新写一遍 --><base-card height="44px" radius="var(--radius-md)" padding="0 var(--space-3)"> <input class="input-control" placeholder="请输入账号"></base-card>密码框的显隐切换怎么写? 清除按钮的位置和点击事件怎么写? 错误态的红框 + 红字怎么统一? 必填星号的位置怎么对齐? prefix slot 和 suffix slot 怎么扩展?
每个登录页都得重新撸一遍,碎片化就此开始。
于是 base-input 诞生——它和 base-card一脉相承:
base-card = 容器属性(背景/圆角/边框/阴影)+ 内容base-input = 容器属性(背景/圆角/边框/标签)+ 原生 input 行为两者都是「参数化外壳组件」——base-card 外壳包内容,base-input 外壳包原生 <input>。设计哲学一脉相承。
base-card | |||
base-input | <input> |
一句话:**
base-card是「一切皆卡片」的根,base-input是「一切皆卡片」在表单领域的延伸。**
二、本次迭代——14 种输入场景
为了让童鞋们按形态检索复用,本次把所有场景独立成文件,每个文件一个 HTML 演示 + 一个 MD 文档。
1. 通用输入(8 种)
2. 搜索栏变体(6 种独立形态)
三、登录页技能全面接入 base-input
这是本次最重要的升级:所有含输入框的登录页 .md 文档,全部从 base-card 模拟改用真正的 <base-input> 组件。
涉及 6 个登录页:
base-card 模拟 2 个输入框 | <base-input border="all" show-clear show-password> | |
base-card 模拟 + 自己撸验证码按钮 | <base-input border="all"> + #suffix slot | |
base-card 模拟下划线 | <base-input border="bottom"> | |
base-card 模拟 2 个输入框(4px 圆角) | <base-input border="all">(账号密码) | |
base-card 模拟下划线 | <base-input border="bottom">(下划线样式 + 透明背景) | |
base-card 模拟 + 自己撸验证码按钮 | <base-input border="all"> + #suffix slot(手机号 + 验证码) |
注:
login-wechat是微信一键登录风格,vue 代码块内无 input 字段,不涉及 base-input 改造。
对比示例:标准账号登录
之前(用 base-card 模拟):
<base-card :height="'52px'" :background="'var(--color-bg)'" :border-radius="'var(--radius-md)'" :padding="'0 var(--space-3)'"> <input class="input-control" placeholder="请输入账号"> <view class="clear-btn">×</view></base-card><base-card :height="'52px'" :background="'var(--color-bg)'" :border-radius="'var(--radius-md)'" :padding="'0 var(--space-3)'"> <input class="input-control" type="password" placeholder="请输入密码"> <view class="toggle-btn">显示</view></base-card>现在(用 base-input):
<base-input v-model="form.username" label="账号" required border="all" placeholder="请输入账号" show-clear/><base-input v-model="form.password" type="password" label="密码" required border="all" placeholder="请输入密码" show-password/>好处一目了然:
不用再写 clear-btn/toggle-btn的样式了不用再写 required-mark必填星号了错误态用 error="账号至少 4 位字符"一行解决主题切换时输入框自动跟随(因为 border="all"控制的是边框策略,圆角由radiusprop 控制,全部走 CSS 变量)
四、base-input Props 全景
interface Props { modelValue?: stringtype?: 'text' | 'password' | 'textarea' | 'number' | 'tel' | 'email' | 'digit' placeholder?: string label?: string// 左侧标签 required?: boolean// 是否必填(自动显示红色星号) disabled?: boolean// 禁用(灰底) readonly?: boolean// 只读(灰底,可复制) maxlength?: number// 最大长度 showClear?: boolean// 有值时显示清除按钮 showPassword?: boolean// 密码框显隐切换 border?: 'all' | 'bottom' | 'none'// 边框策略 error?: string// 错误提示(红框 + 红字) autoHeight?: boolean// textarea 自适应高度 rows?: number// textarea 默认行数}Slots
prefix | ||
suffix |
主题变量
var(--color-surface) /* 输入框背景 */var(--color-bg) /* 禁用态背景 */var(--color-border) /* 边框 */var(--color-text) /* 输入文字 */var(--color-text-tertiary) /* placeholder */var(--color-error) /* 错误提示、必填星号 */var(--radius-md) /* 圆角 */五、典型场景代码示例
1. 账号密码登录(border="all")
<base-card :background="'var(--color-surface)'" :border-radius="'var(--radius-lg)'" :padding="'var(--space-5)'" :shadow="'var(--shadow-sm)'"> <base-input v-model="form.username" label="账号" required border="all" placeholder="请输入账号" show-clear /> <base-input v-model="form.password" type="password" label="密码" required border="all" placeholder="请输入密码" show-password /></base-card>2. 手机号验证码(border="bottom" + suffix slot)
<base-input v-model="form.code" type="number" :maxlength="6" label="验证码" required border="bottom" placeholder="请输入验证码"> <template #suffix> <view class="send-btn" :class="{ disabled: countdown > 0 }" @click="onSendCode"> <text>{{ countdown > 0 ? `${countdown}s` : '发送验证码' }}</text> </view> </template></base-input>3. 多行反馈(type="textarea")
<base-input v-model="form.feedback" type="textarea" label="反馈内容" :rows="5" :maxlength="500" border="all" placeholder="请输入您的反馈..."/>4. 验证码格子(6 位独立 OTP)
这是
base-input的视觉变体——通过type="number"+:maxlength="6"+ 自定义 UI 实现独立格子、自动跳格、闪烁光标。
<base-otp v-model="code" :length="6" type="number"/><view class="otp-meta"> <text>{{ code.length }} / 6</text> <text class="resend" @click="onResend"> {{ countdown > 0 ? `${countdown}s 后重发` : '重新发送' }} </text></view>5. 浮动标签(Material Design 风格)
<base-input-floating v-model="form.name" label="姓名" border="bottom"/><base-input-floating v-model="form.phone" label="手机号" type="number" :maxlength="11" border="bottom" error="手机号格式不正确"/>6. 搜索栏变体(6 种形态)
搜索栏是
base-input的形态变体,由base-input+ 外层容器控制圆角/背景/阴影实现,不单独建组件。
<!-- 1. 胶囊 pill:999px 圆角 + 阴影,顶部导航主流 --><view style="background:white;border-radius:999px;height:36px;..."> <base-input v-model="kw" placeholder="搜索..." border="none" show-clear> <template #prefix> <svg>...搜索 icon...</svg> </template> </base-input></view><!-- 2. 小圆角卡片 card:8px 圆角,结果页内嵌 --><view style="background:white;border-radius:8px;height:36px;box-shadow:var(--shadow-sm);..."> ...</view><!-- 3. 弹窗卡片 bubble:12px 大圆角 + 中等阴影,命令面板式 --><view style="background:white;border-radius:12px;height:44px;box-shadow:var(--shadow-md);..."> ...</view><!-- 4. 扁平 flat:0 圆角 + 白底,工具类极简 --><view style="background:white;border-radius:0;height:44px;..."> ...</view><!-- 5. 嵌入式 embed:8px 圆角 + 浅底嵌入,头部轻搜索 --><view style="background:var(--color-bg);border-radius:8px;height:36px;..."> ...</view><!-- 6. 迷你胶囊 mini:999px 浅底 36px,头像旁内联 --><view style="background:var(--color-bg);border-radius:999px;height:36px;..."> ...</view>












六、圆角 × 边框选型对照
base-input 通过 border prop + 外层 radius 实现 14 种形态:
0 | bottom | ||
0 | all | ||
8px | all | ||
8px | grid | ||
12px | all | ||
12px | bottom | ||
999px | none | ||
8px | none | ||
12px | none | ||
0 | none | ||
8px | none |
七、唤醒操作
# 通用输入/uniapp-base-skill 做一个账号密码登录页/uniapp-base-skill 做一个手机号验证码登录页/uniapp-base-skill 做一个意见反馈表单/uniapp-base-skill 做一个订单详情页(只读)/uniapp-base-skill 做一个带前缀图标的输入框(邮箱/手机号/金额)/uniapp-base-skill 做一个验证码格子(OTP 6 位)/uniapp-base-skill 做一个浮动标签输入框# 搜索栏/uniapp-base-skill 做一个胶囊搜索栏(顶部导航)/uniapp-base-skill 做一个搜索结果页内嵌搜索栏/uniapp-base-skill 做一个全局搜索弹窗/uniapp-base-skill 做一个极简扁平搜索/uniapp-base-skill 做一个嵌入式头部轻搜索/uniapp-base-skill 做一个头像旁的迷你搜索# 登录页(已自动接入 base-input)/uniapp-base-skill 做一个标准账号登录页/uniapp-base-skill 做一个手机号验证码登录页/uniapp-base-skill 做一个极简清爽登录页台风天又来了
base-input 是 base-card 思想在表单领域的延伸——
base-card:容器属性 + 内容 = 一切皆卡片base-input:容器属性 + 原生 input = 一切皆表单卡片
童鞋们后续做登录、注册、设置、反馈、个人资料……所有含输入的页面,直接用 <base-input> 就对了,不用再自己撸清除按钮、密码显隐、错误态、必填星号。
而且相关md技能颗粒化适中,自由度爆表,规范化爆炸,伙伴们使用一次就可以自定义出任何想要的组件插件!
后续,博主会继续把古法时代和 AI 时代所接触过的页面,适配性高的,一一用 base-input + base-card 搭配出来,童鞋们包括我自己,直接就可以使用的那种,只需要调整主题色和尺寸即可。
当然 base-input 本身也会不断迭代,本技能属于一个迭代性机能,或者说是一套不断完善的提示词模板!
下次我们继续来设计几套既定模板页面【更加实战化具体化的业务页面】,同时优化 base-input 比如增加 语音输入、数字步进器、字数计数器 slot 等。
喜欢的童鞋一定要多多点赞收藏!
仓库地址:https://github.com/jiushiwon/wg-skills/tree/main/uniapp-base-skill
一天一个SKILL——FastAPI 后端脚手架:接口契约、架构规范、数据模型、 SSE/上传、安装重启脚本,前端联动零成本,Token直线下降!
一天一个SKILL——uniapp+移动端APP页面布局导航登录页升级:7 套登录页 + 5 种自定义底部 TabBar,Token直线下降,效率嘎嘎提升!
我是【考拉搞AI】,专注 VibeCoding 实战与 AI 工程化。发送 VibeCoding即可加入 VibeCoding 学习小圈子!
夜雨聆风