Make By. RainyTears 基于 Vue移动端打造的「悬浮面板 + 输入框」 ```sh ├── floatPanel.vue # 横向滚动按钮组 / 插槽面板 └── InputArea.vue # 语音/文字双模式输入容器 ``` --- ## 1. 特性总览 | 层级 | 可插拔 | | | ------ | -------------------------------------- | --- | | **外层** | `InputArea.vue` 负责长录音、键盘切换、主题色、v-model | | | **面板** | `floatPanel.vue` 提供按钮渲染 + 两种插槽,零逻辑依赖 | | > ✅ 支持 uni-app、hbuilder、vue3+setup --- ## 2. 安装与最简调用 ```vue ``` --- ## 3. Props(index.Vue) | 属性 | 类型 | 默认 | 说明 | | ----------------- | ------- | ---------------------- | --------------------------- | | modelValue | String | '' | 输入框内容,支持 v-model | | showPanel | Boolean | false | 浮层面板显隐,支持 v-model:showPanel | | placeholder | String | 点击输入或按住说话... | 输入框占位 | | longPressTip | String | 正在录音,上滑取消 | 长按时提示 | | cancelTip | String | 松开手指,取消发送 | 上滑取消时提示 | | LeftIcon | String | /static/button.Png | 左侧图标 | | sendIcon | String | /static/send.Png | 发送态图标 | | attachmentIcon | String | /static/Attachment.Png | 附件图标 | | showLeftBtn | Boolean | true | 是否显示左侧按钮 | | buttons | Array | 见代码 | 面板的按钮数据 | | panelHeight | String | 100rpx | 面板高度 | | panelBottomOffset | String | 10rpx | 面板与输入框距离 | | panelPadding | String | 15rpx | 面板左右留空 | | longPressDelay | Number | 200 | 长按触发阈值 ms | | cancelThreshold | Number | 100 | 上滑取消的 px 阈值 | | adjustPosition | Boolean | false | input adjust-position | | holdKeyboard | Boolean | true | input hold-keyboard | | confirmType | String | send | input confirm-type | | themeColor
| String | #a846e6 | 主色,同--main-color | | BarHeight | String | 100rpx | 整个聊天条高度 | | PadBottom | String | 36rpx | 距离底部距离 | --- ## 4. Events(index.Vue) | 事件 | 参数 | 说明 | | ----------------- | ---------------------------- | -------------- | | update:modelValue | text:String | 文本变化 | | update:showPanel | show:Boolean | 面板显隐变化 | | LongPressStart | - | 开始长按输入框(可用于录音) | | LongPressEnd | - | 正常松手结束 | | LongPressCancel | - | 上滑取消 | | Send | {type:'text',content:String} | 点击发送触发 | | PanelClick | {button,index} | 面板按钮/插槽点击 | | LeftButtonClick | - | 左侧按钮触发 | --- ## 5. Slots — 高自由度 | 插槽 | 作用域 | 用法 | | ------------------------------ | -------------- | ------------------------ | | panel-content(index.Vue) | - | **外层整体替换面板**,常用于自定义复杂 ui | | -(floatPanel.Vue 默认插槽) | - | **完全覆盖按钮区**,保留滚动和动效骨架 | | button-content(floatPanel.Vue) | {button,index} | **仅定制按钮内部结构**,不破坏外层 item | | | | | > 注意:一旦使用 floatPanel 默认插槽 (``),预设按钮循环即不再渲染,仅展示你提供的内容,仍享有 hide/disabled 动效。 --- ## 6. 内部状态(index.Vue) - `focusLock:boolean` —— 防止长按后立即抖动聚焦 - `isLongPressing / isCancelling` —— 手势长按聊天条状态 - `innerShowPanel` —— 本地面板显隐,外部通过 v-model:showPanel 同步 > 面板显隐会自动受 focus/blur 影响,可在回调里 `setPanelVisible` 覆盖 --- ## 7. 样式变量(index.Scss) | CSS 变量 | 默认 | 用途 | | ------------ | -------------------------------- | ------ | | --main-color | #a846e6 | 主色 | | $elastic | transform 0.35s cubic-bezier(... | 全局弹性曲线 | | $btn-height | 100rpx | 输入条高度 | --- ## 8. 常见修补/扩展 1. 底部安全区 & 全面屏定位已内置:`env(safe-area-inset-bottom) + 60rpx` 2. 举例:想替换「长按录音」为「长按拍照」: - 监听 `LongPressStart` 调起相机,返回值自己构造 3. 面板支持无限长按钮,内部 `scroll-view` 已 `white-space:nowrap` ---