save
This commit is contained in:
@@ -59,7 +59,7 @@ watch(store.wrong.originWords, (n) => {
|
||||
})
|
||||
|
||||
async function init() {
|
||||
console.time()
|
||||
// console.time()
|
||||
store.init().then(() => {
|
||||
store.load = true
|
||||
// console.timeEnd()
|
||||
@@ -74,11 +74,9 @@ onMounted(() => {
|
||||
if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
|
||||
// 当前设备是移动设备
|
||||
console.log('当前设备是移动设备')
|
||||
router.replace('/mobile')
|
||||
// router.replace('/mobile')
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -37,7 +37,7 @@ const style = $computed(() => {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
transition: all .5s;
|
||||
transition: all .3s;
|
||||
}
|
||||
|
||||
:deep(.page) {
|
||||
|
||||
@@ -15,7 +15,7 @@ import Setting from "@/components/Setting.vue";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
|
||||
const runtimeStore = useRuntimeStore()
|
||||
let disabledDialogEscKey = $ref(false)
|
||||
let disabledDialogEscKey = $ref(true)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -106,41 +106,26 @@ watch(() => store.load, n => {
|
||||
|
||||
<!-- <Add/>-->
|
||||
|
||||
<Tooltip title="添加">
|
||||
<IconWrapper>
|
||||
<Icon icon="ic:outline-cloud-upload"
|
||||
@click="emitter.emit(EventKey.openDictModal,'my')"
|
||||
/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<BaseIcon
|
||||
@click="emitter.emit(EventKey.openDictModal,'my')"
|
||||
title="添加"
|
||||
icon="ic:outline-cloud-upload"/>
|
||||
|
||||
<BaseIcon
|
||||
@click="showFeedbackModal = true"
|
||||
title="反馈"
|
||||
icon="ph:bug-beetle"/>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<div class="with-bg anim">
|
||||
<Tooltip
|
||||
<BaseIcon
|
||||
@click="runtimeStore.showSettingModal = true"
|
||||
:title="`设置(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon icon="uil:setting" @click="runtimeStore.showSettingModal = true"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
|
||||
<!-- <div class="base-button" @click="emitter.emit(EventKey.openStatModal)">ok</div>-->
|
||||
|
||||
<Tooltip
|
||||
icon="uil:setting"/>
|
||||
<BaseIcon
|
||||
@click="settingStore.showPanel = !settingStore.showPanel"
|
||||
:title="`单词本(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.TogglePanel]})`"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon icon="tdesign:menu-unfold" class="menu" @click="settingStore.showPanel = !settingStore.showPanel"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
icon="tdesign:menu-unfold"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
252
src/pages/mobile/components/MobilePanel.vue
Normal file
252
src/pages/mobile/components/MobilePanel.vue
Normal file
@@ -0,0 +1,252 @@
|
||||
<script setup lang="ts">
|
||||
import {useBaseStore} from "@/stores/base.ts"
|
||||
|
||||
import {$computed, $ref} from "vue/macros"
|
||||
import {computed, onMounted, onUnmounted, provide, watch} from "vue"
|
||||
import {Dict, DictType, ShortcutKey} from "@/types.ts"
|
||||
import PopConfirm from "@/components/PopConfirm.vue"
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Close from "@/components/icon/Close.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
import {useArticleOptions, useWordOptions} from "@/hooks/dict.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import Tooltip from "@/components/Tooltip.vue";
|
||||
import IconWrapper from "@/components/IconWrapper.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import ArticleList from "@/components/list/ArticleList.vue";
|
||||
import Slide from "@/components/Slide.vue";
|
||||
|
||||
const router = useRouter()
|
||||
const store = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const settingStore = useSettingStore()
|
||||
let tabIndex = $ref(0)
|
||||
provide('tabIndex', computed(() => tabIndex))
|
||||
|
||||
watch(() => settingStore.showPanel, n => {
|
||||
if (n) {
|
||||
tabIndex = 0
|
||||
}
|
||||
})
|
||||
|
||||
let practiceType = $ref(DictType.word)
|
||||
|
||||
function changeIndex(dict: Dict) {
|
||||
store.changeDict(dict, practiceType)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
emitter.on(EventKey.changeDict, () => {
|
||||
tabIndex = 0
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
emitter.off(EventKey.changeDict)
|
||||
})
|
||||
|
||||
const {
|
||||
delWrongWord,
|
||||
delSimpleWord,
|
||||
toggleWordCollect,
|
||||
} = useWordOptions()
|
||||
|
||||
const {
|
||||
toggleArticleCollect
|
||||
} = useArticleOptions()
|
||||
|
||||
function addCollect() {
|
||||
runtimeStore.editDict = cloneDeep(store.collect)
|
||||
router.push({path: '/dict', query: {type: 'addWordOrArticle'}})
|
||||
}
|
||||
|
||||
function addSimple() {
|
||||
runtimeStore.editDict = cloneDeep(store.simple)
|
||||
router.push({path: '/dict', query: {type: 'addWordOrArticle'}})
|
||||
}
|
||||
|
||||
const showCollectToggleButton = $computed(() => {
|
||||
if (store.currentDict.type === DictType.collect) {
|
||||
if (store.current.practiceType !== practiceType) {
|
||||
return (practiceType === DictType.word && store.collect.words.length) ||
|
||||
(practiceType === DictType.article && store.collect.articles.length)
|
||||
}
|
||||
} else {
|
||||
return (practiceType === DictType.word && store.collect.words.length) ||
|
||||
(practiceType === DictType.article && store.collect.articles.length)
|
||||
}
|
||||
return false
|
||||
})
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<div class="panel anim">
|
||||
<header>
|
||||
<div class="tabs">
|
||||
<div class="tab" :class="tabIndex === 0 && 'active'" @click="tabIndex = 0">当前</div>
|
||||
<div class="tab" :class="tabIndex === 1 && 'active'" @click="tabIndex = 1">{{ store.collect.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 2 && 'active'" @click="tabIndex = 2">{{ store.simple.name }}</div>
|
||||
<div class="tab" :class="tabIndex === 3 && 'active'" @click="tabIndex = 3">{{ store.wrong.name }}</div>
|
||||
</div>
|
||||
</header>
|
||||
<Slide :slide-count="4" :step="tabIndex">
|
||||
<div class="slide-item">
|
||||
<slot :active="tabIndex === 0 && settingStore.showPanel"></slot>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="dict-name">总词数:{{ store.collect.words.length }}</div>
|
||||
<BaseIcon icon="fluent:add-12-regular" title="添加" @click="addCollect"/>
|
||||
</div>
|
||||
<template v-if="showCollectToggleButton">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.collect)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="store.collect.words.length"
|
||||
class="word-list"
|
||||
:list="store.collect.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item">
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="dict-name">总词数:{{ store.simple.words.length }}</div>
|
||||
<BaseIcon icon="fluent:add-12-regular" title="添加" @click="addSimple"/>
|
||||
</div>
|
||||
<template v-if="store.currentDict.type !== DictType.simple && store.simple.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.simple)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="store.simple.words.length"
|
||||
class="word-list"
|
||||
:list="store.simple.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delSimpleWord(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slide-item">
|
||||
<div class="panel-page-item" v-if="store.wrong.words.length">
|
||||
<div class="list-header">
|
||||
<div class="dict-name">总词数:{{ store.wrong.words.length }}</div>
|
||||
<template
|
||||
v-if="store.currentDict.type !== DictType.wrong && store.wrong.words.length">
|
||||
<PopConfirm
|
||||
:title="`确认切换?`"
|
||||
@confirm="changeIndex( store.wrong)"
|
||||
>
|
||||
<BaseButton size="small">切换</BaseButton>
|
||||
</PopConfirm>
|
||||
</template>
|
||||
</div>
|
||||
<WordList
|
||||
class="word-list"
|
||||
:list="store.wrong.words">
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
class="del"
|
||||
@click="delWrongWord(item)"
|
||||
title="移除"
|
||||
icon="solar:trash-bin-minimalistic-linear"/>
|
||||
</template>
|
||||
</WordList>
|
||||
</div>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</Slide>
|
||||
</div>
|
||||
</template>
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/variable";
|
||||
|
||||
$header-height: 50rem;
|
||||
.slide-item {
|
||||
width: 25%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.panel {
|
||||
border-radius: 8rem;
|
||||
width: 100%;
|
||||
background: var(--color-second-bg);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all .3s;
|
||||
z-index: 1;
|
||||
border: 1px solid var(--color-item-border);
|
||||
box-shadow: var(--shadow);
|
||||
|
||||
|
||||
& > header {
|
||||
min-height: 50rem;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10rem 15rem;
|
||||
border-bottom: 1px solid #e1e1e1;
|
||||
gap: 15rem;
|
||||
|
||||
.close {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tabs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 15rem;
|
||||
font-size: 14rem;
|
||||
|
||||
.tab {
|
||||
cursor: pointer;
|
||||
word-break: keep-all;
|
||||
font-size: 16rem;
|
||||
transition: all .3s;
|
||||
color: gray;
|
||||
|
||||
&.active {
|
||||
color: var(--color-main-active);
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -4,11 +4,18 @@ import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {Word} from "@/types.ts";
|
||||
import {ShortcutKey, Sort, Word} from "@/types.ts";
|
||||
import {cloneDeep} from "lodash-es";
|
||||
import {emitter, EventKey} from "@/utils/eventBus.ts";
|
||||
import {syncMyDictList} from "@/hooks/dict.ts";
|
||||
import {onMounted, onUnmounted} from "vue";
|
||||
import {syncMyDictList, useWordOptions} from "@/hooks/dict.ts";
|
||||
import {onMounted, onUnmounted, watch} from "vue";
|
||||
import BaseButton from "@/components/BaseButton.vue";
|
||||
import Options from "@/pages/practice/Options.vue";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
import MobilePanel from "@/pages/mobile/components/MobilePanel.vue";
|
||||
import MiniDialog from "@/components/dialog/MiniDialog.vue";
|
||||
import WordList from "@/components/list/WordList.vue";
|
||||
import Empty from "@/components/Empty.vue";
|
||||
|
||||
const store = useBaseStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
@@ -29,7 +36,6 @@ const word: Word = $computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
function getCurrentPractice() {
|
||||
if (store.chapter.length) {
|
||||
wordData.words = store.chapter
|
||||
@@ -61,25 +67,150 @@ function next() {
|
||||
getCurrentPractice()
|
||||
}
|
||||
|
||||
watch(() => store.load, n => {
|
||||
getCurrentPractice()
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
getCurrentPractice()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
})
|
||||
const {
|
||||
isWordCollect,
|
||||
toggleWordCollect,
|
||||
isWordSimple,
|
||||
toggleWordSimple,
|
||||
toggleWordSimpleWrapper
|
||||
} = useWordOptions()
|
||||
|
||||
let showSortOption = $ref(false)
|
||||
let showPanel = $ref(false)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div id="mobile">
|
||||
<div class="content">
|
||||
<div class="translate">
|
||||
<div class="translate-item" v-for="(v,i) in word.trans">
|
||||
<span>{{ v }}</span>
|
||||
<div class="slide">
|
||||
<div class="slide-list" :class="{showPanel}">
|
||||
<div class="practice" @click.stop="showPanel = false">
|
||||
<div class="tool-bar">
|
||||
<BaseIcon
|
||||
v-if="!isWordCollect(word)"
|
||||
class="collect"
|
||||
@click="toggleWordCollect(word)"
|
||||
icon="ph:star"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordCollect(word)"
|
||||
icon="ph:star-fill"/>
|
||||
|
||||
<BaseIcon
|
||||
@click="showPanel = !showPanel"
|
||||
icon="tdesign:menu-unfold"/>
|
||||
</div>
|
||||
<div class="word-content">
|
||||
<div class="translate">
|
||||
<div class="translate-item" v-for="(v,i) in word.trans">
|
||||
<span>{{ v }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="word">
|
||||
{{ word.name }}
|
||||
</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'us' && word.usphone">[{{ word.usphone }}]</div>
|
||||
<div class="phonetic" v-if="settingStore.wordSoundType === 'uk' && word.ukphone">[{{ word.ukphone }}]</div>
|
||||
</div>
|
||||
<div class="options">
|
||||
<div class="wrapper">
|
||||
<BaseButton>不认识</BaseButton>
|
||||
<BaseButton @click="wordData.index++">认识</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="list">
|
||||
<MobilePanel>
|
||||
<template v-slot="{active}">
|
||||
<div class="panel-page-item"
|
||||
v-loading="!store.load"
|
||||
>
|
||||
<div class="list-header">
|
||||
<div class="left">
|
||||
<div class="title">
|
||||
{{ store.chapterName }}
|
||||
</div>
|
||||
<BaseIcon title="切换词典"
|
||||
@click="emitter.emit(EventKey.openDictModal,'list')"
|
||||
icon="carbon:change-catalog"/>
|
||||
<div style="position:relative;"
|
||||
@click.stop="null">
|
||||
<BaseIcon
|
||||
title="改变顺序"
|
||||
icon="icon-park-outline:sort-two"
|
||||
@click="showSortOption = !showSortOption"
|
||||
/>
|
||||
<MiniDialog
|
||||
v-model="showSortOption"
|
||||
style="width: 130rem;"
|
||||
>
|
||||
<div class="mini-row-title">
|
||||
列表循环设置
|
||||
</div>
|
||||
<div class="mini-row">
|
||||
<BaseButton size="small" @click="sort(Sort.reverse)">翻转</BaseButton>
|
||||
<BaseButton size="small" @click="sort(Sort.random)">随机</BaseButton>
|
||||
</div>
|
||||
</MiniDialog>
|
||||
</div>
|
||||
<BaseIcon icon="bi:arrow-right"
|
||||
@click="next"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.chapterWords.length - 1"/>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ wordData.words.length }}个单词
|
||||
</div>
|
||||
</div>
|
||||
<WordList
|
||||
v-if="wordData.words.length"
|
||||
:is-active="active"
|
||||
:static="true"
|
||||
:show-word="!settingStore.dictation"
|
||||
:show-translate="settingStore.translate"
|
||||
:list="wordData.words"
|
||||
:activeIndex="wordData.index"
|
||||
@click="(val:any) => wordData.index = val.index"
|
||||
>
|
||||
<template v-slot:suffix="{item,index}">
|
||||
<BaseIcon
|
||||
v-if="!isWordCollect(item)"
|
||||
class="collect"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="收藏" icon="ph:star"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordCollect(item)"
|
||||
title="取消收藏" icon="ph:star-fill"/>
|
||||
<BaseIcon
|
||||
v-if="!isWordSimple(item)"
|
||||
class="easy"
|
||||
@click="toggleWordSimple(item)"
|
||||
title="标记为简单词"
|
||||
icon="material-symbols:check-circle-outline-rounded"/>
|
||||
<BaseIcon
|
||||
v-else
|
||||
class="fill"
|
||||
@click="toggleWordSimple(item)"
|
||||
title="取消标记简单词"
|
||||
icon="material-symbols:check-circle-rounded"/>
|
||||
</template>
|
||||
</WordList>
|
||||
<Empty v-else/>
|
||||
</div>
|
||||
</template>
|
||||
</MobilePanel>
|
||||
</div>
|
||||
</div>
|
||||
<div class="word">
|
||||
{{ word.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,6 +222,92 @@ onUnmounted(() => {
|
||||
z-index: 1;
|
||||
font-size: 14rem;
|
||||
color: black;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
$list-width: 75vw;
|
||||
|
||||
.slide {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.slide-list {
|
||||
width: calc(100% + $list-width);
|
||||
height: 100%;
|
||||
display: flex;
|
||||
transition: all .5s;
|
||||
}
|
||||
.showPanel{
|
||||
transform: translateX(-$list-width);
|
||||
}
|
||||
}
|
||||
|
||||
.practice {
|
||||
width: 100vw;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rem;
|
||||
|
||||
.tool-bar {
|
||||
height: 50rem;
|
||||
display: flex;
|
||||
padding: 0 10rem;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 10rem;
|
||||
}
|
||||
|
||||
.word-content {
|
||||
width: 100%;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
.translate {
|
||||
width: 80%;
|
||||
font-size: 18rem;
|
||||
|
||||
.translate-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10rem;
|
||||
}
|
||||
}
|
||||
|
||||
.word {
|
||||
font-size: 26rem;
|
||||
}
|
||||
|
||||
.phonetic {
|
||||
font-size: 16rem;
|
||||
}
|
||||
}
|
||||
|
||||
.options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding-bottom: 20rem;
|
||||
|
||||
.wrapper {
|
||||
width: 80%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10rem;
|
||||
}
|
||||
|
||||
.base-button {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.list {
|
||||
width: $list-width;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -315,13 +315,10 @@ onUnmounted(() => {
|
||||
</div>
|
||||
</MiniDialog>
|
||||
</div>
|
||||
<Tooltip
|
||||
:title="`下一章(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.NextChapter]})`"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.chapterWords.length - 1">
|
||||
<IconWrapper>
|
||||
<Icon @click="emitter.emit(EventKey.next)" icon="octicon:arrow-right-24"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<BaseIcon icon="bi:arrow-right"
|
||||
@click="emitter.emit(EventKey.next)"
|
||||
:title="`下一章(快捷键:${settingStore.shortcutKeyMap[ShortcutKey.NextChapter]})`"
|
||||
v-if="store.currentDict.chapterIndex < store.currentDict.chapterWords.length - 1"/>
|
||||
</div>
|
||||
<div class="right">
|
||||
{{ data.words.length }}个单词
|
||||
|
||||
@@ -5,16 +5,16 @@ import Mobile from '@/pages/mobile/index.vue'
|
||||
import Test from "@/pages/test.vue";
|
||||
|
||||
const routes: any[] = [
|
||||
{path: '/practice', component: Practice},
|
||||
{path: '/dict', name: 'dict', component: Dict},
|
||||
{path: '/mobile', name: 'dict', component: Mobile},
|
||||
{path: '/test', name: 'test', component: Test},
|
||||
{path: '/', redirect: '/practice'},
|
||||
{path: '/practice', component: Practice},
|
||||
{path: '/dict', component: Dict},
|
||||
{path: '/mobile', component: Mobile},
|
||||
{path: '/test', component: Test},
|
||||
{path: '/', redirect: '/practice'},
|
||||
]
|
||||
|
||||
const router = VueRouter.createRouter({
|
||||
history: VueRouter.createWebHashHistory(),
|
||||
routes,
|
||||
history: VueRouter.createWebHashHistory(),
|
||||
routes,
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user