当前位置: 首页 > news >正文

毕设日志26.3.20(1):HBuilderX开发蓝牙时钟APP,class文本框,picker,event

Q:我想给发送区加框框,框住待发送文本。要怎么加啊

<!-- 发送通用数据区域(可保留用于测试) --> <input v-model="sendMsg" placeholder="输入要发送的数据" /> <button @click="sendData">发送数据</button>

A:

给发送通用数据区域加一个框很简单:用一个<view><input><button>包起来,然后给这个<view>添加边框样式。

Q:所以如果想要指定任何不是直接一个文本出现在app界面的东西出现,就是把它写成一个类然后在style上指定样式?

A:

是的,你的理解基本正确。

在 Vue/uni-app 中,任何你想自定义样式的界面元素,通常的做法就是:

  1. 在模板中给该元素添加一个class属性(例如<view class="my-box">)。

  2. <style>中通过类选择器(例如.my-box { ... })来定义它的外观(边框、背景、间距等)。

这适用于任何元素,无论是单个组件(如按钮、文本)还是一个由多个元素组合成的区块。

但需要注意两点:

  • 不是必须用 class:你也可以用标签选择器(如button {})或内联样式(不推荐),但class是最灵活、最常用的方式。

  • “把东西写成一个类”并不准确更准确的说法是“在模板里用class把样式挂到元素上”。类本身只是一个标识符,真正的样式定义在<style>里。

这就实现了“框住发送区”的效果。

所以,你现在已经掌握了最核心的界面定制方法——组合元素 + 加 class + 写样式。继续读代码会发现更多这样的模式。

Q:但这样会把文本发送处和按钮一起框起来。我要要只框住发送文本,不框住按键。

A:

只需:

  1. 删除包裹用的<view class="send-box">和对应的</view>

  2. <input>上直接加一个类,比如class="input-box"

  3. <style>中定义.input-box的边框样式。

这样就能只框住输入框了。如果需要调整输入框与按钮之间的间距,可以用margin-bottom或给按钮加margin-top

(这个东西真就是指哪打哪…)

Q:详解这两句。

<picker @change="onAlarmNumberChange" :range="[1,2]" range-key="$index"> <view class="picker">闹钟编号: {{ alarmNumber }}</view>

A:

1.<picker>组件

picker是 uni-app 内置的滚动选择器,用于从一组预定义选项中选择一个值。它通常用于让用户选择数字、日期、时间或自定义选项。


2.@change="onAlarmNumberChange"

  • @change是事件绑定,当用户在 picker 中滑动并确认选择时触发。

  • 绑定的方法名是onAlarmNumberChange,需要在methods中定义。

  • 当选择变化时,系统会调用该方法,并传入一个事件对象,其中包含新选中的值(索引或具体值)。


3.:range="[1,2]"

  • :range是动态绑定(v-bind:range的简写),指定可供选择的选项数组。

  • 这里range是一个固定数组[1, 2],表示只有两个选项:数字 1 和数字 2。你可以根据需求扩展成更多选项,比如[1,2,3,4,5]


4.range-key="$index"

  • range-key用于指定在range数组中的对象属性,当range是对象数组时,告诉 picker 显示哪个属性的值作为选项文本。

  • 但这里range数字数组,不是对象数组。使用range-key="$index"意味着告诉 picker 显示数组的索引($index代表当前项的索引,从0开始)作为选项文本。因此,实际显示的选项会是“0”和“1”,而不是你期望的“1”和“2”。

  • 这是错误用法。如果你想让 picker 显示数字本身,应该删除range-key属性,或者将range-key设置为$value(但$value不是标准写法)。对于数字数组,通常不写range-key,picker 会自动显示数组元素的值。所以你应当删除range-key="$index",或者修改range为对象数组。


5. 内部显示的<view>

vue

<view class="picker">闹钟编号:{{ alarmNumber }}</view>
  • 这个<view>是 picker 的触发器——用户点击它就会弹出选择器。

  • 它显示文本“闹钟编号: ”加上当前选中的数字(alarmNumber)。

  • alarmNumberdata中的一个变量,初始值默认为 1(或你设置的),当用户选择新值时,通过onAlarmNumberChange方法更新alarmNumber


6. 如何修正range-key

如果你的意图是让用户从 1 和 2 中选择,最简单的方法是删除range-key,并确保range是数字数组,这样 picker 会直接显示 1 和 2。

修改为:

vue

<picker @change="onAlarmNumberChange" :range="[1,2]"> <view class="picker">闹钟编号: {{ alarmNumber }}</view> </picker>

如果你希望选项更多(比如 1~5),只需修改range的值,如:range="[1,2,3,4,5]"


7.onAlarmNumberChange方法示例

你已经在 methods 中定义了:

javascript

onAlarmNumberChange(e) { this.alarmNumber = parseInt(e.detail.value) + 1; // picker 索引从0开始,所以加1 }
  • e.detail.value是用户所选选项的索引(0 表示第一个选项)。

  • 由于你的选项是 1 和 2,索引 0 对应值 1,索引 1 对应值 2。所以需要将索引加 1 来得到真正的值,并赋给alarmNumber


总结

  • 当前代码的问题在于range-key="$index"导致 picker 显示索引而非数字,应该删除它。

  • 其他部分是正确的:事件绑定、变量更新、显示逻辑都合理。

修正后,用户点击“闹钟编号: X”,会弹出选择器显示 1 和 2,选择后数字会更新。

Q:range-key和“$index”突然出现了,也不说是什么意思还有用来干什么的吗?

A:

1.picker的两种模式

  • range是简单数组(如数字数组[1,2]或字符串数组['选项1','选项2']
    picker 默认会直接显示数组元素的值(即显示12)。此时不需要range-key属性。

  • range是对象数组(如[{ id:1, name:'一号' }, { id:2, name:'二号' }]
    你无法直接显示对象,需要告诉 picker 用对象的哪个属性作为显示文本。range-key就是用来指定这个属性名的。例如range-key="name"会让 picker 显示'一号''二号'


2. 你的代码range-key="$index"是什么?

  • $index是 picker 组件内部的一个特殊变量,代表当前选项在数组中的索引(0、1、2……)。

  • 当你写range-key="$index",意味着你让picker 把每个选项对应的索引作为显示文本。所以显示出来的是01,而不是12

  • 由于你的range[1,2](数字数组),根本不需要range-key,但如果你强行指定range-key="$index",就会覆盖默认行为,显示索引而非元素本身。


3. 正确做法

删除range-key="$index",让 picker 使用默认行为,直接显示数组元素的值。

vue

<picker @change="onAlarmNumberChange" :range="[1,2]"> <view class="picker">闹钟编号: {{ alarmNumber }}</view> </picker>

此时选择器显示12e.detail.value是所选索引(0 或 1),在onAlarmNumberChange中通过parseInt(e.detail.value) + 1就能得到正确的数字。


4. 如果你希望range是对象数组(扩展性更好)

你可以写成:

vue

<picker @change="onAlarmNumberChange" :range="alarmOptions" range-key="label"> <view class="picker">闹钟编号: {{ alarmNumber }}</view> </picker>

javascript

data() { return { alarmOptions: [ { value: 1, label: '闹钟1' }, { value: 2, label: '闹钟2' } ], alarmNumber: 1 }; }, methods: { onAlarmNumberChange(e) { this.alarmNumber = this.alarmOptions[e.detail.value].value; } }

这样显示的是“闹钟1”、“闹钟2”,但实际使用的值是数字 1、2。这种方法更清晰,但当前你不需要改,用简单数组即可。


总结

  • range-key只在range是对象数组时使用,用来指定显示对象的哪个属性。

  • $index不是你在数据里定义的变量,而是 picker 内部用来表示索引的占位符,一般不直接用在range-key里。

  • 对于你的数字数组[1,2],直接去掉range-key就能正常工作。

Q:说说这里。

<view class="row"> <label>开关:</label> <switch :checked="alarmOn" @change="alarmOn = $event.detail.value" /> </view>

A:

  • <view class="row">
    一个容器,用于将“开关:”标签和开关组件放在同一行。class="row"在样式中通常被设置为display: flex;等布局属性,让标签和开关水平排列并垂直居中。

  • <label>开关:</label>
    普通文本标签,显示“开关:”,用于说明后面组件的用途。

  • <switch :checked="alarmOn" @change="alarmOn = $event.detail.value" />

    • :checked="alarmOn"动态绑定checked属性,值为数据中的alarmOn(布尔值),决定开关的初始状态。

    • @change:监听开关状态变化事件。当用户拨动开关时,触发change事件,事件对象$event中包含新状态detail.valuetruefalse)。这里直接将其赋值给alarmOn,实现了双向数据绑定——开关改变,alarmOn变量自动更新。

    • 注意<switch>是 uni-app 的内置组件,渲染为移动端原生风格的开关。

整个区块的作用是让用户选择闹钟是“启用”(ON)还是“禁用”(OFF),选择结果实时保存在alarmOn中,供后续发送命令时使用。

Q:@change="alarmOn = $event.detail.value",这里event这一串不知哪来的。

A:

@change="alarmOn = $event.detail.value"中的$event是什么?

在 Vue/uni-app 中,$event是事件回调的默认参数名当你在模板中写@change="alarmOn = $event.detail.value",其实是在说:

  • @change监听了<switch>组件的change事件。

  • 当用户拨动开关时,系统会调用你写的这个表达式,并自动将一个事件对象作为参数传入,这个参数在模板中固定用$event来表示。

  • 事件对象的结构由组件决定。对于<switch>组件,$event.detail.value就是开关的新状态(truefalse)。

等效写法:你也可以把逻辑写成一个方法

vue

<switch @change="onSwitchChange" />

javascript

onSwitchChange(e) { this.alarmOn = e.detail.value; }

模板中的$event就是这种方法的参数。用内联表达式时,$event是框架预留的占位符。

Q:那event.detail又是?咋不是event.value?

A:

为什么是$event.detail.value而不是$event.value

在 uni-app 中,组件(尤其是表单组件)的自定义事件,其事件对象的结构是框架统一定义的。对于<switch>组件的change事件,触发时传入的事件对象格式为:

javascript

{ type: 'change', detail: { value: true/false // 开关的新状态 } }

因此,在模板中获取新状态必须写$event.detail.value。这不是你选的,是 uni-app 的设计决定。为什么这样设计?

  • detail字段用来封装组件特定的数据,避免与标准 DOM 事件的属性混淆。

  • 不同组件的change事件可能在detail中携带不同的信息(比如<picker>detail.value是选中的索引)。

如果你想验证,可以在方法里打印e,结构一目了然。这和我们之前从蓝牙 API 里取res.devices是同样的道理——文档怎么规定,你就怎么取

http://www.jsqmd.com/news/508184/

相关文章:

  • 手把手教你用DeepSeek-OCR-2:表格、标题、段落精准识别全攻略
  • 编译参数选错=白写十年嵌入式代码,这3个-march/-mtune/-mcpu组合正在 silently 破坏你的实时性,你中招了吗?
  • Simulink新手必看:5分钟搞定模拟信号数字化处理(附完整MATLAB代码)
  • Step3-VL-10B-Base模型内网穿透方案:安全访问本地部署的AI服务
  • Qwen3-ASR语音识别5分钟快速部署:30+语言支持一键搞定
  • Granite TimeSeries FlowState R1快速调用实战:10分钟完成你的第一个预测项目
  • kill-doc用户脚本:自动化文档下载解决方案
  • 新手必看!李慕婉-仙逆-造相Z-Turbo完整使用指南:生成、保存、分享全流程
  • SGLang-v0.5.6部署指南:快速配置高性能大模型推理环境
  • RTW89驱动完全指南:从WiFi设备识别失败到高速网络体验的实战之路
  • 网易云音乐下载器完整指南:三步快速构建个人高品质音乐库
  • 网易云音乐歌单数据分析:用Python和Matplotlib揭秘热门歌单的秘密
  • Youtu-VL-4B-Instruct效果展示:复杂场景下多物体计数准确率98.2%实测截图集
  • Qwen3-32B部署保姆级教程:基于RTX4090D 24G显存的开源大模型镜像免配置指南
  • 从tensors内存共享到磁盘重复:深入理解transformers库中的checkpoint保存机制
  • 2026发泥十大热门款盘点,男士造型选购全攻略 - 品牌测评鉴赏家
  • Dify + OpenAI/Gemini/Qwen三模态Judge协同评估方案(独家披露某金融大模型团队内部SOP文档节选)
  • 互联网广告创意分析:用NLP-StructBERT聚类相似广告文案
  • OpenSpeedy架构深度解析:用户态Hook技术在游戏变速中的创新实践
  • 零基础玩转Wan2.2-T2V-A5B:ChatGPT辅助提示词编写实战
  • 实测DeepSeek-OCR-2:Flash Attention 2极速推理,GPU显存优化效果展示
  • ThinkPad T14s 升级Ubuntu22避坑指南:从驱动兼容到挂起优化
  • 无线智能小车的软件设计与实现(ZigBee)
  • 油头救星✅5款实测封神免洗蓬松水!新手也能焊住高颅顶 - 品牌测评鉴赏家
  • HDLbits进阶实战:解锁Verilog高阶特性与高效设计技巧
  • 扎根南开科创沃土,喵飞AI以智能直播赋能企业数字化蝶变
  • Retinaface+CurricularFace镜像教程:快速搭建人脸识别系统
  • YOLO26镜像快速部署:预装权重文件,无需额外下载
  • 避坑指南:Windows 11安装xray常见错误及解决方案(含证书配置)
  • Turbo Intruder:高性能HTTP安全测试工具全攻略