save
This commit is contained in:
92
src/pages/pc/article/ArticleIndex.vue
Normal file
92
src/pages/pc/article/ArticleIndex.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import DictListPanel from "@/pages/pc/components/DictListPanel.vue";
|
||||
import {Icon} from '@iconify/vue'
|
||||
import {ActivityCalendar} from "vue-activity-calendar";
|
||||
import "vue-activity-calendar/style.css";
|
||||
import {useRouter} from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
||||
const base = useBaseStore()
|
||||
const router = useRouter()
|
||||
|
||||
function clickEvent(e) {
|
||||
console.log('e', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="word flex justify-center ">
|
||||
<div class="w-5/10 pt-5">
|
||||
<div class="flex gap-6">
|
||||
<div class="card w-1/2 flex flex-col">
|
||||
<div class="title">
|
||||
我的词典
|
||||
</div>
|
||||
<div class="grid flex-1 flex gap-5 mt-4">
|
||||
<div class="p-4 flex-1 rounded-md bg-slate-200 relative" v-for="i in 3">
|
||||
<span>收藏</span>
|
||||
<div class="absolute bottom-4 right-4">333个词</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="card ">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="bg-slate-200 p-3 rounded-md cursor-pointer flex items-center">
|
||||
<span class="text-lg font-bold">{{ base.currentDict.name }}</span>
|
||||
<Icon icon="gg:arrows-exchange" class="text-2xl ml-2"/>
|
||||
<Icon icon="uil:setting" class="text-2xl ml-2"/>
|
||||
</div>
|
||||
<div class="rounded-xl bg-slate-800 flex items-center py-3 px-5 text-white cursor-pointer"
|
||||
@click="router.push('/practice')">
|
||||
开始学习
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
|
||||
<el-progress class="mt-1" percentage="80" :show-text="false"></el-progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="flex justify-between">
|
||||
<div class="title">
|
||||
其他学习词典
|
||||
</div>
|
||||
<BaseIcon icon="ic:round-add" @click="router.push('/dict')"/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-6 mt-5 ">
|
||||
<div class=" p-4 rounded-md justify-between items-center bg-slate-200 " v-for="i in 3">
|
||||
<div class="flex justify-between w-full">
|
||||
<span>{{ base.currentDict.name }}</span>
|
||||
<div class="text-2xl ml-2 flex gap-4">
|
||||
<Icon icon="hugeicons:delete-02"/>
|
||||
<Icon icon="nonicons:go-16"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
|
||||
<el-progress class="mt-1" percentage="80" color="white" :show-text="false"></el-progress>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 text-2xl">
|
||||
<Icon icon="mingcute:down-line"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.card {
|
||||
@apply rounded-xl bg-white p-4 mt-5;
|
||||
}
|
||||
|
||||
.center {
|
||||
@apply flex justify-center items-center;
|
||||
}
|
||||
|
||||
.title {
|
||||
@apply text-lg font-medium;
|
||||
}
|
||||
</style>
|
||||
164
src/pages/pc/article/ArticleIndexTEST.vue
Normal file
164
src/pages/pc/article/ArticleIndexTEST.vue
Normal file
@@ -0,0 +1,164 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import Toolbar from "@/pages/pc/components/toolbar/index.vue"
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import Footer from "@/pages/pc/practice/Footer.vue";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
|
||||
import Statistics from "@/pages/pc/practice/Statistics.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import PracticeArticle from "@/pages/pc/practice/practice-article/index.vue";
|
||||
import {ShortcutKey} from "@/types.ts";
|
||||
import DictModal from "@/pages/pc/components/dialog/DictDiglog.vue";
|
||||
import {useStartKeyboardEventListener} from "@/hooks/event.ts";
|
||||
import useTheme from "@/hooks/theme.ts";
|
||||
|
||||
const practiceStore = usePracticeStore()
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const {toggleTheme} = useTheme()
|
||||
const practiceRef: any = $ref()
|
||||
|
||||
watch(practiceStore, () => {
|
||||
if (practiceStore.inputWordNumber < 1) {
|
||||
return practiceStore.correctRate = -1
|
||||
}
|
||||
if (practiceStore.wrongWordNumber > practiceStore.inputWordNumber) {
|
||||
return practiceStore.correctRate = 0
|
||||
}
|
||||
practiceStore.correctRate = 100 - Math.trunc(((practiceStore.wrongWordNumber) / (practiceStore.inputWordNumber)) * 100)
|
||||
})
|
||||
|
||||
|
||||
function test() {
|
||||
MessageBox.confirm(
|
||||
'2您选择了“本地翻译”,但译文内容却为空白,是否修改为“不需要翻译”并保存?',
|
||||
'1提示',
|
||||
() => {
|
||||
console.log('ok')
|
||||
},
|
||||
() => {
|
||||
console.log('cencal')
|
||||
})
|
||||
}
|
||||
|
||||
function write() {
|
||||
// console.log('write')
|
||||
settingStore.dictation = true
|
||||
repeat()
|
||||
}
|
||||
|
||||
//TODO 需要判断是否已忽略
|
||||
function repeat() {
|
||||
// console.log('repeat')
|
||||
emitter.emit(EventKey.resetWord)
|
||||
practiceRef.getCurrentPractice()
|
||||
}
|
||||
|
||||
function prev() {
|
||||
// console.log('next')
|
||||
if (store.currentDict.chapterIndex === 0) {
|
||||
ElMessage.warning('已经在第一章了~')
|
||||
} else {
|
||||
store.currentDict.chapterIndex--
|
||||
repeat()
|
||||
}
|
||||
}
|
||||
|
||||
function toggleShowTranslate() {
|
||||
settingStore.translate = !settingStore.translate
|
||||
}
|
||||
|
||||
function toggleDictation() {
|
||||
settingStore.dictation = !settingStore.dictation
|
||||
}
|
||||
|
||||
function openSetting() {
|
||||
runtimeStore.showSettingModal = true
|
||||
}
|
||||
|
||||
function openDictDetail() {
|
||||
emitter.emit(EventKey.openDictModal, 'detail')
|
||||
}
|
||||
|
||||
function toggleConciseMode() {
|
||||
settingStore.showToolbar = !settingStore.showToolbar
|
||||
settingStore.showPanel = settingStore.showToolbar
|
||||
}
|
||||
|
||||
function togglePanel() {
|
||||
settingStore.showPanel = !settingStore.showPanel
|
||||
}
|
||||
|
||||
function jumpSpecifiedChapter(val: number) {
|
||||
store.currentDict.chapterIndex = val
|
||||
repeat()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.write, write)
|
||||
emitter.on(EventKey.repeat, repeat)
|
||||
emitter.on(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
|
||||
|
||||
emitter.on(ShortcutKey.PreviousChapter, prev)
|
||||
emitter.on(ShortcutKey.RepeatChapter, repeat)
|
||||
emitter.on(ShortcutKey.DictationChapter, write)
|
||||
emitter.on(ShortcutKey.ToggleShowTranslate, toggleShowTranslate)
|
||||
emitter.on(ShortcutKey.ToggleDictation, toggleDictation)
|
||||
emitter.on(ShortcutKey.OpenSetting, openSetting)
|
||||
emitter.on(ShortcutKey.OpenDictDetail, openDictDetail)
|
||||
emitter.on(ShortcutKey.ToggleTheme, toggleTheme)
|
||||
emitter.on(ShortcutKey.ToggleConciseMode, toggleConciseMode)
|
||||
emitter.on(ShortcutKey.TogglePanel, togglePanel)
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.write, write)
|
||||
emitter.off(EventKey.repeat, repeat)
|
||||
emitter.off(EventKey.jumpSpecifiedChapter, jumpSpecifiedChapter)
|
||||
|
||||
emitter.off(ShortcutKey.PreviousChapter, prev)
|
||||
emitter.off(ShortcutKey.RepeatChapter, repeat)
|
||||
emitter.off(ShortcutKey.DictationChapter, write)
|
||||
emitter.off(ShortcutKey.ToggleShowTranslate, toggleShowTranslate)
|
||||
emitter.off(ShortcutKey.ToggleDictation, toggleDictation)
|
||||
emitter.off(ShortcutKey.OpenSetting, openSetting)
|
||||
emitter.off(ShortcutKey.OpenDictDetail, openDictDetail)
|
||||
emitter.off(ShortcutKey.ToggleTheme, toggleTheme)
|
||||
emitter.off(ShortcutKey.ToggleConciseMode, toggleConciseMode)
|
||||
emitter.off(ShortcutKey.TogglePanel, togglePanel)
|
||||
})
|
||||
|
||||
useStartKeyboardEventListener()
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="practice-wrapper">
|
||||
<Toolbar/>
|
||||
<PracticeArticle ref="practiceRef"/>
|
||||
<Footer/>
|
||||
</div>
|
||||
<DictModal/>
|
||||
<Statistics/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.practice-wrapper {
|
||||
font-size: 0.9rem;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
//padding-right: var(--practice-wrapper-padding-right);
|
||||
transform: translateX(var(--practice-wrapper-translateX));
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,8 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
import {onMounted} from "vue"
|
||||
import {DefaultDict, Dict, DictResource, DictType} from "@/types.ts"
|
||||
import {chunk, cloneDeep} from "lodash-es";
|
||||
import {chunk} from "lodash-es";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {Icon} from '@iconify/vue';
|
||||
@@ -14,11 +13,7 @@ import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import Dialog from "@/pages/pc/components/dialog/Dialog.vue";
|
||||
import EditBatchArticleModal from "@/pages/pc/components/article/EditBatchArticleModal.vue";
|
||||
import {nanoid} from "nanoid";
|
||||
import {useRouter} from "vue-router";
|
||||
import {MessageBox} from "@/utils/MessageBox.tsx";
|
||||
import {getDictFile} from "@/utils";
|
||||
|
||||
const store = useBaseStore()
|
||||
const settingStore = useSettingStore()
|
||||
@@ -30,69 +25,10 @@ let chapterWordNumber = $ref(0)
|
||||
let toggleLoading = $ref(false)
|
||||
|
||||
|
||||
async function selectDict(val: { dict: DictResource | Dict, index: number }) {
|
||||
let item = val.dict
|
||||
// console.log('item', item)
|
||||
let find: Dict = store.myDictList.find((v: Dict) => v.id === item.id)
|
||||
if (find) {
|
||||
runtimeStore.editDict = cloneDeep(find)
|
||||
} else {
|
||||
runtimeStore.editDict = cloneDeep({
|
||||
...cloneDeep(DefaultDict),
|
||||
...item,
|
||||
})
|
||||
runtimeStore.editDict.id = nanoid(6)
|
||||
//设置默认章节单词数
|
||||
runtimeStore.editDict.chapterWordNumber = settingStore.chapterWordNumber
|
||||
}
|
||||
|
||||
if ([DictType.collect, DictType.simple, DictType.wrong].includes(runtimeStore.editDict.type)) {
|
||||
} else {
|
||||
//如果不是自定义词典,并且有url地址才去下载
|
||||
if (!runtimeStore.editDict.isCustom && runtimeStore.editDict.url) {
|
||||
let url = `./dicts/${runtimeStore.editDict.language}/${runtimeStore.editDict.type}/${runtimeStore.editDict.translateLanguage}/${runtimeStore.editDict.url}`;
|
||||
if (runtimeStore.editDict.type === DictType.word) {
|
||||
if (!runtimeStore.editDict.originWords.length) {
|
||||
let v = await getDictFile(url)
|
||||
v.map(s => {
|
||||
s.id = nanoid(6)
|
||||
})
|
||||
runtimeStore.editDict.originWords = cloneDeep(v)
|
||||
} else {
|
||||
runtimeStore.editDict.length = runtimeStore.editDict.words.length
|
||||
}
|
||||
}
|
||||
if (runtimeStore.editDict.type === DictType.article) {
|
||||
if (!runtimeStore.editDict.articles.length) {
|
||||
let v = await getDictFile(url)
|
||||
v.map(s => {
|
||||
s.id = nanoid(6)
|
||||
})
|
||||
runtimeStore.editDict.articles = cloneDeep(v)
|
||||
} else {
|
||||
runtimeStore.editDict.length = runtimeStore.editDict.articles.length
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
chapterWordNumber = runtimeStore.editDict.chapterWordNumber
|
||||
}
|
||||
|
||||
|
||||
function close() {
|
||||
show = false
|
||||
}
|
||||
|
||||
//TODO 切大词典太卡了
|
||||
function changeDict() {
|
||||
close()
|
||||
store.changeDict(runtimeStore.editDict)
|
||||
setTimeout(() => {
|
||||
runtimeStore.editDict = cloneDeep(DefaultDict)
|
||||
})
|
||||
ElMessage.success('切换成功')
|
||||
}
|
||||
|
||||
const dictIsArticle = $computed(() => {
|
||||
return isArticle(runtimeStore.editDict.type)
|
||||
})
|
||||
@@ -117,7 +53,6 @@ function resetChapterList(v: number) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function option(type: string) {
|
||||
show = false
|
||||
setTimeout(() => {
|
||||
@@ -126,10 +61,7 @@ function option(type: string) {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.openDictModal, (type: 'detail' | 'list' | 'my') => {
|
||||
if (type === "detail") {
|
||||
selectDict({dict: store.currentDict, index: 0})
|
||||
}
|
||||
emitter.on(EventKey.openDictModal, (typ) => {
|
||||
show = true
|
||||
})
|
||||
})
|
||||
@@ -145,7 +77,7 @@ onMounted(() => {
|
||||
<div id="DictDialog">
|
||||
<header>
|
||||
<div class="text-2xl">
|
||||
{{ runtimeStore.editDict.name }}
|
||||
{{ store.currentDict.name }}
|
||||
</div>
|
||||
<Icon @click="close"
|
||||
class="hvr-grow pointer"
|
||||
@@ -153,13 +85,13 @@ onMounted(() => {
|
||||
icon="ion:close-outline"/>
|
||||
</header>
|
||||
<div class="detail">
|
||||
<div class="desc">{{ runtimeStore.editDict.description }}</div>
|
||||
<div class="desc">{{ store.currentDict.description }}</div>
|
||||
<div class="text flex align-center">
|
||||
<div v-if="dictIsArticle">总文章:{{ runtimeStore.editDict.articles.length }}篇
|
||||
<div v-if="dictIsArticle">总文章:{{ store.currentDict.articles.length }}篇
|
||||
</div>
|
||||
<div v-else>总词汇:
|
||||
<span class="count" @click="showAllWordModal">{{
|
||||
runtimeStore.editDict.originWords.length
|
||||
store.currentDict.originWords.length
|
||||
}}词</span>
|
||||
</div>
|
||||
<BaseIcon icon="mi:add"
|
||||
@@ -181,7 +113,7 @@ onMounted(() => {
|
||||
class="my-slider"
|
||||
:min="10"
|
||||
:step="10"
|
||||
:max="runtimeStore.editDict.words.length < 10 ? 10 : 500"
|
||||
:max="store.currentDict.words.length < 10 ? 10 : 500"
|
||||
size="small"
|
||||
v-model="chapterWordNumber"
|
||||
@change="resetChapterList"
|
||||
@@ -189,17 +121,15 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="notice">
|
||||
<span class="text">最小:10</span>
|
||||
<span class="text">最大:{{ runtimeStore.editDict.words.length < 10 ? 10 : 500 }}</span>
|
||||
<span class="text">最大:{{ store.currentDict.words.length < 10 ? 10 : 500 }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
<BaseButton @click="close">关闭</BaseButton>
|
||||
<BaseButton :loading="toggleLoading" @click="changeDict">切换</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</Dialog>
|
||||
<WordListDialog/>
|
||||
<EditBatchArticleModal/>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
129
src/pages/pc/home/HomeIndex.vue
Normal file
129
src/pages/pc/home/HomeIndex.vue
Normal file
@@ -0,0 +1,129 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import DictListPanel from "@/pages/pc/components/DictListPanel.vue";
|
||||
import {Icon} from '@iconify/vue'
|
||||
import {ActivityCalendar} from "vue-activity-calendar";
|
||||
import "vue-activity-calendar/style.css";
|
||||
import {useRouter} from "vue-router";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
||||
const base = useBaseStore()
|
||||
const router = useRouter()
|
||||
|
||||
function clickEvent(e) {
|
||||
console.log('e', e)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="word flex justify-center ">
|
||||
<div class="w-5/10 pt-5">
|
||||
<div class="flex gap-6">
|
||||
<div class="card w-1/2 flex flex-col">
|
||||
<div class="title">
|
||||
我的词典
|
||||
</div>
|
||||
<div class="grid flex-1 flex gap-5 mt-4">
|
||||
<div class="p-4 flex-1 rounded-md bg-slate-200 relative" v-for="i in 3">
|
||||
<span>收藏</span>
|
||||
<div class="absolute bottom-4 right-4">333个词</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-1/2">
|
||||
<div class="card ">
|
||||
<div class="flex justify-between items-center">
|
||||
<div class="bg-slate-200 p-3 rounded-md cursor-pointer flex items-center">
|
||||
<span class="text-lg font-bold">{{ base.currentDict.name }}</span>
|
||||
<Icon icon="gg:arrows-exchange" class="text-2xl ml-2"/>
|
||||
<Icon icon="uil:setting" class="text-2xl ml-2"/>
|
||||
</div>
|
||||
<div class="rounded-xl bg-slate-800 flex items-center py-3 px-5 text-white cursor-pointer"
|
||||
@click="router.push('/practice')">
|
||||
开始学习
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
|
||||
<el-progress class="mt-1" percentage="80" :show-text="false"></el-progress>
|
||||
</div>
|
||||
<div class="card flex gap-3">
|
||||
<div class="bg-slate-200 w-10 h-10 flex center text-2xl rounded">
|
||||
0
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="flex justify-between">
|
||||
<div class="title">
|
||||
每日目标
|
||||
</div>
|
||||
<div style="color:#ac6ed1;" class="cursor-pointer">
|
||||
更改目标
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-2 text-xs">学习 50 个单词</div>
|
||||
<el-progress class="flex-1 mt-1" percentage="80" :show-text="false"></el-progress>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="flex justify-between">
|
||||
<div class="title">
|
||||
其他学习词典
|
||||
</div>
|
||||
<BaseIcon icon="ic:round-add" @click="router.push('/dict')"/>
|
||||
</div>
|
||||
<div class="grid grid-cols-2 gap-6 mt-5 ">
|
||||
<div class=" p-4 rounded-md justify-between items-center bg-slate-200 " v-for="i in 3">
|
||||
<div class="flex justify-between w-full">
|
||||
<span>{{ base.currentDict.name }}</span>
|
||||
<div class="text-2xl ml-2 flex gap-4">
|
||||
<Icon icon="hugeicons:delete-02"/>
|
||||
<Icon icon="nonicons:go-16"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-5 text-sm">已学习5555个单词的1%</div>
|
||||
<el-progress class="mt-1" percentage="80" color="white" :show-text="false"></el-progress>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-center mt-2 text-2xl">
|
||||
<Icon icon="mingcute:down-line"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="title">
|
||||
学习记录
|
||||
</div>
|
||||
<div class="center">
|
||||
<ActivityCalendar
|
||||
:data="[{ date: '2023-05-22', count: 5 }]"
|
||||
:width="40"
|
||||
:height="7"
|
||||
:cellLength="16"
|
||||
:cellInterval="8"
|
||||
:fontSize="12"
|
||||
:showLevelFlag="false"
|
||||
:showWeekDayFlag="false"
|
||||
:clickEvent="clickEvent"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.card {
|
||||
@apply rounded-xl bg-white p-4 mt-5;
|
||||
}
|
||||
|
||||
.center {
|
||||
@apply flex justify-center items-center;
|
||||
}
|
||||
|
||||
.title {
|
||||
@apply text-lg font-medium;
|
||||
}
|
||||
</style>
|
||||
@@ -21,12 +21,17 @@ const router = useRouter()
|
||||
<div class="aside">
|
||||
<div class="top">
|
||||
<Logo/>
|
||||
<div class="row" @click="router.push('/home')">
|
||||
<Icon icon="material-symbols-light:dictionary-outline-sharp"/>
|
||||
<!-- <Icon icon="streamline:dictionary-language-book"/>-->
|
||||
<span>主页</span>
|
||||
</div>
|
||||
<div class="row" @click="router.push('/word')">
|
||||
<Icon icon="material-symbols-light:dictionary-outline-sharp"/>
|
||||
<!-- <Icon icon="streamline:dictionary-language-book"/>-->
|
||||
<span>单词</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="row" @click="router.push('/article')">
|
||||
<Icon icon="ph:article-ny-times"/>
|
||||
<span>文章</span>
|
||||
</div>
|
||||
|
||||
@@ -143,9 +143,7 @@ useStartKeyboardEventListener()
|
||||
<template>
|
||||
<div class="practice-wrapper">
|
||||
<Toolbar/>
|
||||
<!-- <BaseButton @click="test">test</BaseButton>-->
|
||||
<PracticeArticle ref="practiceRef" v-if="store.isArticle"/>
|
||||
<PracticeWord ref="practiceRef" v-else/>
|
||||
<PracticeWord ref="practiceRef"/>
|
||||
<Footer/>
|
||||
</div>
|
||||
<DictModal/>
|
||||
|
||||
Reference in New Issue
Block a user