在现代 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() 对密码加密,防止明文入库 |
非空判断 | 避免用户传入空值覆盖数据库 |
邮箱唯一匹配 | 通过邮箱定位用户记录,保证修改的是本人数据 |