Add custom shortcut key function
This commit is contained in:
60
gulpfile.esm.js
Normal file
60
gulpfile.esm.js
Normal file
@@ -0,0 +1,60 @@
|
||||
import { src, dest } from 'gulp';
|
||||
import through from 'through2';
|
||||
import * as XLSX from 'xlsx';
|
||||
import * as path from 'path';
|
||||
|
||||
function excel2json() {
|
||||
let json = {};
|
||||
const stream = through.obj(function(file, encode, cb) {
|
||||
if (!file.isBuffer()) {
|
||||
return cb(null, file);
|
||||
}
|
||||
const workbook = XLSX.read(file.contents);
|
||||
// const excelData = XLSX.utils.sheet_to_json(
|
||||
// workbook.Sheets[workbook.SheetNames[0]],
|
||||
// );
|
||||
const excelData = XLSX.utils.sheet_to_json(workbook.Sheets['Sheet1']);
|
||||
json = excelData.reduce((result, current) => {
|
||||
let newCurrent = {};
|
||||
for (var key in current) {
|
||||
var letterPattern = /[a-zA-Z]+/g;
|
||||
var matches = key.match(letterPattern);
|
||||
if (matches) {
|
||||
var string = matches[0].toLocaleLowerCase();
|
||||
newCurrent[string] = current[key].replace(/@{/g, '{');
|
||||
}
|
||||
}
|
||||
result[newCurrent.key] = {};
|
||||
result[newCurrent.key]['en'] = newCurrent.en || '';
|
||||
result[newCurrent.key]['zh'] = newCurrent.zh || '';
|
||||
result[newCurrent.key]['id'] = newCurrent.id || '';
|
||||
result[newCurrent.key]['tw'] = newCurrent.tw || '';
|
||||
result[newCurrent.key]['th'] = newCurrent.th || '';
|
||||
result[newCurrent.key]['ru'] = newCurrent.ru || '';
|
||||
result[newCurrent.key]['vi'] = newCurrent.vi || '';
|
||||
result[newCurrent.key]['es'] = newCurrent.es || '';
|
||||
result[newCurrent.key]['pt'] = newCurrent.pt || '';
|
||||
|
||||
result[newCurrent.key]['ja'] = newCurrent.ja || '';
|
||||
result[newCurrent.key]['uk'] = newCurrent.uk || '';
|
||||
result[newCurrent.key]['ko'] = newCurrent.ko || '';
|
||||
result[newCurrent.key]['de'] = newCurrent.de || '';
|
||||
result[newCurrent.key]['fr'] = newCurrent.fr || '';
|
||||
return result;
|
||||
}, json);
|
||||
file.contents = Buffer.from(JSON.stringify(json, null, '\t'));
|
||||
file.path = path.join(file.base, 'i18n.json');
|
||||
cb(null, file);
|
||||
});
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
// 将翻译好的excel写入json
|
||||
function i18nwrite() {
|
||||
return src(['./src/locales/i18n.xlsx'])
|
||||
.pipe(excel2json())
|
||||
.pipe(dest('src/locales'));
|
||||
}
|
||||
|
||||
export { i18nwrite };
|
||||
@@ -12,7 +12,8 @@
|
||||
"commit": "git-cz",
|
||||
"prepare": "husky install",
|
||||
"test": "",
|
||||
"deploy": "push-dir --dir=dist --branch=gh-pages --cleanup"
|
||||
"deploy": "push-dir --dir=dist --branch=gh-pages --cleanup",
|
||||
"i18n:write": "gulp i18nwrite"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentranslate/baidu": "^1.4.2",
|
||||
@@ -55,7 +56,10 @@
|
||||
"unplugin-auto-import": "^0.16.6",
|
||||
"unplugin-vue-components": "^0.25.2",
|
||||
"vite": "^4.4.5",
|
||||
"vue-tsc": "^1.8.5"
|
||||
"vue-tsc": "^1.8.5",
|
||||
"esm": "^3.2.25",
|
||||
"gulp": "^4.0.2",
|
||||
"xlsx": "^0.18.5"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
||||
2006
pnpm-lock.yaml
generated
2006
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -49,13 +49,13 @@ defineEmits<{
|
||||
v-if="!isSimple"
|
||||
class-name="easy"
|
||||
@click="$emit('toggleSimple')"
|
||||
title="标记为简单词(快捷键:`)"
|
||||
title="标记为简单词"
|
||||
icon="material-symbols:check-circle-outline-rounded"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class-name="fill"
|
||||
@click="$emit('toggleSimple')"
|
||||
title="取消标记简单词(快捷键:`)"
|
||||
title="取消标记简单词"
|
||||
icon="material-symbols:check-circle-rounded"/>
|
||||
|
||||
</template>
|
||||
|
||||
@@ -200,6 +200,7 @@ defineExpose({del, showWord, hideWord, play})
|
||||
}
|
||||
|
||||
.phonetic {
|
||||
margin-top: 5rem;
|
||||
font-family: $word-font-family;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,13 +25,19 @@ onMounted(() => {
|
||||
statModalIsOpen = true
|
||||
store.saveStatistics(stat)
|
||||
})
|
||||
|
||||
const close = () => {
|
||||
statModalIsOpen = false
|
||||
}
|
||||
|
||||
emitter.on(ShortcutKey.NextChapter, close)
|
||||
emitter.on(ShortcutKey.RepeatChapter, close)
|
||||
emitter.on(ShortcutKey.DictationChapter, close)
|
||||
})
|
||||
|
||||
let optionType = $ref('')
|
||||
|
||||
function options(emitType: 'write' | 'repeat' | 'next') {
|
||||
statModalIsOpen = false
|
||||
optionType = emitType
|
||||
emitter.emit(EventKey[emitType])
|
||||
}
|
||||
|
||||
@@ -41,20 +47,12 @@ const isEnd = $computed(() => {
|
||||
store.currentDict.chapterIndex === store.currentDict.chapterWords.length - 1
|
||||
})
|
||||
|
||||
function onClose() {
|
||||
if (!optionType) {
|
||||
options('next')
|
||||
}
|
||||
optionType = ''
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
:header="false"
|
||||
v-model="statModalIsOpen"
|
||||
@close="onClose">
|
||||
v-model="statModalIsOpen">
|
||||
<div class="statistics">
|
||||
<header>
|
||||
<div class="title">{{ store.currentDict.name }}</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ import {cloneDeep} from "lodash-es";
|
||||
import {DefaultShortcutKeyMap} from "@/types.ts";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
|
||||
const tabIndex = $ref(2)
|
||||
const tabIndex = $ref(0)
|
||||
const settingStore = useSettingStore()
|
||||
//@ts-ignore
|
||||
const gitLastCommitHash = ref(LATEST_COMMIT_HASH);
|
||||
@@ -43,17 +43,22 @@ useEventListener('keydown', (e: KeyboardEvent) => {
|
||||
// }
|
||||
|
||||
if (editShortcutKey) {
|
||||
for (const [k, v] of Object.entries(settingStore.shortcutKeyMap)) {
|
||||
if (v === shortcutKey && k !== editShortcutKey) {
|
||||
settingStore.shortcutKeyMap[editShortcutKey] = DefaultShortcutKeyMap[editShortcutKey]
|
||||
return ElMessage.warning('快捷键重复!')
|
||||
if (shortcutKey === 'Delete') {
|
||||
settingStore.shortcutKeyMap[editShortcutKey] = ''
|
||||
} else {
|
||||
for (const [k, v] of Object.entries(settingStore.shortcutKeyMap)) {
|
||||
if (v === shortcutKey && k !== editShortcutKey) {
|
||||
settingStore.shortcutKeyMap[editShortcutKey] = DefaultShortcutKeyMap[editShortcutKey]
|
||||
return ElMessage.warning('快捷键重复!')
|
||||
}
|
||||
}
|
||||
settingStore.shortcutKeyMap[editShortcutKey] = shortcutKey
|
||||
}
|
||||
settingStore.shortcutKeyMap[editShortcutKey] = shortcutKey
|
||||
}
|
||||
})
|
||||
|
||||
function resetShortcutKeyMap() {
|
||||
editShortcutKey = ''
|
||||
settingStore.shortcutKeyMap = cloneDeep(DefaultShortcutKeyMap)
|
||||
ElMessage.success('恢复成功')
|
||||
}
|
||||
@@ -77,7 +82,7 @@ function resetShortcutKeyMap() {
|
||||
<span>其他设置</span>
|
||||
</div>
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">
|
||||
<Icon icon="icon-park-outline:setting-config" width="20" color="#0C8CE9"/>
|
||||
<Icon icon="material-symbols:keyboard-outline" width="20" color="#0C8CE9"/>
|
||||
<span>快捷键设置</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -239,7 +244,7 @@ function resetShortcutKeyMap() {
|
||||
<label class="item-title">字体设置(仅可调整单词练习)</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="sut-title">外语字体</label>
|
||||
<label class="sub-title">外语字体</label>
|
||||
<div class="wrapper">
|
||||
<el-slider
|
||||
:min="10"
|
||||
@@ -249,7 +254,7 @@ function resetShortcutKeyMap() {
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="sut-title">中文字体</label>
|
||||
<label class="sub-title">中文字体</label>
|
||||
<div class="wrapper">
|
||||
<el-slider
|
||||
:min="10"
|
||||
@@ -264,7 +269,7 @@ function resetShortcutKeyMap() {
|
||||
<label class="item-title">其他设置</label>
|
||||
</div>
|
||||
<div class="row">
|
||||
<label class="sut-title">切换下一个单词时间</label>
|
||||
<label class="sub-title">切换下一个单词时间</label>
|
||||
<div class="wrapper">
|
||||
<el-input-number v-model="settingStore.waitTimeForChangeWord"
|
||||
:min="6"
|
||||
@@ -275,22 +280,27 @@ function resetShortcutKeyMap() {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="tabIndex === 2">
|
||||
<div class="body" v-if="tabIndex === 2">
|
||||
<div class="row">
|
||||
<label class="item-title">功能</label>
|
||||
<label class="main-title">功能</label>
|
||||
<div class="wrapper">快捷键(点击可修改)</div>
|
||||
</div>
|
||||
<div class="row" v-for="item of Object.entries(settingStore.shortcutKeyMap)">
|
||||
<label class="item-title">{{ item[0] }}</label>
|
||||
<div class="wrapper" @click="editShortcutKey = item[0]">
|
||||
<div class="set-key" v-if="editShortcutKey === item[0]">
|
||||
<input :value="item[1]" readonly type="text" @blur="editShortcutKey = ''">
|
||||
<span @click.stop="editShortcutKey = ''">直接按键盘进行设置</span>
|
||||
<div class="scroll">
|
||||
<div class="row" v-for="item of Object.entries(settingStore.shortcutKeyMap)">
|
||||
<label class="item-title">{{ $t(item[0]) }}</label>
|
||||
<div class="wrapper" @click="editShortcutKey = item[0]">
|
||||
<div class="set-key" v-if="editShortcutKey === item[0]">
|
||||
<input :value="item[1]?item[1]:'未设置快捷键'" readonly type="text" @blur="editShortcutKey = ''">
|
||||
<span @click.stop="editShortcutKey = ''">直接按键盘进行设置</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div v-if="item[1]">{{ item[1] }}</div>
|
||||
<span v-else>未设置快捷键</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else> {{ item[1] }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row footer">
|
||||
<label class="item-title"></label>
|
||||
<div class="wrapper">
|
||||
<BaseButton @click="resetShortcutKeyMap">恢复默认</BaseButton>
|
||||
@@ -350,17 +360,18 @@ function resetShortcutKeyMap() {
|
||||
background: var(--color-header-bg);
|
||||
flex: 1;
|
||||
height: 100%;
|
||||
padding: 0 $space;
|
||||
overflow: auto;
|
||||
padding: 0 $space;
|
||||
|
||||
.row {
|
||||
height: 50rem;
|
||||
height: 40rem;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: $space * 5;
|
||||
|
||||
.wrapper {
|
||||
height: 30rem;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
@@ -368,7 +379,7 @@ function resetShortcutKeyMap() {
|
||||
|
||||
span {
|
||||
text-align: right;
|
||||
width: 30rem;
|
||||
//width: 30rem;
|
||||
font-size: 12rem;
|
||||
color: gray;
|
||||
}
|
||||
@@ -393,22 +404,39 @@ function resetShortcutKeyMap() {
|
||||
}
|
||||
|
||||
.main-title {
|
||||
font-size: 26rem;
|
||||
font-size: 18rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 22rem;
|
||||
font-size: 16rem;
|
||||
}
|
||||
|
||||
.sub-title {
|
||||
font-size: 18rem;
|
||||
font-size: 14rem;
|
||||
}
|
||||
}
|
||||
|
||||
.body {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.scroll {
|
||||
flex: 1;
|
||||
padding-right: 10rem;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-bottom: 20rem;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-bottom: 10rem;
|
||||
font-size: 14rem;
|
||||
font-size: 12rem;
|
||||
}
|
||||
|
||||
.line {
|
||||
|
||||
@@ -82,7 +82,7 @@ watch(() => store.load, n => {
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip
|
||||
:title="`开关默写模式(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.ToggleShowTranslate]})`"
|
||||
:title="`开关默写模式(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.ToggleDictation]})`"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon icon="majesticons:eye-off-line"
|
||||
|
||||
@@ -42,7 +42,7 @@ function save() {
|
||||
<template>
|
||||
<div class="setting" @click.stop="null">
|
||||
<Tooltip
|
||||
:title="`开关释义显示(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.ToggleDictation]})`"
|
||||
:title="`开关释义显示(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.ToggleShowTranslate]})`"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon v-if="settingStore.translate" icon="mdi:translate"
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import VolumeIcon from "@/components/VolumeIcon.vue";
|
||||
import Modal from "@/components/Modal/Modal.vue";
|
||||
import {$ref} from "vue/macros";
|
||||
import {onMounted, onUnmounted} from "vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ListItem from "@/components/ListItem.vue";
|
||||
import {Word} from "@/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
|
||||
let show = $ref(false)
|
||||
let loading = $ref(false)
|
||||
let list = $ref([])
|
||||
let title = $ref('')
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.openWordListModal, (val: any) => {
|
||||
loading = true
|
||||
show = true
|
||||
list = cloneDeep(val.list)
|
||||
title = val.title
|
||||
setTimeout(() => {
|
||||
if (val.translateLanguage === 'common') {
|
||||
console.time()
|
||||
let tempList = cloneDeep(val.list)
|
||||
tempList.map((w: Word) => {
|
||||
if (!w.trans.length) {
|
||||
let res = runtimeStore.translateWordList.find(a => a.name === w.name)
|
||||
if (res) w = Object.assign(w, res)
|
||||
}
|
||||
})
|
||||
list = cloneDeep(tempList)
|
||||
console.timeEnd()
|
||||
}
|
||||
// loading = false
|
||||
}, 500)
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.openWordListModal)
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Modal
|
||||
:title="title"
|
||||
v-model="show">
|
||||
<div class="all-word">
|
||||
<virtual-list class="virtual-list"
|
||||
:keeps="20"
|
||||
data-key="name"
|
||||
v-loading="loading"
|
||||
:data-sources="list"
|
||||
:estimate-size="85"
|
||||
item-class="dict-virtual-item"
|
||||
>
|
||||
<template #={source}>
|
||||
<ListItem
|
||||
class="common-list-item"
|
||||
:show-volume="true">
|
||||
<div class="item-title">
|
||||
<span class="word">{{ source.name }}</span>
|
||||
<span class="phonetic">{{ source.usphone }}</span>
|
||||
<VolumeIcon class="volume" @click="playWordAudio(source.name)"></VolumeIcon>
|
||||
</div>
|
||||
<div class="item-sub-title" v-if="source.trans.length">{{ source.trans.join(';') }}</div>
|
||||
</ListItem>
|
||||
</template>
|
||||
</virtual-list>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "@/assets/css/style";
|
||||
|
||||
.all-word {
|
||||
padding: $space;
|
||||
padding-top: 0;
|
||||
width: 400rem;
|
||||
height: 75vh;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/variable.scss";
|
||||
|
||||
.virtual-list {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.dict-virtual-item {
|
||||
margin-bottom: 15rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
242
src/locales/i18n.json
Normal file
242
src/locales/i18n.json
Normal file
@@ -0,0 +1,242 @@
|
||||
{
|
||||
"ShowWord": {
|
||||
"en": "",
|
||||
"zh": "显示单词",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"EditArticle": {
|
||||
"en": "",
|
||||
"zh": "编辑文章",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"Skip": {
|
||||
"en": "",
|
||||
"zh": "跳过",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleSimple": {
|
||||
"en": "",
|
||||
"zh": "标记/取消简单词",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleCollect": {
|
||||
"en": "",
|
||||
"zh": "添加/取消收藏",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"NextChapter": {
|
||||
"en": "",
|
||||
"zh": "下一章",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"RepeatChapter": {
|
||||
"en": "",
|
||||
"zh": "重复本章",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"DictationChapter": {
|
||||
"en": "",
|
||||
"zh": "默写本章",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"PlaySound": {
|
||||
"en": "",
|
||||
"zh": "播放发音",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleShowTranslate": {
|
||||
"en": "",
|
||||
"zh": "隐藏/显示翻译",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleDictation": {
|
||||
"en": "",
|
||||
"zh": "切换默写",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"OpenSetting": {
|
||||
"en": "",
|
||||
"zh": "打开设置",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"OpenDictDetail": {
|
||||
"en": "",
|
||||
"zh": "打开词典详情",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleTheme": {
|
||||
"en": "",
|
||||
"zh": "切换主题",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
},
|
||||
"ToggleConciseMode": {
|
||||
"en": "",
|
||||
"zh": "切换简洁模式",
|
||||
"id": "",
|
||||
"tw": "",
|
||||
"th": "",
|
||||
"ru": "",
|
||||
"vi": "",
|
||||
"es": "",
|
||||
"pt": "",
|
||||
"ja": "",
|
||||
"uk": "",
|
||||
"ko": "",
|
||||
"de": "",
|
||||
"fr": ""
|
||||
}
|
||||
}
|
||||
BIN
src/locales/i18n.xlsx
Normal file
BIN
src/locales/i18n.xlsx
Normal file
Binary file not shown.
11
src/locales/zh-CN.ts
Normal file
11
src/locales/zh-CN.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import i18nData from './i18n.json';
|
||||
|
||||
const ZH = Object.entries(i18nData).reduce((result, current) => {
|
||||
const [key, value] = current;
|
||||
if (value.zh) {
|
||||
result[key] = value.zh;
|
||||
}
|
||||
return result;
|
||||
}, {} as any);
|
||||
|
||||
export default ZH;
|
||||
10
src/main.ts
10
src/main.ts
@@ -5,7 +5,16 @@ import App from './App.vue'
|
||||
import {createPinia} from "pinia"
|
||||
// import ElementPlus from 'element-plus'
|
||||
import VirtualList from 'vue-virtual-list-v3';
|
||||
import ZH from "@/locales/zh-CN.ts";
|
||||
import {createI18n} from 'vue-i18n'
|
||||
|
||||
const i18n = createI18n({
|
||||
locale: 'zh-CN',
|
||||
fallbackLocale: 'zh-CN',
|
||||
messages: {
|
||||
'zh-CN': ZH
|
||||
},
|
||||
})
|
||||
const pinia = createPinia()
|
||||
// const app = createApp(Mobile)
|
||||
const app = createApp(App)
|
||||
@@ -13,5 +22,6 @@ const app = createApp(App)
|
||||
// app.use(ElementPlus)
|
||||
app.use(pinia)
|
||||
app.use(VirtualList);
|
||||
app.use(i18n)
|
||||
|
||||
app.mount('#app')
|
||||
Reference in New Issue
Block a user