pinyin-pro
一个专业的 JavaScript 中文转拼音的库,具备多音字识别准确、体积轻量、性能优异、功能丰富等特点。
1 其功能具体如下:
2 支持拼音/声母/韵母/首字母/音调/全部信息
3 支持人名姓氏模式
4 支持文本和拼音匹配
5 支持自定义拼音
6 支持获取带拼音汉字的 HTML 字符串
7 支持获取汉字的所有拼音
8 支持拼音输入转换
9 极致的性能和极高的拼音识别准确率
使用场景包括但不限于{
上传文件不支持中文名称可以使用pinyin库进行转换
}
安装
//npm
npm install pinyin-pro --save
//yarn
yarn add pinyin-pro
(如果新版本与项目不兼容 可安装文档版本(3.15.1))
//npm
npm install pinyin-pro@3.15.1 --save
//yarn
yarn add pinyin-pro@3.15.1
单页简单使用
import { pinyin } from 'pinyin-pro';
// 获取字符串格式拼音
pinyin('汉语拼音'); // 'hàn yǔ pīn yīn'
// 获取数组格式拼音
pinyin('汉语拼音', { type: 'array' }); // ["hàn", "yǔ", "pīn", "yīn"]
// 获取不带音调数组格式拼音
pinyin('汉语拼音', { toneType: 'none' }); // "han yu pin yin"
// 获取不带音调数组格式拼音
pinyin('汉语拼音', { toneType: 'none', type: 'array' }); // ["han", "yu", "pin", "yin"]
// 音调以数组形式显示
pinyin('汉语拼音', { toneType: 'num' }); // "han4 yu3 pin1 yin1"
// 自动识别多音字
pinyin('睡着了'); // "shuì zháo le"
封装使用
utils-pinyin.js
创建一个utils文件夹-pinyin
如下所示:
import { pinyin } from 'pinyin-pro';
/**
* 将中文文字转换为拼音,并去除特殊字符
* @param text - 需要转换的文字
* @returns 转换后的拼音字符串,仅包含字母和数字
*/
export function convertToPinyinAndRemoveSpecialChars(text) {
// 使用 pinyin-pro 将文本转换为拼音,不包含声调且全部小写
const pinyinText = pinyin(text, {
pattern: 'lower', // 使用小写
toneType: 'none', // 不包含声调
type: 'array' // 返回数组格式
}).join(' '); // 默认用空格分隔
// 去除非字母和数字的字符
const cleanedText = pinyinText.replace(/[^a-z0-9\s]/gi, '');
// 移除多余的空格
return cleanedText.trim().replace(/\s+/g, ' ');
}
页面使用
<template>
<div>{{ convertedText }}</div>
</template>
<script>
import { convertToPinyinAndRemoveSpecialChars } from '@/utils/pinyin'; // 确保路径正确
export default {
data() {
return {
text: '你好 世界!?',
};
},
computed: {
convertedText() {
return convertToPinyinAndRemoveSpecialChars(this.text);
}
}
};
</script>
<style>
/* 你的CSS样式 */
</style>
上传文件限制中文(封装使用)
上传文件为手动上传 不去请求服务
首先上传文件不能上传带中文的名称 根据pinyin-pro库转写中文变成字母 达到想要的结果
下面是封装的方法-如下所示:
utils-pinyin.js
pinyin-pro库封装中文转字母格式功能
import { pinyin } from 'pinyin-pro';
/* 提取上传文件带中文名称转成字母格式方法
并且去掉特殊字符
*/
export function convertFileNameToPinyin(file: File): File {
// 提取文件扩展名
const extension = file.name.split('.').pop();
if (!extension) {
console.error('File has no extension:', file.name);
return file; // 如果没有扩展名,直接返回原文件对象
}
// 去掉文件扩展名后的名字部分
const nameWithoutExtension = file.name.replace(new RegExp(`.${extension}$`), '');
console.log('Original name without extension:', nameWithoutExtension);
// 将名字部分转换为拼音
let pinyinName = '';
try {
pinyinName = pinyin(nameWithoutExtension, { toneType: 'none' }).toLowerCase().replace(/\s+/g, '-');
console.log('Converted to pinyin:', pinyinName);
} catch (error) {
console.error('Error converting filename to pinyin:', error);
pinyinName = nameWithoutExtension; // 如果转换失败,则保留原名
}
// 定义要移除的特殊字符列表
const specialCharsToRemove = [
'\\', '/', ':', '*','(', ')', '?', '"', '<', '>', '|', '$', '+', '{', '}', '[', ']', '(', ')'
];
// 移除所有特殊字符,包括括号和其他非法字符
let cleanedPinyinName = pinyinName;
specialCharsToRemove.forEach(char => {
cleanedPinyinName = cleanedPinyinName.split(char).join('');
});
console.log('Cleaned pinyin name:', cleanedPinyinName);
// 创建新的带有拼音文件名的Blob对象
const newFile = new File([file], `${cleanedPinyinName}.${extension}`, { type: file.type });
console.log('New file object:', newFile);
return newFile;
}
封装上传的组件
before-upload设置手动上传 不去请求服务
需求:
增添的时候只需要带传入文件链接的入参 不去请求服务
components-FileUploader.vue
<template>
<div>
<el-upload
ref="upload"
:action="uploadUrl"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:auto-upload="false"
:limit="limit"
:disabled="disabled"
multiple
:accept="'.wav'"
:file-list="fileList"
:on-exceed="handleExceed"
:http-request="customUpload"
>
<el-button type="primary">选择文件</el-button>
<template #tip>
<div style="display: flex">
<div class="el-upload__tip">{{ tip }}</div>
<el-button size="small" style="margin: 11px 6px;" @click="submitUpload" type="primary">
<el-icon><Check /></el-icon>
</el-button>
</div>
</template>
</el-upload>
<!-- <el-button @click="submitUpload" style="margin-top: 20px;">保存</el-button> -->
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from "vue";
import { ElMessage } from "element-plus";
import { convertFileNameToPinyin } from "../utils/pinyin";
import { Edit, Search, Check, CirclePlus } from "@element-plus/icons-vue";
export default defineComponent({
name: "FileUploader",
components: {
Edit,
Search,
Check, // 注册 Plus 图标组件
CirclePlus, // 注册 CirclePlus 图标组件
},
props: {
uploadUrl: { type: String, required: true },
autoUpload: { type: Boolean, default: false },
fileList: { type: Array, default: () => [] },
limit: { type: Number, default: 5 },
disabled: { type: Boolean, default: false },
tip: {
type: String,
default: "只能上传音视频文件(wav格式),且不超过 50MB",
},
},
emits: ["uploaded", "removed", "Preview"],
setup(props, { emit }) {
const upload = ref(null);
// 模拟上传的方法
const customUpload = (options) => {
const file = options.file;
// 在模拟上传前转换文件名
const convertedFile = convertFileNameToPinyin(file);
setTimeout(() => {
const response = { success: true, message: "模拟上传" };
emit("uploaded", response, convertedFile); // 使用转换后的文件对象
ElMessage.success("文件保存成功");
}, 1000);
};
// 手动触发上传
const submitUpload = () => {
if (upload.value) {
upload.value.submit(); // 触发所有选中的文件上传
}
};
// 假设这是你在 FileUploader.vue 中处理预览的方法
const handlePreview = (file) => {
// 如果 file 是一个有效的 File 对象,则发射 Preview 事件
if (file.raw && file.raw instanceof File) {
emit("Preview", file.raw); // 发射原始文件对象
} else {
//证明是编辑的状态(接口返回 发射file)
emit("Preview", file);
console.warn("Invalid file object for preview:", file);
}
};
const handleRemove = (file, fileList) => {
emit("removed", file, fileList);
};
const beforeUpload = (file) => {
//自动上传才会生效(当前手动上传)
const isAcceptableType = [
//限制wav格式
"audio/mpeg",
"audio/wav",
"audio/ogg",
"video/mp4",
"video/webm",
"video/quicktime",
].includes(file.type);
const isLt50M = file.size / 1024 / 1024 < 50;
if (!isAcceptableType) {
ElMessage.error("上传文件只能是音视频格式!");
}
if (!isLt50M) {
ElMessage.error("上传文件大小不能超过 50MB!");
}
return isAcceptableType && isLt50M;
};
const handleExceed = (files, fileList) => {
ElMessage.warning(
`当前限制选择 ${props.limit} 个文件,本次选择了 ${
files.length
} 个文件,共选择了 ${files.length + fileList.length} 个文件`
);
};
watch(
() => props.fileList,
(newVal) => {
if (Array.isArray(newVal)) {
if (upload.value) {
upload.value.clearFiles();
newVal.forEach((file) => {
// el-upload 并没有直接的 handleStart 方法来模拟文件选择。
// 需要预览文件或显示已选文件,需要手动创建 File 对象或使用其他方式。
});
}
} else {
console.warn("fileList prop is not an array:", newVal);
}
},
{ deep: true, immediate: true }
); // 使用 immediate 确保初始化时也触发
return {
upload,
customUpload,
handlePreview,
handleRemove,
beforeUpload,
handleExceed,
submitUpload, // 提交上传函数
};
},
});
</script>
<style lang="scss" scoped>
// :deep(.el-upload) {
// display: flex !important;
// justify-content: space-between !important;
// }
</style>
页面使用
<template>
<el-form :model="fileFrom" ref="formRef" :rules="rules" @submit.prevent>
<el-form-item label="上传文件" prop="fileList" :label-width="formLabelWidth">
<file-uploader
ref="fileUploader"
:upload-url="'#'"
:auto-upload="false"
:file-list="formData.fileList"
:limit="1"
:disabled="false"
@Preview="handPreview"
@uploaded="handleUploaded"
@removed="handleRemoved"
/>
</el-form-item>
</el-form>
</template>
<script lang='ts'>
import { reactive, ref, toRefs } from 'vue';
import { ElForm, ElMessage } from 'element-plus';
import FileUploader from './components/FileUploader.vue';
export default {
name: '',
components: {
FileUploader,
},
setup() {
const formRef = ref<InstanceType<typeof ElForm> | null>(null);
const data = reactive({
formLabelWidth: '140px',
formData: {
fileList: [],
}
});
const handPreview = async (file: File) => {
// 预览
console.log(file);
}
const handleUploaded = (response, uploadFile, fileList) => {
// 处理上传成功的文件
console.log(response, uploadFile, fileList, 'o');
// 更新文件列表或其他操作
};
const handleRemoved = (file, fileList) => {
// 处理移除的文件
console.log('File removed:', file, fileList);
// 更新文件列表或其他操作
};
return {
...toRefs(data),
handleUploaded,
handleRemoved,
formRef,
handPreview,
};
}
};
</script>
<style scoped>
/* 你的CSS样式 */
</style>