Vue3 简单实现虚拟Table,展示海量单词.利用WebAPI speechSynthesis,朗读英语单词

目录

本页面完整代码

视频演示

完整的页面代码


利用webapi speechSynthesis帮助我们自动郎读英语单词,可以利用这个API,做一些小说朗读或到账提示。

 

本页面完整代码

用Vue写了一个简单页面,里面还写了一个简单的虚拟Table支持海量数据展示。

视频演示

20231106-223410

完整的页面代码

里面的all.js文件是英语四级的单词,在文章内自行下载,也可以去这里面把JSON下载。

GitHub - cuttlin/Vocabulary-of-CET-4: 英语四级词库

复制里面的代码,放到html文件就可以运行

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script src="all.js"></script><script src="https://cdn.jsdelivr.net/npm/vue@3.3.7/dist/vue.global.js"></script><style>body{background-color: rgba(0,0,0,0.04);}.table-wrapper{background-color: #fff;border: solid 1px #efefef;box-shadow: 0 0px 3px 1px rgba(0,0,0,0.05);}.table-wrapper table {width: 100%;border-spacing: 0;table-layout: fixed;}.header-table th {background-color: #00a674;height: 40px;line-height: 40px;color: rgb(158, 255, 205);}.body-table td {background-color: #fff;text-align: center;}.body-table tr:nth-of-type(n+2) td {border-top: solid 1px rgba(0, 0, 0, 0.06);}.body-table tr:hover td {background-color: #f7f7f7;}.form-wrap{background-color: #fff;margin-bottom: 15px;padding: 15px;box-shadow: 0 1px 3px 1px rgba(0,0,0,0.05);}.table-form {table-layout:fixed;}.table-form th,.table-form td{height: 25px;line-height: 25px;}.table-form th{width: 80px;font-weight: 400;font-size: 14px;text-align: right;}.table-form th::after{content:':';}</style>
</head>
<body><div id="app"></div><template id="tplApp"><div><div class="form-wrap"><table class="table-form"><tr><th>声音</th><td colspan="5"> <select v-model="voice.lang"><option v-for="(v,i) in voices" :key="v.key" :value="v.name">{{v.name}}</option></select></td></tr><tr><th>语速</th><td><input v-model.number="voice.rate" type="number" min="0.1" max="10" step="0.1"/></td><th>音调</th><td><input v-model.number="voice.pitch" type="number" min="0" max="2" step="0.1"/></td><th>音量</th><td><input v-model.number="voice.volume" type="number" min="0" max="1" step="0.1"/></td></tr></table></div></div><Virtual-Table :columns="columns" :data-source="dataSource" row-key="word" :row-height="50" :scroll="scroll"></VirtualTable></div></template><script>const { ref, shallowRef, h, toRaw, renderSlot,reactive,shallowReactive, toRefs, toRef, computed } = Vueconst useVirtualList = (options) => {const { rowHeight, height, dataSource, columnCount = 1 } = optionsconst scrollTop = ref(0)const onScroll = (e) => {scrollTop.value = e.target.scrollTop}const scrollRowIndex = computed(() => {return Math.floor(scrollTop.value / rowHeight.value)})const visibilityRowCount = computed(() => {return Math.ceil(height / rowHeight.value)})const start = computed(() => {return scrollRowIndex.value * columnCount})const end = computed(() => {return start.value + visibilityRowCount.value * columnCount})const rowCount = computed(() => {return Math.ceil(dataSource.value.length / columnCount)})const scrollHeight = computed(() => {return rowCount.value * rowHeight.value})const currentList = computed(() => {return dataSource.value.slice(start.value, end.value)})const containerProps = computed(() => {return {style: {height: height + 'px',overflowY: 'auto'},onScroll: onScroll}})const invisibleHeight = computed(() => {return (scrollRowIndex.value * rowHeight.value)})const scrollProps = computed(() => {return {style: {height: scrollHeight.value + 'px',paddingTop: invisibleHeight.value + 'px',boxSizing: 'border-box',},}})return [{containerProps,scrollProps,data: currentList}]}const VirtualTable = {props: ['columns', 'rowKey', 'dataSource', 'scroll', 'rowHeight'],setup(props, { slots }) {const rowHeight = toRef(props, 'rowHeight')console.log('rowHeight',rowHeight.value)const scroll = props.scrollconst rowKey = props.rowKeyconst columns = toRef(props, 'columns')const dataSource = toRef(props, 'dataSource')const [{ containerProps, scrollProps, data: currentData }] = useVirtualList({rowKey: rowKey,rowHeight: rowHeight,height: scroll.y,dataSource: dataSource})const renderCol = (columns) => {return h('colgroup', {}, columns.map((c, i) => {return h('col', {key: c.dataIndex || i,style: {...(c.width ? { width: c.width + 'px' } : {})}})}))}const renderHeader = (columns) => {return h('thead', {}, h('tr', {}, columns.map((c, i) => {return h('th', {key: c.dataIndex || i,}, c.title)})))}const renderCell = (columns, dataItem) => {return columns.map((c, i) => {return h('td', {key: c.dataIndex || i,}, c.render ? c.render(dataItem[c.dataIndex], dataItem, i) : dataItem[c.dataIndex])})}const renderRow = (data) => {return h('tbody', {}, data.map((d, i) => {return h('tr', {key: d[rowKey],style: {height: rowHeight.value + 'px'}}, renderCell(columns.value, d))}))}return () => {return h('div', {class: 'table-wrapper'},h('div', {class: 'header-wrap'}, h('table', {class: 'header-table'},renderCol(columns.value),renderHeader(columns.value),)),h('div', {class: 'body-wrap',...containerProps.value}, h('div', {class: 'body-scroll-wrap',...scrollProps.value},h('table', {class: 'body-table'},renderCol(columns.value),renderRow(currentData.value)))))}}}const app = Vue.createApp({template: '#tplApp',components:{VirtualTable:VirtualTable},setup() {const voices=shallowRef([])const voice=shallowReactive({lang:"",pitch:1,rate:1,volume:1})speechSynthesis.addEventListener('voiceschanged', () => {voices.value = speechSynthesis.getVoices()voice.lang=voices.value[0].name})// 语音合成const speak=(word, options = {})=> {return new Promise((resolve, reject) => {const utterThis = new SpeechSynthesisUtterance(word);for (let i = 0; i < voices.value.length; i++) {if ( voices.value[i].name === voice.lang) {utterThis.voice =  voices.value[i];}}utterThis.pitch = voice.pitch;utterThis.rate = voice.rate;utterThis.volume = voice.volumeutterThis.onend = function () {resolve()}utterThis.onerror = (e) => {reject(e)}speechSynthesis.speak(utterThis);})}const columns = shallowRef([{title: '单词',dataIndex: 'word',width: 220},{title: '音标',dataIndex: 'phonetic_symbol',width: 220},{title: '中文意思',dataIndex: 'mean'},{title: '操作',width: 160,render(v, record) {return h('div',{},h('button', {onClick: () => {speak(record.word)}}, '朗读单词'),h('button', {style:{marginLeft:'5px'},onClick: () => {speak(record.mean)}}, '朗读中文'))}}])const dataSource = shallowRef(english_word_cet4_all)return {voices,voice,dataSource,columns:columns,scroll:{y:window.innerHeight-150}}}})app.mount('#app')</script>
</body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/133747.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kubernetes存储-volumes

目录 一、Volumes的简介 二、emptyDir卷 1、emptyDir的引入 2、emptyDir 的使用场景 3、多容器共享volumes 4、emptyDir缺点 三、hostPath卷 1、hostPath卷简介 2、创建hostPath卷 3、NFS共享文件 四、PersistentVolume&#xff08;持久卷&#xff09; 1、PV与P…

免费音效素材,不能错过这6个网站

找免费音效素材&#xff0c;那必须要上这6个网站&#xff0c;热门音效、BGM都能免费下载&#xff0c;赶紧收藏起来。 1、菜鸟图库 https://www.sucai999.com/audio.html?vNTYwNDUx 菜鸟图库是一个综合性素材网站&#xff0c;站内涵盖设计、图片、办公、视频、音效等素材。其中…

数据可视化:动态柱状图

终于来到最后一个数据可视化的文章拿啦~~~ 在这里学习如何绘制动态柱状图 我先整个活 (๑′ᴗ‵๑)&#xff29; Lᵒᵛᵉᵧₒᵤ❤ 什么是pyecharts&#xff1f; 答&#xff1a; Python的Pyecharts软件包。它是一个用于Python数据可视化和图表绘制的库&#xff0c;可用于制作…

力扣最热一百题——盛水最多的容器

终于又来了。我的算法记录的文章已经很久没有更新了。为什么呢&#xff1f; 这段时间都在更新有关python的文章&#xff0c;有对python感兴趣的朋友可以在主页找到。 但是这也并不是主要的原因 在10月5号我发布了我的第一篇博客&#xff0c;大家也可以看见我的每一篇算法博客…

【23真题】易!题源全部定位!带讲解!

今天分享的是23年长春理工大学808的信号与系统试题及解析。 本套试卷难度分析&#xff1a;22年长春理工808考研真题&#xff0c;我也发布过&#xff0c;若有需要&#xff0c;戳这里自取&#xff01;本套试题内容难度中等偏下&#xff0c;题量较少&#xff0c;没有选择填空题&a…

算法学习打卡day41|栈和队列:栈和队列相互实现、括号匹配、逆波兰表达式、滑动窗口最大值问题、求前 K 个高频元素

栈和队列相互实现 力扣题目链接&#xff1a;用栈实现队列、用队列实现栈 题目描述&#xff1a; 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(…

无人机航迹规划:狐猴优化算法LO求解无人机路径规划MATLAB(可以修改起始点,地图可自动生成)

一、狐猴优化算法 狐猴优化算法&#xff08;Lemurs Optimizer&#xff0c;LO&#xff09;由Ammar Kamal Abasi等人于2022年提出&#xff0c;该算法模拟狐猴的跳跃和跳舞行为&#xff0c;具有结构简单&#xff0c;思路新颖&#xff0c;搜索速度快等优势。狐猴优化算法&#xff…

JavaScript 进阶问题列表,巩固自己的知识。

不定时更新 JavaScript 进阶问题列表 从基础到进阶&#xff0c;测试你有多了解 JavaScript&#xff0c;刷新你的知识&#xff0c;或者帮助你的 coding 面试&#xff01; &#x1f4aa; &#x1f680; 答案❤️ 1. 输出是什么&#xff1f; function sayHi() {console.log(na…

iSlide2024一款基于PPT的插件工具包含38个设计辅助功能

根据使用者情况表明iSlide 是一款拥有30W素材的PPT高效设计软件&#xff0c;可提高90%工作效率&#xff0c;现全球已有超过1400万使用者&#xff0c;智能排版原创高品模板可商用图形&#xff0c;真正摆脱PPT的束缚&#xff0c;把精力用在该用的地方。我们都明白islide插件功能特…

Vue 3 中,watch 和 watchEffect 的区别

结论先行&#xff1a; watch&#xff1a;需要指明要监听的数据&#xff0c;而且在回调函数中可以获取到属性变化的前后值&#xff1b; 适用于需要精确控制监视范围的情况&#xff1b;也就是需要针对特定数据变化执行操作。 watchEffect&#xff1a;不用指明监听哪个属性&…

python单元测试框架(继承、unittest参数化、断言、测试报告)

一、继承 继承能解决什么问题&#xff1f; unittest每个模块都要用到前提条件以及清理&#xff0c;如果有上百个模块&#xff0c;我们要改域名和浏览器&#xff0c;就会工作量很大特别麻烦&#xff0c;这时我们可以用继承的思想只用改一次 我们可以将前提和清理提出来单独放…

新登录接口独立版变现宝升级版知识付费小程序-多领域素材资源知识变现营销系统

源码简介&#xff1a; 资源入口 点击进入 源码亲测无bug&#xff0c;含前后端源码&#xff0c;非线传&#xff0c;修复最新登录接口 梦想贩卖机升级版&#xff0c;变现宝吸取了资源变现类产品的很多优点&#xff0c;摒弃了那些无关紧要的东西&#xff0c;使本产品在运营和变现…

MVC、MVP、MVVM区别

MVC、MVP、MVVM区别 MVC&#xff08;Model-View-Controller&#xff09; 。是一种设计模式&#xff0c;通常用于组织与应用程序的数据流。它通常包括三个组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&…

TDengine 上榜 BenchCouncil 全球首个开源贡献榜

近日&#xff0c;Bench Council&#xff08;国际测试委员会&#xff09;公布了“世界首个开源贡献榜”&#xff0c;该榜单号称“只以贡献分高下”。值得一提的是&#xff0c;涛思数据、TDengine 上榜 BenchCouncil 发布的开源计算机系统机构榜、成果榜&#xff0c;TDengine 创始…

CDN策略好坏的重要性

CDN加速技术在今天的互联网世界中扮演着至关重要的角色&#xff0c;它可以显著提高网站和应用程序的性能&#xff0c;同时也有助于提供更好的安全性。然而&#xff0c;设定安全策略的好坏对CDN的影响是一个关键的议题&#xff0c;本文将深入探讨这个问题。 CDN&#xff08;内容…

2、Sentinel基本应用限流规则(2)

2.2.1 是什么 Sentinel 是阿里中间件团队开源的&#xff0c;面向分布式服务架构的轻量级高可用流量控制组件&#xff0c;主要以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度来帮助用户保护服务的稳定性。 2.2.2 基本概念 • 资源 (需要被保护的东西…

宝马——使用人工智能制造和驾驶汽车

德国汽车制造商宝马(BMW)每年在全球制造和销售250万台汽车&#xff0c;其品牌包括宝马、MINI和劳斯莱斯。 宝马汽车以其卓越的性能和对新技术的应用而著名&#xff0c;它是道路上最精致的汽车之一&#xff0c;并且和其竞争对手戴姆勒(Daimler)一样&#xff0c;在将自动驾驶汽车…

Redis中的Zset类型

目录 Zset的相关命令 zadd zrange zcard zcount zrevrange zrangebyscore zpopmax bzpopmax zpopmin和bzpopmin zrank zrevrank zscore zrem zremrangebyrank zremrangebyscore 操作集合间的命令 zinterstore和zunionstore 内部编码 Zset的应用场景 Zset表…

独立键盘接口设计(Keil+Proteus)

前言 软件的操作参考这篇博客。 LED数码管的静态显示与动态显示&#xff08;KeilProteus&#xff09;-CSDN博客https://blog.csdn.net/weixin_64066303/article/details/134101256?spm1001.2014.3001.5501实验&#xff1a;用4个独立按键控制8个LED指示灯。 按下k1键&#x…

Mysql进阶-视图篇

介绍 视图&#xff08;View&#xff09;是一种虚拟存在的表。视图中的数据并不在数据库中实际存在&#xff0c;行和列数据来自定义视图的查询中使用的表&#xff0c;并且是在使用视图时动态生成的。 通俗的讲&#xff0c;视图只保存了查询的SQL逻辑&#xff0c;不保存查询结果。…