Override list component
This commit is contained in:
13
components.d.ts
vendored
13
components.d.ts
vendored
@@ -15,10 +15,10 @@ declare module 'vue' {
|
||||
BaseButton: typeof import('./src/components/BaseButton.vue')['default']
|
||||
BaseIcon: typeof import('./src/components/BaseIcon.vue')['default']
|
||||
ChapterDetail: typeof import('./src/components/ChapterDetail.vue')['default']
|
||||
ChapterList: typeof import('./src/components/ChapterList.vue')['default']
|
||||
ChapterList: typeof import('./src/components/list/ChapterList.vue')['default']
|
||||
Close: typeof import('./src/components/icon/Close.vue')['default']
|
||||
DictGroup: typeof import('./src/components/Toolbar/DictGroup.vue')['default']
|
||||
DictList: typeof import('./src/components/DictList.vue')['default']
|
||||
DictList: typeof import('./src/components/list/DictList.vue')['default']
|
||||
DictModal: typeof import('./src/components/Modal/DictModal.vue')['default']
|
||||
EditAbleText: typeof import('./src/components/EditAbleText.vue')['default']
|
||||
EditArticle: typeof import('./src/components/Article/EditArticle.vue')['default']
|
||||
@@ -43,8 +43,9 @@ declare module 'vue' {
|
||||
Footer: typeof import('./src/components/Practice/Footer.vue')['default']
|
||||
IconWrapper: typeof import('./src/components/IconWrapper.vue')['default']
|
||||
Input: typeof import('./src/components/Input.vue')['default']
|
||||
List: typeof import('./src/components/List.vue')['default']
|
||||
ListItem: typeof import('./src/components/ListItem.vue')['default']
|
||||
List: typeof import('./src/components/list/List.vue')['default']
|
||||
ListItem: typeof import('./src/components/list/ListItem.vue')['default']
|
||||
ListItem2: typeof import('./src/components/list/ListItem2.vue')['default']
|
||||
MiniModal: typeof import('./src/components/Modal/MiniModal.vue')['default']
|
||||
Modal: typeof import('./src/components/Modal/Modal.vue')['default']
|
||||
Options: typeof import('./src/components/Practice/Options.vue')['default']
|
||||
@@ -66,7 +67,9 @@ declare module 'vue' {
|
||||
TypingWord: typeof import('./src/components/Practice/PracticeWord/TypingWord.vue')['default']
|
||||
VolumeIcon: typeof import('./src/components/icon/VolumeIcon.vue')['default']
|
||||
VolumeSetting: typeof import('./src/components/Toolbar/VolumeSetting.vue')['default']
|
||||
WordList: typeof import('./src/components/WordList.vue')['default']
|
||||
WordItem: typeof import('./src/components/list/WordItem.vue')['default']
|
||||
WordList: typeof import('./src/components/list/WordList.vue')['default']
|
||||
WordList2: typeof import('./src/components/list/WordList2.vue')['default']
|
||||
WordListModal: typeof import('./src/components/Modal/WordListModal.vue')['default']
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import WordList from "@/components/WordList.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
import DictList from "@/components/DictList.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
@@ -15,7 +15,7 @@ import {FormInstance, FormRules} from "element-plus";
|
||||
import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ChapterList from "@/components/ChapterList.vue";
|
||||
import ChapterList from "@/components/list/ChapterList.vue";
|
||||
|
||||
let data = $ref({
|
||||
words: [],
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Input from "@/components/Input.vue";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {Article, Word} from "@/types.ts";
|
||||
import ListItem from "@/components/ListItem.vue";
|
||||
import ListItem from "@/components/list/ListItem.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {watch} from "vue";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import {cloneDeep} from "lodash-es";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import List from "@/components/List.vue";
|
||||
import List from "@/components/list/List.vue";
|
||||
import {v4 as uuidv4} from 'uuid';
|
||||
import Modal from "@/components/Modal/Modal.vue";
|
||||
import EditArticle from "@/components/Article/EditArticle.vue";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {computed, inject} from "vue"
|
||||
import WordList from "@/components/WordList.vue"
|
||||
import WordList from "@/components/list/WordList.vue"
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
|
||||
const store = useBaseStore()
|
||||
|
||||
@@ -1,29 +1,31 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import WordList from "@/components/WordList.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
import DictList from "@/components/DictList.vue";
|
||||
import DictList from "@/components/list/DictList.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useDisableEventListener} from "@/hooks/event.ts";
|
||||
import {Dict, DictType, languageCategoryOptions, Sort} from "@/types.ts";
|
||||
import {Dict, DictType, languageCategoryOptions, Sort, Word} from "@/types.ts";
|
||||
import {onMounted, reactive, watch} from "vue";
|
||||
import {FormInstance, FormRules} from "element-plus";
|
||||
import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ChapterList from "@/components/ChapterList.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import WordList2 from "@/components/list/WordList2.vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
|
||||
let data = $ref({
|
||||
words: [],
|
||||
index: 0
|
||||
index: -1
|
||||
})
|
||||
|
||||
useDisableEventListener()
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -33,10 +35,8 @@ const emit = defineEmits([
|
||||
'close',
|
||||
])
|
||||
|
||||
let step = $ref(0)
|
||||
let isEdit = $ref(true)
|
||||
|
||||
useDisableEventListener()
|
||||
let step = $ref(1)
|
||||
let isAddDict = $ref(false)
|
||||
|
||||
let list = $computed(() => {
|
||||
return store.myDicts.filter(v => v.type === DictType.customArticle)
|
||||
@@ -48,7 +48,11 @@ let list = $computed(() => {
|
||||
.concat([{name: '',} as any])
|
||||
})
|
||||
|
||||
let form = reactive({
|
||||
let languageCategoryList = []
|
||||
let categoryList = {}
|
||||
let tagList = {}
|
||||
|
||||
let dictForm = reactive({
|
||||
id: '',
|
||||
name: '123',
|
||||
description: '',
|
||||
@@ -57,19 +61,8 @@ let form = reactive({
|
||||
languageCategory: '',
|
||||
language: '',
|
||||
})
|
||||
|
||||
let wordForm = reactive({
|
||||
name: '',
|
||||
trans: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
})
|
||||
|
||||
let languageCategoryList = []
|
||||
let categoryList = {}
|
||||
let tagList = {}
|
||||
const ruleFormRef = $ref<FormInstance>()
|
||||
const rules = reactive<FormRules>({
|
||||
const dictFormRef = $ref<FormInstance>()
|
||||
const dictRules = reactive<FormRules>({
|
||||
name: [
|
||||
{required: true, message: '请输入名称', trigger: 'blur'},
|
||||
{max: 20, message: '名称不能超过20个字符', trigger: 'blur'},
|
||||
@@ -78,15 +71,9 @@ const rules = reactive<FormRules>({
|
||||
tags: [{required: true, message: '请选择', trigger: 'change'}],
|
||||
languageCategory: [{required: true, message: '请选择', trigger: 'change'}],
|
||||
})
|
||||
const rules2 = reactive<FormRules>({
|
||||
name: [
|
||||
{required: true, message: '请输入单词', trigger: 'blur'},
|
||||
{max: 30, message: '名称不能超过30个字符', trigger: 'blur'},
|
||||
],
|
||||
})
|
||||
|
||||
watch(() => form.languageCategory, () => form.category = '')
|
||||
watch(() => form.category, () => form.tags = [])
|
||||
watch(() => dictForm.languageCategory, () => dictForm.category = '')
|
||||
watch(() => dictForm.category, () => dictForm.tags = [])
|
||||
|
||||
onMounted(() => {
|
||||
dictionaryResources.map(v => {
|
||||
@@ -113,13 +100,14 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function selectDict(dict: Dict) {
|
||||
runtimeStore.editDict = cloneDeep(dict)
|
||||
isEdit = false
|
||||
// runtimeStore.editDict = cloneDeep(dict)
|
||||
runtimeStore.editDict = dict
|
||||
isAddDict = false
|
||||
step = 1
|
||||
}
|
||||
|
||||
async function onSubmit() {
|
||||
await ruleFormRef.validate((valid, fields) => {
|
||||
await dictFormRef.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
let data = {
|
||||
sort: Sort.normal,
|
||||
@@ -133,20 +121,20 @@ async function onSubmit() {
|
||||
statistics: [],
|
||||
articles: [],
|
||||
url: '',
|
||||
...form,
|
||||
...dictForm,
|
||||
}
|
||||
if (form.id) {
|
||||
let rIndex = store.myDicts.findIndex(v => v.id === form.id)
|
||||
if (dictForm.id) {
|
||||
let rIndex = store.myDicts.findIndex(v => v.id === dictForm.id)
|
||||
runtimeStore.editDict = data
|
||||
store.myDicts[rIndex] = cloneDeep(data)
|
||||
isEdit = false
|
||||
isAddDict = false
|
||||
} else {
|
||||
if (store.myDicts.find(v => v.name === form.name)) {
|
||||
if (store.myDicts.find(v => v.name === dictForm.name)) {
|
||||
return ElMessage.warning('已有相同名称词典!')
|
||||
} else {
|
||||
runtimeStore.editDict = data
|
||||
store.myDicts.push(cloneDeep(data))
|
||||
isEdit = false
|
||||
isAddDict = false
|
||||
console.log('submit!', data)
|
||||
}
|
||||
}
|
||||
@@ -156,16 +144,74 @@ async function onSubmit() {
|
||||
})
|
||||
}
|
||||
|
||||
function editDict() {
|
||||
dictForm.name = runtimeStore.editDict.name
|
||||
dictForm.description = runtimeStore.editDict.description
|
||||
wordFormMode = FormMode.None;
|
||||
isAddDict = true
|
||||
}
|
||||
|
||||
enum FormMode {
|
||||
None = 'None',
|
||||
Edit = 'Edit',
|
||||
Add = 'Add'
|
||||
}
|
||||
|
||||
let wordFormMode = $ref(FormMode.None)
|
||||
let wordForm = reactive({
|
||||
name: '',
|
||||
trans: '',
|
||||
usphone: '',
|
||||
ukphone: '',
|
||||
})
|
||||
const wordFormRef = $ref<FormInstance>()
|
||||
const wordRules = reactive<FormRules>({
|
||||
name: [
|
||||
{required: true, message: '请输入单词', trigger: 'blur'},
|
||||
{max: 30, message: '名称不能超过30个字符', trigger: 'blur'},
|
||||
],
|
||||
})
|
||||
|
||||
async function onSubmitWord() {
|
||||
await wordFormRef.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
if (wordFormMode === FormMode.Add) {
|
||||
if (runtimeStore.editDict.originWords.find(v => v.name === wordForm.name)) {
|
||||
return ElMessage.warning('已有相同名称单词!')
|
||||
} else {
|
||||
let data: any = cloneDeep(wordForm)
|
||||
if (data.trans) {
|
||||
data.trans = data.trans.split('\n');
|
||||
} else {
|
||||
data.trans = []
|
||||
}
|
||||
runtimeStore.editDict.originWords.push(data)
|
||||
}
|
||||
console.log('runtimeStore.editDict', runtimeStore.editDict)
|
||||
}
|
||||
} else {
|
||||
ElMessage.warning('请填写完整')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function close() {
|
||||
emit('close')
|
||||
}
|
||||
|
||||
let isAddWord = $ref(false)
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
const {
|
||||
isWordCollect,
|
||||
toggleWordCollect,
|
||||
isWordSimple,
|
||||
toggleWordSimple,
|
||||
} = useWordOptions()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="AddWordDialog" :class="isAddWord && 'add-word-mode'">
|
||||
<Slide slide-count="2" :step="step">
|
||||
<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">
|
||||
@@ -178,7 +224,7 @@ let isAddWord = $ref(false)
|
||||
</header>
|
||||
<div class="list">
|
||||
<DictList
|
||||
@add="step = 1;isEdit = true"
|
||||
@add="step = 1;isAddDict = true"
|
||||
@selectDict="selectDict"
|
||||
:list="list"/>
|
||||
</div>
|
||||
@@ -196,7 +242,7 @@ let isAddWord = $ref(false)
|
||||
width="20" color="#929596"
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="detail" v-if="!isEdit">
|
||||
<div class="detail" v-if="!isAddDict">
|
||||
<div class="dict">
|
||||
<div class="info">
|
||||
<div class="name">{{ runtimeStore.editDict.name }}</div>
|
||||
@@ -210,15 +256,15 @@ let isAddWord = $ref(false)
|
||||
<BaseIcon
|
||||
class-name="edit-icon"
|
||||
icon="tabler:edit"
|
||||
@click='isAddWord = false;isEdit = true'
|
||||
@click='editDict'
|
||||
/>
|
||||
</div>
|
||||
<div class="add" v-if="isAddWord">
|
||||
<div class="add" v-if="wordFormMode !== FormMode.None">
|
||||
<div class="common-title">添加单词</div>
|
||||
<el-form
|
||||
class="form"
|
||||
ref="ruleFormRef"
|
||||
:rules="rules"
|
||||
ref="wordFormRef"
|
||||
:rules="wordRules"
|
||||
:model="wordForm"
|
||||
label-width="140rem">
|
||||
<el-form-item label="单词" prop="name">
|
||||
@@ -237,66 +283,86 @@ let isAddWord = $ref(false)
|
||||
<el-input v-model="wordForm.ukphone"/>
|
||||
</el-form-item>
|
||||
<div class="flex-center">
|
||||
<el-button @click="isAddWord = false">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
<el-button @click="wordFormMode = FormMode.None">关闭</el-button>
|
||||
<el-button type="primary" @click="onSubmitWord">确定</el-button>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<div class="list-wrapper">
|
||||
<div class="list-header">
|
||||
<div class="name">单词列表</div>
|
||||
<div class="flex-center gap10">
|
||||
<div class="name">{{ runtimeStore.editDict.words.length }}个单词</div>
|
||||
<div class="name">{{ store.currentDict.originWords.length }}个单词</div>
|
||||
<BaseIcon icon="mi:add"
|
||||
@click='isAddWord = true'
|
||||
@click='wordFormMode = FormMode.Add'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="runtimeStore.editDict.words.length"
|
||||
<!-- <WordList-->
|
||||
<!-- v-if="runtimeStore.editDict.originWords.length"-->
|
||||
<!-- class="word-list"-->
|
||||
<!-- :is-active="true"-->
|
||||
<!-- @change="(i:number) => data.index = i"-->
|
||||
<!-- :list="runtimeStore.editDict.originWords"-->
|
||||
<!-- :activeIndex="data.index"/>-->
|
||||
<WordList2
|
||||
v-if="store.currentDict.words.length"
|
||||
class="word-list"
|
||||
:is-active="true"
|
||||
@change="(i:number) => data.index = i"
|
||||
:list="runtimeStore.editDict.words"
|
||||
:activeIndex="data.index"/>
|
||||
:list="store.currentDict.words"
|
||||
:activeIndex="data.index">
|
||||
<template v-slot="{word}">
|
||||
<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"/>
|
||||
</template>
|
||||
</WordList2>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="edit" v-else>
|
||||
<el-form
|
||||
ref="ruleFormRef"
|
||||
:rules="rules"
|
||||
:model="form"
|
||||
label-width="120px">
|
||||
ref="dictFormRef"
|
||||
:rules="dictRules"
|
||||
:model="dictForm"
|
||||
label-width="120rem">
|
||||
<el-form-item label="名称" prop="name">
|
||||
<el-input v-model="form.name"/>
|
||||
<el-input v-model="dictForm.name"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="描述">
|
||||
<el-input v-model="form.description" type="textarea"/>
|
||||
<el-input v-model="dictForm.description" type="textarea"/>
|
||||
</el-form-item>
|
||||
<el-form-item label="分类" prop="languageCategory">
|
||||
<el-select
|
||||
v-model="form.languageCategory" placeholder="请选择选项">
|
||||
v-model="dictForm.languageCategory" placeholder="请选择选项">
|
||||
<el-option :label="i.name" :value="i.id" v-for="i in languageCategoryOptions"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="用途" prop="category">
|
||||
<el-select v-model="form.category" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in categoryList[form.languageCategory]"/>
|
||||
<el-select v-model="dictForm.category" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in categoryList[dictForm.languageCategory]"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="标签" prop="tags">
|
||||
<el-select
|
||||
multiple
|
||||
v-model="form.tags" placeholder="请选择选项">
|
||||
<el-option :label="i" :value="i" v-for="i in tagList[form.category]"/>
|
||||
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>
|
||||
<div class="flex-center">
|
||||
<el-button @click="step = 0">返回</el-button>
|
||||
<el-button type="primary" @click="onSubmit">确定</el-button>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -324,6 +390,7 @@ let isAddWord = $ref(false)
|
||||
.more-info {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -404,7 +471,7 @@ let isAddWord = $ref(false)
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
.list-wrapper {
|
||||
width: 350rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -427,6 +494,12 @@ let isAddWord = $ref(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.edit {
|
||||
padding: 0 $space;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -12,7 +12,7 @@ import DictGroup from "@/components/Toolbar/DictGroup.vue";
|
||||
import {v4 as uuidv4} from "uuid";
|
||||
import {ActivityCalendar} from "vue-activity-calendar";
|
||||
import "vue-activity-calendar/style.css";
|
||||
import ChapterList from "@/components/ChapterList.vue";
|
||||
import ChapterList from "@/components/list/ChapterList.vue";
|
||||
import WordListModal from "@/components/Modal/WordListModal.vue";
|
||||
import {isArticle} from "@/hooks/article.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
@@ -6,7 +6,7 @@ import {$ref} from "vue/macros";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import ListItem from "@/components/ListItem.vue";
|
||||
import ListItem from "@/components/list/ListItem.vue";
|
||||
import {Word} from "@/types.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import WordList from "@/components/WordList.vue"
|
||||
import WordList from "@/components/list/WordList.vue"
|
||||
|
||||
import {$ref} from "vue/macros"
|
||||
import {computed, provide, watch} from "vue"
|
||||
|
||||
@@ -22,7 +22,7 @@ import Options from "@/components/Practice/Options.vue";
|
||||
import Typing from "@/components/Practice/PracticeWord/Typing.vue";
|
||||
import Panel from "@/components/Practice/Panel.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import WordList from "@/components/WordList.vue";
|
||||
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";
|
||||
|
||||
@@ -58,7 +58,7 @@ function showWordListModal(index: number, item: Word[]) {
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable.scss";
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
74
src/components/list/WordItem.vue
Normal file
74
src/components/list/WordItem.vue
Normal file
@@ -0,0 +1,74 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {Word} from "@/types.ts";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
|
||||
const props = withDefaults(defineProps<{
|
||||
list?: Word[],
|
||||
activeIndex?: number,
|
||||
showDel?: boolean,
|
||||
isActive?: boolean
|
||||
active?: boolean
|
||||
showTranslate?: boolean
|
||||
showWord?: boolean
|
||||
word: Word
|
||||
}>(), {
|
||||
activeIndex: -1,
|
||||
isActive: false,
|
||||
showDel: false,
|
||||
showTranslate: true,
|
||||
showWord: true
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
del: [val: Word],
|
||||
change: [i: number]
|
||||
}>()
|
||||
|
||||
const playWordAudio = usePlayWordAudio()
|
||||
const {
|
||||
isWordCollect,
|
||||
toggleWordCollect,
|
||||
isWordSimple,
|
||||
toggleWordSimple,
|
||||
} = useWordOptions()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="common-list-item"
|
||||
:class="{active}"
|
||||
>
|
||||
<div class="left">
|
||||
<div class="item-title">
|
||||
<span class="word" :class="!showWord && 'text-shadow'">{{ word.name }}</span>
|
||||
<span class="phonetic">{{ word.usphone }}</span>
|
||||
<VolumeIcon class="volume" @click="playWordAudio(word.name)"></VolumeIcon>
|
||||
</div>
|
||||
<div class="item-sub-title" v-if="word.trans.length && showTranslate">
|
||||
<div v-for="item in word.trans">{{ item }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.left {
|
||||
display: flex;
|
||||
gap: 10rem;
|
||||
flex-direction: column;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5rem;
|
||||
transition: all .3s;
|
||||
}
|
||||
</style>
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import {Word} from "../types";
|
||||
import {Word} from "../../types.ts";
|
||||
import {watch} from "vue"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import ListItem from "@/components/ListItem.vue";
|
||||
import ListItem from "@/components/list/ListItem.vue";
|
||||
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
|
||||
import {usePlayWordAudio} from "@/hooks/sound.ts";
|
||||
import {useWordOptions} from "@/hooks/dict.ts";
|
||||
@@ -92,7 +92,7 @@ const {
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable.scss";
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.list {
|
||||
display: flex;
|
||||
82
src/components/list/WordList2.vue
Normal file
82
src/components/list/WordList2.vue
Normal file
@@ -0,0 +1,82 @@
|
||||
<script setup lang="ts">
|
||||
import {Word} from "../../types.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import WordItem from "@/components/list/WordItem.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: [i: 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)
|
||||
// })
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<virtual-list class="virtual-list"
|
||||
:keeps="20"
|
||||
data-key="name"
|
||||
:data-sources="list"
|
||||
:estimate-size="85"
|
||||
item-class="dict-virtual-item"
|
||||
>
|
||||
<template #={source}>
|
||||
<WordItem :word="source">
|
||||
<slot :word="source"></slot>
|
||||
</WordItem>
|
||||
</template>
|
||||
</virtual-list>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
.virtual-list {
|
||||
overflow: overlay;
|
||||
height: 100%;
|
||||
padding: 0 $space;
|
||||
}
|
||||
|
||||
.dict-virtual-item {
|
||||
margin-bottom: 15rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -216,8 +216,8 @@ export const useBaseStore = defineStore('base', {
|
||||
r.json().then(v => {
|
||||
if (this.currentDict.translateLanguage === 'common') {
|
||||
const runtimeStore = useRuntimeStore()
|
||||
fetch('./translate/en2zh_CN.json').then(r => {
|
||||
r.json().then((list: Word[]) => {
|
||||
fetch('./translate/en2zh_CN.json').then(r2 => {
|
||||
r2.json().then((list: Word[]) => {
|
||||
runtimeStore.translateWordList = list
|
||||
|
||||
this.currentDict.originWords = cloneDeep(v)
|
||||
|
||||
Reference in New Issue
Block a user