在 Vue 页面中实现文字朗读(Text-to-Speech,TTS)可以通过浏览器的 Web Speech API 实现。以下是完整实现方案:
一、使用 Web Speech API 实现文字朗读
1. 基本实现
<template>
<div>
<!-- 输入要朗读的文字 -->
<textarea v-model="text" rows="3"></textarea>
<!-- 控制按钮 -->
<button @click="speak" :disabled="isSpeaking">朗读</button>
<button @click="pause" :disabled="!isSpeaking">暂停</button>
<button @click="resume" :disabled="isSpeaking">继续</button>
<button @click="stop">停止</button>
<!-- 语音选择(可选) -->
<select v-model="selectedVoice" v-if="voicesLoaded">
<option v-for="voice in voices" :key="voice.name" :value="voice">
{{ voice.name }} ({{ voice.lang }})
</option>
</select>
<!-- 参数调节(可选) -->
<div>
语速: <input type="range" v-model="rate" min="0.5" max="2" step="0.1">
音调: <input type="range" v-model="pitch" min="0" max="2" step="0.1">
音量: <input type="range" v-model="volume" min="0" max="1" step="0.1">
</div>
<!-- 兼容性提示 -->
<div v-if="!isSupported" class="error">
当前浏览器不支持文字朗读功能,请使用 Chrome/Firefox/Edge 最新版
</div>
</div>
</template>
<script>
export default {
data() {
return {
text: "欢迎使用文字朗读功能", // 朗读文本
isSpeaking: false, // 朗读状态
synth: null, // SpeechSynthesis 实例
utterance: null, // 当前朗读实例
voices: [], // 可用语音列表
voicesLoaded: false, // 语音是否加载完成
selectedVoice: null, // 选择的语音
rate: 1, // 语速 (0.1-10)
pitch: 1, // 音调 (0-2)
volume: 1 // 音量 (0-1)
};
},
computed: {
// 检查浏览器支持情况
isSupported() {
return 'speechSynthesis' in window;
}
},
mounted() {
if (this.isSupported) {
this.synth = window.speechSynthesis;
// 加载可用语音列表(需要时间初始化)
this.synth.onvoiceschanged = () => {
this.voices = this.synth.getVoices();
this.voicesLoaded = true;
this.selectedVoice = this.voices.find(v => v.default) || this.voices[0];
};
}
},
methods: {
// 创建新的朗读实例
createUtterance() {
const utterance = new SpeechSynthesisUtterance(this.text);
utterance.voice = this.selectedVoice;
utterance.rate = this.rate;
utterance.pitch = this.pitch;
utterance.volume = this.volume;
// 监听状态变化
utterance.onstart = () => this.isSpeaking = true;
utterance.onend = utterance.onerror = () => {
this.isSpeaking = false;
this.utterance = null;
};
return utterance;
},
// 开始朗读
speak() {
if (!this.text) return;
this.stop(); // 停止当前朗读
this.utterance = this.createUtterance();
this.synth.speak(this.utterance);
},
// 暂停
pause() {
this.synth.pause();
},
// 继续
resume() {
this.synth.resume();
},
// 停止
stop() {
this.synth.cancel();
this.isSpeaking = false;
}
},
beforeDestroy() {
this.stop();
}
};
</script>
<style>
.error {
color: red;
margin-top: 10px;
}
</style>
二、功能特性
- 完整控制:支持开始、暂停、继续、停止操作
- 语音选择:自动加载系统可用语音(需用户交互后生效)
- 参数调节:实时调整语速、音调、音量
- 状态管理:通过
isSpeaking
控制按钮状态 - 兼容性处理:自动检测浏览器支持情况
三、注意事项
-
浏览器兼容性
- 支持 Chrome、Firefox、Edge 等现代浏览器
- 不支持 iOS 的 WKWebView(需特殊处理)
-
用户交互要求
首次调用speak()
必须由用户点击等手势触发(浏览器安全策略) -
语音加载延迟
语音列表 (voices
) 可能在页面加载后需要时间初始化,建议添加加载状态提示 -
移动端限制
安卓设备可能需要用户明确授权麦克风权限(即使只是朗读)
四、高级扩展方案
1. 使用第三方 TTS 服务(如阿里云、Azure)
// 示例:调用阿里云TTS API
async function cloudTTS(text) {
const response = await fetch('https://tts-api.aliyun.com/synthesize', {
method: 'POST',
body: JSON.stringify({ text, voice: 'xiaoyun' })
});
const audioBlob = await response.blob();
const url = URL.createObjectURL(audioBlob);
new Audio(url).play();
}
2. 使用 vue-speech 插件
npm install vue-speech
import VueSpeech from 'vue-speech';
Vue.use(VueSpeech);
// 组件中使用
<vue-speech v-model="text" :voices="voices" />
五、最佳实践建议
- 提供备选方案:对不支持 SpeechSynthesis 的浏览器显示文字提示
- 加载状态反馈:添加 loading 动画等待语音列表加载
- 错误处理:监听
onerror
事件并提示用户 - 持久化配置:使用 localStorage 保存用户选择的语音和参数
根据需求选择原生 API 方案(轻量简单)或第三方服务(支持更多语言和音色)。