易学探索助手-个人记录(十)
在现代 Web 应用中,用户体验的重要性不断上升。近期我完成了两个功能模块 —— 语音播报功能 与 用户信息修改表单,分别增强了界面交互与用户自管理能力。
一、语音播报功能(SpeechSynthesis)
功能特点
-
支持播放、暂停、继续、停止;
-
自动识别当前语音状态(播放中 / 暂停 / 非播放);
-
中文语音支持,速率、语调可调;
-
防止同时播放多条消息。
代码解析
1. 语音播放按钮的显示逻辑
<div class="voice-button-container"v-if="message.text && (typeof message.text === 'string' || message.text.length) && !message.d3Code">
-
确保
message.text
存在且为字符串或数组; -
如果是 SVG 图形类内容(如
d3Code
),不显示播放按钮。
2. 播放控制逻辑
const speakText = (message) => {const text = Array.isArray(message.text) ? message.text.join('') : message.text;if (!text) return;// 如果当前消息正在播放,切换暂停 / 恢复if (message.isSpeaking) {if (speechSynthesis.paused) {speechSynthesis.resume();message.isPaused = false;} else {speechSynthesis.pause();message.isPaused = true;}return;}// 播放其他消息则取消speechSynthesis.cancel();resetAllSpeechStatus();const newUtterance = new SpeechSynthesisUtterance(text);newUtterance.lang = 'zh-CN';newUtterance.rate = 1;newUtterance.pitch = 1;newUtterance.onend = () => {message.isSpeaking = false;message.isPaused = false;currentSpeakingMessageId = null;};message.isSpeaking = true;message.isPaused = false;currentUtterance = newUtterance;currentSpeakingMessageId = message.id;speechSynthesis.speak(newUtterance);
};
-
自动处理字符串数组拼接;
-
speechSynthesis.cancel()
清理可能存在的旧播报; -
播放状态挂载到
message
对象中,避免全局共享状态冲突; -
支持暂停、恢复和播放完毕自动清除状态。
3. 停止播放
const stopSpeech = (message) => {speechSynthesis.cancel();message.isSpeaking = false;message.isPaused = false;currentSpeakingMessageId = null;
};
4. 样式美化
.voice-button {background-color: #f0f0f0;border: 1px solid #ccc;border-radius: 6px;padding: 4px 10px;cursor: pointer;
}
.voice-button:hover {background-color: #e8e8e8;
}
简洁的按钮样式,搭配 hover 效果,让用户操作体验更自然。
5.效果展示
实现亮点
功能点 | 说明 |
---|---|
支持暂停与继续 | 利用 speechSynthesis.pause() 和 resume() |
多条消息互斥 | 播放前调用 speechSynthesis.cancel() |
状态控制 | 通过 message.isSpeaking 与 message.isPaused 控制 UI 交互 |
状态重置 | 播报结束或停止后重置状态,防止按钮状态错乱 |
二、用户信息修改功能
功能实现
-
使用
Element Plus
的el-form
组件构建完整表单; -
实现前端校验(如邮箱格式、密码长度、二次确认);
-
支持密码非必填(可选填);
-
成功后发送异步请求更新用户信息;
-
支持“保存修改”、“重置”、“返回首页”三种操作。
核心代码解析
1. 表单结构
<el-form :model="form" :rules="rules" ref="formRef"><el-form-item label="昵称" prop="nickname"><el-input v-model="form.nickname" /></el-form-item>...
</el-form>
-
v-model
实现双向绑定; -
rules
定义字段级校验规则。
2. 校验逻辑(密码与确认密码)
password: [{validator(rule, value, callback) {if (value && value.length < 6) {callback(new Error('密码长度不能小于6位'));} else {callback();}},trigger: 'blur'}
],
confirmPassword: [{validator(rule, value, callback) {if (form.password && value !== form.password) {callback(new Error('两次密码输入不一致'));} else {callback();}},trigger: 'blur'}
]
支持 密码非必填,但只要填写了就必须满足长度与一致性要求。
3. 表单提交
-
表单校验通过后,发送更新请求;
-
成功或失败均有用户反馈。
4.后端实现
优点总结
措施 | 说明 |
---|---|
密码加密存储 | 使用 passwordEncoder.encode() 对密码加密,防止明文入库 |
非空判断 | 避免用户传入空值覆盖数据库 |
邮箱唯一匹配 | 通过邮箱定位用户记录,保证修改的是本人数据 |