Modify the word list component
This commit is contained in:
1
Note.md
1
Note.md
@@ -54,3 +54,4 @@ http://enpuz.com/ 语法分析工具
|
||||
点击句子播放的音乐,需要可暂停
|
||||
|
||||
footer 的输入数统计有问题,当在列表点一个,然后输入错误之后,不会统计到输入数里面(单词和文章的都有问题)
|
||||
|
||||
|
||||
2
components.d.ts
vendored
2
components.d.ts
vendored
@@ -17,6 +17,7 @@ declare module 'vue' {
|
||||
ChapterDetail: typeof import('./src/components/ChapterDetail.vue')['default']
|
||||
ChapterList: typeof import('./src/components/list/ChapterList.vue')['default']
|
||||
Close: typeof import('./src/components/icon/Close.vue')['default']
|
||||
CommonWordList: typeof import('./src/components/list/CommonWordList.vue')['default']
|
||||
DictGroup: typeof import('./src/components/Toolbar/DictGroup.vue')['default']
|
||||
DictList: typeof import('./src/components/list/DictList.vue')['default']
|
||||
DictModal: typeof import('./src/components/Modal/DictModal.vue')['default']
|
||||
@@ -64,6 +65,7 @@ declare module 'vue' {
|
||||
Typing: typeof import('./src/components/Practice/PracticeWord/Typing.vue')['default']
|
||||
TypingArticle: typeof import('./src/components/Practice/PracticeArticle/TypingArticle.vue')['default']
|
||||
TypingWord: typeof import('./src/components/Practice/PracticeWord/TypingWord.vue')['default']
|
||||
VirtualWordList: typeof import('./src/components/list/VirtualWordList.vue')['default']
|
||||
VolumeIcon: typeof import('./src/components/icon/VolumeIcon.vue')['default']
|
||||
VolumeSetting: typeof import('./src/components/Toolbar/VolumeSetting.vue')['default']
|
||||
WordItem: typeof import('./src/components/list/WordItem.vue')['default']
|
||||
|
||||
@@ -38,7 +38,6 @@ watch(store.wrong.originWords, (n) => {
|
||||
store.wrong.chapterWords = [store.wrong.words]
|
||||
})
|
||||
|
||||
useStartKeyboardEventListener()
|
||||
|
||||
async function init() {
|
||||
console.time()
|
||||
@@ -54,6 +53,8 @@ onMounted(() => {
|
||||
init()
|
||||
})
|
||||
|
||||
useStartKeyboardEventListener()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -271,28 +271,44 @@ footer {
|
||||
gap: 20rem;
|
||||
border: 1px solid var(--color-item-border);
|
||||
|
||||
.volume {
|
||||
.left {
|
||||
display: flex;
|
||||
gap: 3rem;
|
||||
flex-direction: column;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5rem;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
.volume, .collect, .easy {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
&:hover {
|
||||
background: var(--color-item-hover);
|
||||
|
||||
.volume {
|
||||
.volume, .collect, .easy {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--color-item-active);
|
||||
|
||||
.volume {
|
||||
color: #E6A23C;
|
||||
}
|
||||
$c: #E6A23C;
|
||||
|
||||
.phonetic, .item-sub-title {
|
||||
color: var(--color-gray) !important;
|
||||
}
|
||||
|
||||
.volume, .collect, .easy, .fill {
|
||||
color: $c;
|
||||
}
|
||||
}
|
||||
|
||||
.item-title {
|
||||
@@ -325,7 +341,6 @@ footer {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
|
||||
.common-title {
|
||||
font-size: 20rem;
|
||||
color: var(--color-font-1);
|
||||
|
||||
@@ -15,9 +15,11 @@ import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import WordList2 from "@/components/list/WordList2.vue";
|
||||
import VirtualWordList from "@/components/list/VirtualWordList.vue";
|
||||
import Modal from "@/components/Modal/Modal.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
|
||||
useDisableEventListener()
|
||||
// useDisableEventListener()
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -233,181 +235,194 @@ watch(() => step, v => {
|
||||
}
|
||||
})
|
||||
|
||||
let show = $ref(false)
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
show = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.editDict, (dict: Dict) => {
|
||||
show = true
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="AddWordDialog" :class="wordFormMode !== FormMode.None && 'add-word-mode'">
|
||||
<Slide :slide-count="2" :step="step">
|
||||
<div class="page dict-list-page">
|
||||
<header>
|
||||
<div class="title">
|
||||
我的词典
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="list">
|
||||
<DictList
|
||||
@add="step = 1;isAddDict = true"
|
||||
@selectDict="selectDict"
|
||||
:list="dictList"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page add-page">
|
||||
<header>
|
||||
<div class="left" @click.stop="step = 0">
|
||||
<Icon icon="octicon:arrow-left-24" class="go" width="20"/>
|
||||
<Modal
|
||||
:header="false"
|
||||
v-model="show"
|
||||
:show-close="false">
|
||||
<div id="AddWordDialog" :class="wordFormMode !== FormMode.None && 'add-word-mode'">
|
||||
<Slide :slide-count="2" :step="step">
|
||||
<div class="page dict-list-page">
|
||||
<header>
|
||||
<div class="title">
|
||||
词典详情
|
||||
我的词典
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="list">
|
||||
<DictList
|
||||
@add="step = 1;isAddDict = true"
|
||||
@selectDict="selectDict"
|
||||
:list="dictList"/>
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="detail" v-if="!isAddDict">
|
||||
<div class="dict">
|
||||
<div class="info">
|
||||
<div class="name">{{ store.editDict.name }}</div>
|
||||
<div class="desc">{{ store.editDict.description }}</div>
|
||||
<div class="more-info">
|
||||
<div class="item">词汇量:{{ store.editDict.originWords.length }}词</div>
|
||||
<div class="item">创建日期:-</div>
|
||||
<div class="item">花费时间:-</div>
|
||||
<div class="item">累积错误:-</div>
|
||||
</div>
|
||||
<div class="page add-page">
|
||||
<header>
|
||||
<div class="left" @click.stop="step = 0">
|
||||
<Icon icon="octicon:arrow-left-24" class="go" width="20"/>
|
||||
<div class="title">
|
||||
词典详情
|
||||
</div>
|
||||
<BaseIcon
|
||||
class-name="edit-icon"
|
||||
icon="tabler:edit"
|
||||
@click='editDict'
|
||||
/>
|
||||
</div>
|
||||
<div class="add" v-if="wordFormMode !== FormMode.None">
|
||||
<div class="common-title">{{ wordFormMode === FormMode.Add ? '添加' : '修改' }}单词</div>
|
||||
<el-form
|
||||
class="form"
|
||||
ref="wordFormRef"
|
||||
:rules="wordRules"
|
||||
:model="wordForm"
|
||||
label-width="140rem">
|
||||
<el-form-item label="单词" prop="name">
|
||||
<el-input v-model="wordForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译">
|
||||
<el-input v-model="wordForm.trans"
|
||||
placeholder="多个翻译请换行"
|
||||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音①">
|
||||
<el-input v-model="wordForm.usphone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音②">
|
||||
<el-input v-model="wordForm.ukphone"/>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeWordForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmitWord">{{
|
||||
wordFormMode === FormMode.Add ? '添加' : '保存'
|
||||
}}
|
||||
</el-button>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="detail" v-if="!isAddDict">
|
||||
<div class="dict">
|
||||
<div class="info">
|
||||
<div class="name">{{ store.editDict.name }}</div>
|
||||
<div class="desc">{{ store.editDict.description }}</div>
|
||||
<div class="more-info">
|
||||
<div class="item">词汇量:{{ store.editDict.originWords.length }}词</div>
|
||||
<div class="item">创建日期:-</div>
|
||||
<div class="item">花费时间:-</div>
|
||||
<div class="item">累积错误:-</div>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list-wrapper">
|
||||
<div class="list-header">
|
||||
<div class="name">单词列表</div>
|
||||
<div class="flex-center gap10">
|
||||
<div class="name">{{ wordList.length }}个单词</div>
|
||||
<BaseIcon icon="mi:add"
|
||||
@click='addWord'
|
||||
<BaseIcon
|
||||
v-if="![DictType.collect,DictType.wrong,DictType.simple].includes(store.editDict.type)"
|
||||
class-name="edit-icon"
|
||||
icon="tabler:edit"
|
||||
@click='editDict'
|
||||
/>
|
||||
</div>
|
||||
<div class="add" v-if="wordFormMode !== FormMode.None">
|
||||
<div class="common-title">{{ wordFormMode === FormMode.Add ? '添加' : '修改' }}单词</div>
|
||||
<el-form
|
||||
class="form"
|
||||
ref="wordFormRef"
|
||||
:rules="wordRules"
|
||||
:model="wordForm"
|
||||
label-width="140rem">
|
||||
<el-form-item label="单词" prop="name">
|
||||
<el-input v-model="wordForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译">
|
||||
<el-input v-model="wordForm.trans"
|
||||
placeholder="多个翻译请换行"
|
||||
:autosize="{ minRows: 2, maxRows: 6 }"
|
||||
type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音①">
|
||||
<el-input v-model="wordForm.usphone"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="音标/发音/注音②">
|
||||
<el-input v-model="wordForm.ukphone"/>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeWordForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmitWord">{{
|
||||
wordFormMode === FormMode.Add ? '添加' : '保存'
|
||||
}}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<WordList2
|
||||
ref="wordListRef"
|
||||
v-if="wordList.length"
|
||||
class="word-list"
|
||||
:is-active="true"
|
||||
@change="editWord"
|
||||
:list="wordList"
|
||||
:activeIndex="wordFormMode">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delWord(index)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList2>
|
||||
<Empty v-else/>
|
||||
<div class="list-wrapper">
|
||||
<div class="list-header">
|
||||
<div class="name">单词列表</div>
|
||||
<div class="flex-center gap10">
|
||||
<div class="name">{{ wordList.length }}个单词</div>
|
||||
<BaseIcon icon="mi:add"
|
||||
@click='addWord'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<VirtualWordList
|
||||
ref="wordListRef"
|
||||
v-if="wordList.length"
|
||||
class="word-list"
|
||||
:is-active="true"
|
||||
@change="editWord"
|
||||
:list="wordList"
|
||||
:activeIndex="wordFormMode">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delWord(index)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</VirtualWordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-else>
|
||||
<div class="common-title">{{ dictForm.id ? '修改' : '添加' }}词典</div>
|
||||
<el-form
|
||||
ref="dictFormRef"
|
||||
:rules="dictRules"
|
||||
:model="dictForm"
|
||||
label-width="120rem">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="dictForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="dictForm.description" type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="语言">
|
||||
<el-select v-model="dictForm.language" placeholder="请选择选项">
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
<el-option label="代码" value="code"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译语言">
|
||||
<el-select v-model="dictForm.translateLanguage" placeholder="请选择选项">
|
||||
<!-- <el-option label="通用" value="common"/>-->
|
||||
<el-option label="中文" value="zh-CN"/>
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="category">
|
||||
<el-select v-model="dictForm.category" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in categoryList[dictForm.language]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="tags">
|
||||
<el-select
|
||||
multiple
|
||||
v-model="dictForm.tags" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in tagList[dictForm.category]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="dictForm.type" placeholder="请选择选项">
|
||||
<el-option label="单词" :value="DictType.customWord"/>
|
||||
<el-option label="文章" :value="DictType.customArticle"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeDictForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-else>
|
||||
<div class="common-title">{{ dictForm.id ? '修改' : '添加' }}词典</div>
|
||||
<el-form
|
||||
ref="dictFormRef"
|
||||
:rules="dictRules"
|
||||
:model="dictForm"
|
||||
label-width="120rem">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="dictForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="dictForm.description" type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="语言">
|
||||
<el-select v-model="dictForm.language" placeholder="请选择选项">
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
<el-option label="代码" value="code"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="翻译语言">
|
||||
<el-select v-model="dictForm.translateLanguage" placeholder="请选择选项">
|
||||
<!-- <el-option label="通用" value="common"/>-->
|
||||
<el-option label="中文" value="zh-CN"/>
|
||||
<el-option label="英语" value="en"/>
|
||||
<el-option label="德语" value="de"/>
|
||||
<el-option label="日语" value="ja"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="category">
|
||||
<el-select v-model="dictForm.category" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in categoryList[dictForm.language]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="tags">
|
||||
<el-select
|
||||
multiple
|
||||
v-model="dictForm.tags" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in tagList[dictForm.category]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="类型">
|
||||
<el-select v-model="dictForm.type" placeholder="请选择选项">
|
||||
<el-option label="单词" :value="DictType.customWord"/>
|
||||
<el-option label="文章" :value="DictType.customArticle"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="closeDictForm">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</Slide>
|
||||
</div>
|
||||
</Slide>
|
||||
</div>
|
||||
</Modal>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -15,6 +15,8 @@ import {useWordOptions} from "@/hooks/dict.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import CommonWordList from "@/components/list/CommonWordList.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -38,9 +40,11 @@ function changeIndex(i: number, dict: Dict) {
|
||||
|
||||
const {
|
||||
delWrongWord,
|
||||
delSimpleWord
|
||||
delSimpleWord,
|
||||
toggleWordCollect,
|
||||
} = useWordOptions()
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Transition name="fade">
|
||||
@@ -100,10 +104,18 @@ const {
|
||||
</template>
|
||||
</div>
|
||||
<template v-if="practiceType === DictType.word">
|
||||
<WordList
|
||||
<CommonWordList
|
||||
v-if="store.collect.words.length"
|
||||
class="word-list"
|
||||
:list="store.collect.words"/>
|
||||
:list="store.collect.words">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="toggleWordCollect(word)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</CommonWordList>
|
||||
<Empty v-else/>
|
||||
</template>
|
||||
<template v-else>
|
||||
@@ -129,11 +141,17 @@ const {
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
<CommonWordList
|
||||
class="word-list"
|
||||
:show-del="true"
|
||||
@del="delSimpleWord"
|
||||
:list="store.simple.words"/>
|
||||
:list="store.simple.words">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delSimpleWord(word)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</CommonWordList>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
@@ -151,11 +169,17 @@ const {
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
<CommonWordList
|
||||
class="word-list"
|
||||
:show-del="true"
|
||||
@del="delWrongWord"
|
||||
:list="store.wrong.words"/>
|
||||
:list="store.wrong.words">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
class-name="del"
|
||||
@click="delWrongWord(word)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</CommonWordList>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
|
||||
@@ -158,7 +158,7 @@ onUnmounted(() => {
|
||||
<PracticeWord ref="practiceRef" v-else/>
|
||||
<Footer/>
|
||||
</div>
|
||||
<!-- <AddWordDialog></AddWordDialog>-->
|
||||
<AddWordDialog></AddWordDialog>
|
||||
<DictModal :model-value="runtimeStore.showDictModal" @close="runtimeStore.showDictModal = false"/>
|
||||
<SettingModal v-if="runtimeStore.showSettingModal" @close="runtimeStore.showSettingModal = false"/>
|
||||
<Statistics/>
|
||||
|
||||
@@ -198,7 +198,7 @@ defineExpose({del, showWord, hideWord, play})
|
||||
<VolumeIcon ref="volumeIconRef" :simple="true" :cb="() => playWordAudio(word.name)"/>
|
||||
</Tooltip>
|
||||
</div>
|
||||
<div class="phonetic">{{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}</div>
|
||||
<div class="phonetic">[{{ settingStore.wordSoundType === 'us' ? word.usphone : word.ukphone }}]</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ import WordList from "@/components/list/WordList.vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import CommonWordList from "@/components/list/CommonWordList.vue";
|
||||
|
||||
interface IProps {
|
||||
words: Word[],
|
||||
@@ -172,9 +174,9 @@ useOnKeyboardEventListener(onKeyDown, onKeyUp)
|
||||
|
||||
//TODO 略过忽略的单词上
|
||||
function prev() {
|
||||
if (data.index === 0){
|
||||
if (data.index === 0) {
|
||||
ElMessage.warning('已经是第一个了~')
|
||||
}else {
|
||||
} else {
|
||||
data.index--
|
||||
}
|
||||
}
|
||||
@@ -296,14 +298,39 @@ onUnmounted(() => {
|
||||
{{ data.words.length }}个单词
|
||||
</div>
|
||||
</div>
|
||||
<WordList
|
||||
<CommonWordList
|
||||
class="word-list"
|
||||
:is-active="active"
|
||||
@change="(i:number) => data.index = i"
|
||||
@change="(val:any) => data.index = val.index"
|
||||
:show-word="!settingStore.dictation"
|
||||
:show-translate="settingStore.translate"
|
||||
:list="data.words"
|
||||
:activeIndex="data.index"/>
|
||||
:activeIndex="data.index">
|
||||
<template v-slot="{word,index}">
|
||||
<BaseIcon
|
||||
v-if="!isWordCollect(word)"
|
||||
class-name="collect"
|
||||
@click="toggleWordCollect(word)"
|
||||
title="收藏" icon="ph:star"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class-name="fill"
|
||||
@click="toggleWordCollect(word)"
|
||||
title="取消收藏" icon="ph:star-fill"/>
|
||||
<BaseIcon
|
||||
v-if="!isWordSimple(word)"
|
||||
class-name="easy"
|
||||
@click="toggleWordCollect(word)"
|
||||
title="标记为简单词"
|
||||
icon="material-symbols:check-circle-outline-rounded"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class-name="fill"
|
||||
@click="toggleWordCollect(word)"
|
||||
title="取消标记简单词"
|
||||
icon="material-symbols:check-circle-rounded"/>
|
||||
</template>
|
||||
</CommonWordList>
|
||||
</div>
|
||||
</template>
|
||||
</Panel>
|
||||
|
||||
89
src/components/list/CommonWordList.vue
Normal file
89
src/components/list/CommonWordList.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<script setup lang="ts">
|
||||
import {Word} from "../../types.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {watch} from 'vue'
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
list: Word[],
|
||||
activeIndex?: number,
|
||||
isActive?: boolean
|
||||
showTranslate?: boolean
|
||||
showWord?: boolean
|
||||
}>(), {
|
||||
activeIndex: -1,
|
||||
isActive: false,
|
||||
showTranslate: true,
|
||||
showWord: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
change: [val: { word: Word, index: number }],
|
||||
}>()
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
const listRef: HTMLElement = $ref(null as any)
|
||||
|
||||
function scrollViewToCenter(index: number) {
|
||||
if (index === -1) return
|
||||
listRef.children[index]?.scrollIntoView({block: 'center', behavior: 'smooth'})
|
||||
}
|
||||
|
||||
watch(() => props.activeIndex, (n: any) => {
|
||||
if (settingStore.showPanel) {
|
||||
scrollViewToCenter(n)
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => props.isActive, (n: boolean) => {
|
||||
setTimeout(() => {
|
||||
if (n) scrollViewToCenter(props.activeIndex)
|
||||
}, 300)
|
||||
})
|
||||
|
||||
watch(() => props.list, () => {
|
||||
listRef.scrollTo(0, 0)
|
||||
})
|
||||
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="common-list" ref="listRef">
|
||||
<div class="common-list-item"
|
||||
v-for="(source,index) in list" :key="index"
|
||||
:class="{active:activeIndex === index}"
|
||||
@click="emit('change',{word:source,index})"
|
||||
>
|
||||
<div class="left">
|
||||
<div class="item-title">
|
||||
<span class="word" :class="!showWord && 'text-shadow'">{{ 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 && showTranslate">
|
||||
<div v-for="item in source.trans">{{ item }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<slot :word="source" :index="index"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.common-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15rem;
|
||||
flex: 1;
|
||||
overflow: overlay;
|
||||
padding: 0 var(--space);
|
||||
}
|
||||
</style>
|
||||
@@ -9,20 +9,17 @@ import {watch} from 'vue'
|
||||
const props = withDefaults(defineProps<{
|
||||
list: Word[],
|
||||
activeIndex?: number,
|
||||
showDel?: boolean,
|
||||
isActive?: boolean
|
||||
showTranslate?: boolean
|
||||
showWord?: boolean
|
||||
}>(), {
|
||||
activeIndex: -1,
|
||||
isActive: false,
|
||||
showDel: false,
|
||||
showTranslate: true,
|
||||
showWord: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
del: [val: Word],
|
||||
change: [val: { word: Word, index: number }],
|
||||
}>()
|
||||
|
||||
@@ -74,7 +74,7 @@ const {
|
||||
:isCollect="isWordCollect(word)"
|
||||
@toggle-collect="toggleWordCollect(word)"
|
||||
:is-simple="isWordSimple(word)"
|
||||
@toggle-simple="toggleWordSimple(word)"
|
||||
@toggle-simple="toggleWordCollect(word)"
|
||||
:show-del="showDel"
|
||||
@del="emit('del',word)"
|
||||
>
|
||||
|
||||
@@ -13,4 +13,6 @@ export const EventKey = {
|
||||
repeat: 'repeat',
|
||||
next: 'next',
|
||||
write: 'write',
|
||||
editDict: 'editDict',
|
||||
openMyDictDialog: 'openMyDictDialog',
|
||||
}
|
||||
Reference in New Issue
Block a user