拼音标注
刀刀
1/8/2025
0 字
0 分钟
效果
拼音标注的效果如上图所示,每一个汉字都有自己的拼音标注。想要实现这个效果,首先需要有思路。
思路
结构与样式
在 HTML 中标签
ruby
和rt
可用于实现东亚文字的拼音标注的,该标签目前主流浏览器都能支持,如果想要兼容旧版本的浏览器,则可用rp
标签包裹rt
标签,这样在旧浏览器中会显示为 汉字(拼音) 的形式。html<ruby> 汉 <rt>han</rt> </ruby>
html<ruby> 汉 <rp>(</rp> <rt>han</rt> <rp>)</rp> </ruby>
通过汉字拿到拼音
最笨的方法是自己根据汉字用映射表一一对应保存,需要使用时再获取对应的拼音。但是繁琐且复杂。
有第三方库
pinyin
可实现效果。下面介绍一下它的使用。
pinyin
首先下载第三方依赖:
shell
yarn add pinyin
引入依赖并使用:
js
import pinyin from 'pinyin'
const result = pinyin('弹')
console.log(result)
最终打印结果如下:
js
Array(1) ['dan']
之所以是一个数组,是因为要考虑到其多音字的情况。可为什么他只返回了一个没有返回两个拼音呢?
查看 官方文档 可知,如果想要实现多音字返回多个拼音,需要启用多音字模式。代码修改为下方结构:
js
import pinyin from 'pinyin'
const result = pinyin('弹', {
heteronym: true, // 启用多音字模式
})
console.log(result)
现在输出结果如下:
js
Array(2) ['dan', 'tan']
那么我该拿哪一个读音呢?可以通过传递一串上下文文本内容,并启用分词,就能获取对应的读音了,上下文越多,其读音就越准确。代码再次修改如下:
js
import pinyin from 'pinyin'
const result = pinyin('弹', {
segment: true, // 启用分词,以解决多音字问题。默认不开启,使用 true 开启使用 nodejieba 分词库。
heteronym: true, // 启用多音字模式
})
console.log(result)
打印结果如下:
js
[Array(1),Array(1)] [['zi'], ['dan']]
优化
包体积
这个库由于包含了一本新华字典,因此打包后体积是非常大的,直接打包会有不小的体积压力。放到服务器或许是一个解决方法。
请求时长
如果文本内容过长,一次性传过去等到拼音标注会需要一定时间,因此通过分割并发获取是一个解决方案。
内容
文本内容可能 不一定全是中文,因此需要做判断处理。
业务完整代码
查看代码
js
import pinyin from 'pinyin'
import { computed, ref } from 'vue'
const content = ref('')
const reg = /[\u4e00-\u9fa5]/
function isChinese(char) {
return reg.test(char)
}
const html = computed(() => {
let tags = ''
for(const c of content.value) {
if(isChinese(c)) {
tags += `<ruby>${c}<rp>(</rp><rt>pinyin(c)[0]</rt><rp>)</rp></ruby>`
} else if(c === '\n') {
tags += '<br />'
} else {
tags += c
}
}
})