Add more route

master
cast1e 2023-11-07 22:07:15 +08:00
parent 7d404aeb66
commit bd6d4cf797
9 changed files with 550 additions and 423 deletions

View File

@ -1,411 +0,0 @@
<template>
<el-page-header style="margin:20px" @back="back_home">
<template #content>
<span class="text-large font-600 mr-3"> 编辑单词本 </span>
</template>
</el-page-header>
<el-container v-if="mode < 2" id="main-container" class="container card">
<el-header id="header" class="colbox">
<div class="no">共有{{ Object.keys(this.wordsets).length }}个单词集合</div>
<div>
<el-button @click="export_set" type="success"><box-icon color="white" name='export'
size="15px"></box-icon></el-button>
<el-button @click="import_set" type="warning"><box-icon color="white" name='import'
size="15px"></box-icon></el-button>
<el-button @click="mode = 1" type="primary"><box-icon color="white" name='plus'></box-icon></el-button>
</div>
</el-header>
<el-main id="wordsets-container">
<div v-if="mode === 0" class="colbox" if="sets-container">
<el-collapse accordion v-model="active_set_class" style="width: 100%;border: none;">
<el-collapse-item v-for="(set_class, class_name) in wordsets" :title="class_name" :key="class_name"
:name="class_name">
<div class="colbox wordclass">
<div v-for="(wordset, index) in set_class" :key="index" class="wordset rowbox">
<div class="no">
{{ index + 1 }}
</div>
<div class="title">
{{ wordset.name }}
</div>
<div style="font-size: 17px;font-weight: 200;">
创建日期{{ (new Date(wordset.created)).toLocaleString() }}
</div>
<div class="option">
<box-icon class="btn" name='edit' color="var(--text-color)"
@click="edit(wordset, class_name)"></box-icon>
<box-icon class="btn" name='trash' color="var(--text-color)"
@click="del(class_name, wordset.id, index)"></box-icon>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
<div v-if="mode === 1" id="new" class="rowbox">
<el-page-header @back="mode = 0">
<template #content>
<span class="text-large font-600 mr-3"> 新建单词本 </span>
</template>
</el-page-header>
<div class="colbox">
<div class="mid-text">名称:</div>
<el-input v-model="set_name"></el-input>
<div class="mid-text">分组:</div>
<el-select allow-create filterable v-model="new_set_class" class="m-2" placeholder="Select">
<el-option v-for="item in Object.keys(wordsets)" :key="item" :label="item" :value="item" />
</el-select>
</div>
<el-button style="width: 50%;" type="primary" @click="new_wordset()"></el-button>
</div>
</el-main>
</el-container>
<div v-if="mode === 2" class="container" style="overflow: auto;">
<el-page-header @back="mode = 0">
<template #content>
<span class="text-large font-600 mr-3"> {{ editing.name }} ({{ editing.id }}) </span>
</template>
</el-page-header>
<div class="colbox" style="margin-top: 20px;">
<div class="rowbox">
<div class="card" style="margin-bottom: 20px;">
<div class="title">添加单词</div>
<el-input ref="input1" autofocus @change="focusnext($refs.input2)" v-model="new_word.word"></el-input>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
<el-input ref="input2" @change="focusnext($refs.input3)" v-model="new_word.trans"></el-input>
</div>
<div class="colbox">
<el-text class="mx-1" style="width: 80px;">词性</el-text>
<el-select ref="input3" v-model="new_word.type" class="m-2" placeholder="Select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<el-button @click="add_word()" type="primary">添加</el-button>
</div>
<div class="card">
<div class="title">更改名称</div>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">新名称:</el-text>
<el-input v-model="new_name"></el-input>
</div>
<el-button @click="change_name()" type="primary">更改名称</el-button>
</div>
</div>
<div style="width: 100%;" class="card">
<el-table :data="table" style="max-height: 550px;overflow: auto;border-radius: 10px;">
<el-table-column type="index" />
<el-table-column prop="word" label="单词" />
<el-table-column prop="type" label="词性" />
<el-table-column prop="trans" label="翻译" />
<el-table-column width="100px" fixed="right" label="操作">
<template #default="scope">
<div style="display: flex;flex-direction: row;justify-content: space-around;">
<box-icon color="var(--text-color)" size="14px" class="btn" name='trash'
@click="del_word(scope.$index)"></box-icon>
<box-icon color="var(--text-color)" size="14px" class="btn" name='edit-alt'
@click="edit_word(scope.$index)"></box-icon>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<el-dialog v-model="word_editing">
<div class="title">修改单词</div>
<el-input v-model="editing_word.word"></el-input>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
<el-input v-model="editing_word.trans"></el-input>
</div>
<div class="colbox">
<el-text class="mx-1" style="width: 80px;">词性</el-text>
<el-select v-model="editing_word.type" class="m-2" placeholder="Select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<el-button @click="save_word" type="primary">更改</el-button>
</el-dialog>
</template>
<script>
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus';
import uuid from 'node-uuid';
export default {
name: "NoteEditor",
data() {
return {
mode: 0,
wordsets: window.wordsets,
set_name: "",
new_set_class: "",
editing: {},
editingClass: "",
new_word: {
word: "",
trans: "",
type: "adj.",
},
editing_word: {
word: "",
trans: "",
type: "adj.",
index: 0,
},
options: [{ label: "adjective(adj.)", value: "adj." }, { label: "verb(v.)", value: "v." }, { label: "noun(n.)", value: "n." }, { label: "adverb(adv.)", value: "adv." }, { label: "prepositions(prep.)", value: "prep." }, { label: "phrase(phr.)", value: "phr." },],
table: [],
active_set_class: "",
word_editing: false,
}
},
methods: {
focusnext(node) {
node.focus();
},
back_home() {
this.$router.push("/");
},
new_wordset() {
if (!this.new_set_class) {
ElMessage({
message: "集合不能为空",
type: "error"
})
return;
}
if (!this.wordsets[this.new_set_class]) {
this.wordsets[this.new_set_class] = [];
}
let id = uuid.v1();
this.wordsets[this.new_set_class].push({
name: this.set_name,
created: (new Date()).getTime(),
id: id
});
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
localStorage.setItem(id, JSON.stringify([]));
this.mode = 0;
return;
},
del(set_class_name, id, index) {
ElMessageBox.confirm("确定要删除吗?")
.then(() => {
localStorage.removeItem(id);
this.wordsets[set_class_name].splice(index, 1);
if (!this.wordsets[set_class_name].length) {
delete this.wordsets[set_class_name];
}
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElMessage(`已经删除 ${set_class_name} `);
});
},
edit(set, set_class_name) {
this.editing = set;
this.table = JSON.parse(localStorage.getItem(set.id));
this.mode = 2;
this.editingClass = set_class_name;
},
has_word(word) {
for (let i of this.table) {
if (i.word === word) return true;
}
return false;
},
add_word() {
if (this.has_word(this.new_word.word)) {
ElMessage({
message: `单词 ${this.new_word.word} 已存在`,
type: 'error',
});
return;
}
this.table.push(Object.assign({}, this.new_word));
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已添加 ${this.new_word.word} (${this.new_word.type})`,
type: 'success',
});
this.new_word.word = "";
this.new_word.trans = "";
this.$refs.input1.focus();
},
edit_word(index) {
this.editing_word = Object.assign({}, this.table[index]);
this.editing_word.index = index;
this.word_editing = true;
return;
},
save_word() {
if (this.editing_word.word != this.table[this.editing_word.index].word) {
if (this.has_word(this.editing_word.word)) {
ElMessage({
message: `单词 ${this.new_word.word} 已存在`,
type: 'error',
});
return;
}
}
this.table[this.editing_word.index] = {
word: this.editing_word.word,
type: this.editing_word.type,
trans: this.editing_word.trans,
}
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已保存更改`,
type: 'success',
});
this.word_editing = false;
},
change_name() {
let old_name = this.editing.name;
this.editing.name = this.new_name;
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElMessage({
message: `已更改 ${old_name}${this.new_name}`,
type: 'success',
});
return;
},
del_word(index) {
let word = this.table[index].word.concat();
this.table.splice(index, 1);
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已删除 ${word}`,
type: 'warning',
});
},
async export_set() {
let fileHandle = await window.showSaveFilePicker({
types: [
{
description: "JSON file",
accept: {
'text/json': ['.json'],
},
},
],
});
let writestream = await fileHandle.createWritable();
let data = {
wordsets: this.wordsets,
words: {}
};
for (let i of Object.values(this.wordsets)) {
for (let j of i) {
let temp = localStorage.getItem(j.id);
data.words[j.id] = temp;
}
}
writestream.write(JSON.stringify(data));
writestream.close();
},
async import_set() {
let [fileHandle] = await window.showOpenFilePicker({
types: [
{
description: "JSON file",
accept: {
'text/json': ['.json'],
},
},
],
});
let file = await fileHandle.getFile();
let data = JSON.parse(await file.text());
let cnt = 0;
for (let i of Object.keys(data.wordsets)) {
for (let j of data.wordsets[i]) {
if (!localStorage.getItem(j.id)) {
if (!this.wordsets[i]) this.wordsets[i] = [];
this.wordsets[i].push(j);
localStorage.setItem(j.id, data.words[j.id]);
cnt++;
}
}
}
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElNotification({
type: "success",
title: "添加成功",
message: `已添加 ${cnt} 本单词本`
});
}
},
created() {
this.active_set_class = Object.keys(this.wordsets)[0];
}
}
</script>
<style scoped>
#header {
/* border-bottom: solid 1px #bcbcbc; */
justify-content: space-between;
height: 40px;
}
.no {
font-size: 20px;
font-weight: 700;
}
.title {
font-weight: 800;
color: var(--text-color);
font-size: 35px;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-height: 60px;
}
.option {
display: flex;
justify-content: space-around;
opacity: 0;
transition: .5s;
}
.wordset:hover .option {
opacity: 1;
}
.card div {
margin-bottom: 10px;
}
#new div {
margin-bottom: 20px;
}
#sets-container {
background-color: var(--bg-color);
padding: 5px;
border-radius: 8px;
}
.el-collapse {
--el-collapse-header-bg-color: #FFFFFF00;
--el-collapse-content-bg-color: #FFFFFF00;
--el-collapse-header-font-size: 18px;
}
.wordclass {
flex-wrap: wrap
}
#wordsets-container {
overflow-x: auto;
height: 100%;
}
#main-container {
height: 87%;
}
</style>

View File

@ -7,7 +7,7 @@
<router-link to="/recite" class="button"> <router-link to="/recite" class="button">
背诵 背诵
</router-link> </router-link>
<router-link to="editor" class="button"> <router-link to="/manage" class="button">
编辑单词本 编辑单词本
</router-link> </router-link>
</div> </div>

View File

@ -0,0 +1,32 @@
<template>
<el-page-header style="margin:20px" @back="back_home">
<template #content>
<span class="text-large font-600 mr-3"> 编辑单词本 </span>
</template>
</el-page-header>
<router-view>
</router-view>
</template>
<script>
export default {
name: "SetManage",
data() {
return {
}
},
methods: {
back_home() {
this.$router.push("/");
},
},
}
</script>
<style scoped>
</style>

View File

@ -4,8 +4,8 @@
<span class="text-large font-600 mr-3"> 背诵 </span> <span class="text-large font-600 mr-3"> 背诵 </span>
</template> </template>
</el-page-header> </el-page-header>
<div v-if="mode === 0" class="container"> <div v-if="mode === 0" id="range" class="container colbox">
<div class="card item"> <div id="rangeselect" class="card item">
<div class="title">选择测验范围</div> <div class="title">选择测验范围</div>
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange" <el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange"
size="large">全选</el-checkbox> size="large">全选</el-checkbox>
@ -22,7 +22,7 @@
</el-checkbox-group> </el-checkbox-group>
<el-button style="margin: 20px;width: 50%;" type="primary" @click="init"></el-button> <el-button style="margin: 20px;width: 50%;" type="primary" @click="init"></el-button>
</div> </div>
<div class="card item"> <div id="lastrecite" class="card item">
<div class="title" style="font-size: 35px;">继续上一次的背诵</div> <div class="title" style="font-size: 35px;">继续上一次的背诵</div>
<el-button style="margin: 20px;width: 50%;" type="primary" @click="last_recite"></el-button> <el-button style="margin: 20px;width: 50%;" type="primary" @click="last_recite"></el-button>
</div> </div>
@ -40,9 +40,10 @@
<el-button v-if="current > 0" @click="prev"></el-button> <el-button v-if="current > 0" @click="prev"></el-button>
<el-button v-if="current < answered" @click="next"></el-button> <el-button v-if="current < answered" @click="next"></el-button>
<el-button v-if="current === answered" @click="showAnswer"></el-button> <el-button v-if="current === answered" @click="showAnswer"></el-button>
<el-button v-if="current === answered" type="warning" @click="skip"></el-button>
<el-button @click="terminate" type="danger">停止背诵</el-button> <el-button @click="terminate" type="danger">停止背诵</el-button>
<box-icon color="var(--text-color)" class="btn" style="margin-left: 10px;translate: 0 4px;" @click="audio_play" <box-icon color="var(--text-color)" class="btn" style="margin-left: 10px;translate: 0 4px;"
name='volume-full'></box-icon> @click="audio_play" name='volume-full'></box-icon>
</p> </p>
<div id="trans">{{ word.type }} {{ word.trans }}</div> <div id="trans">{{ word.type }} {{ word.trans }}</div>
</div> </div>
@ -187,6 +188,16 @@ export default {
this.show(); this.show();
}); });
}, },
skip() {
ElMessage({
message: "已经跳过该词",
type: "info"
});
this.answered++;
localStorage.setItem("lastcurrent", this.answered.toString());
this.next();
return;
},
prev() { prev() {
this.current--; this.current--;
this.show(); this.show();
@ -340,4 +351,17 @@ export default {
width: 30%; width: 30%;
min-width: 200px; min-width: 200px;
} }
#lastrecite {
max-height: 150px;
}
#range {
max-height: 85%;
}
#rangeselect {
max-height: 100%;
overflow-x: auto;
}
</style> </style>

View File

@ -0,0 +1,218 @@
<template>
<div class="container" style="overflow: auto;">
<el-page-header @back="$router.push('/manage')">
<template #content>
<span class="text-large font-600 mr-3"> {{ editing.name }} ({{ editing.id }}) </span>
</template>
</el-page-header>
<div class="colbox" style="margin-top: 20px;">
<div class="rowbox">
<div class="card" style="margin-bottom: 20px;">
<div class="title">添加单词</div>
<el-input ref="input1" autofocus @change="focusnext($refs.input2)" v-model="new_word.word"></el-input>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
<el-input ref="input2" @change="focusnext($refs.input3)" v-model="new_word.trans"></el-input>
</div>
<div class="colbox">
<el-text class="mx-1" style="width: 80px;">词性</el-text>
<el-select ref="input3" v-model="new_word.type" class="m-2" placeholder="Select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<el-button @click="add_word()" type="primary">添加</el-button>
</div>
<div class="card">
<div class="title">更改名称</div>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">新名称:</el-text>
<el-input v-model="new_name"></el-input>
</div>
<el-button @click="change_name()" type="primary">更改名称</el-button>
</div>
</div>
<div style="width: 100%;" class="card">
<el-table :data="table" style="max-height: 550px;overflow: auto;border-radius: 10px;">
<el-table-column type="index" />
<el-table-column prop="word" label="单词" />
<el-table-column prop="type" label="词性" />
<el-table-column prop="trans" label="翻译" />
<el-table-column width="100px" fixed="right" label="操作">
<template #default="scope">
<div style="display: flex;flex-direction: row;justify-content: space-around;">
<box-icon color="var(--text-color)" size="14px" class="btn" name='trash'
@click="del_word(scope.$index)"></box-icon>
<box-icon color="var(--text-color)" size="14px" class="btn" name='edit-alt'
@click="edit_word(scope.$index)"></box-icon>
</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
</div>
<el-dialog v-model="word_editing">
<div class="title">修改单词</div>
<el-input v-model="editing_word.word"></el-input>
<div class="colbox">
<el-text class="mx-1" style="width: 60px;">翻译:</el-text>
<el-input v-model="editing_word.trans"></el-input>
</div>
<div class="colbox">
<el-text class="mx-1" style="width: 80px;">词性</el-text>
<el-select v-model="editing_word.type" class="m-2" placeholder="Select">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
<el-button @click="save_word" type="primary">更改</el-button>
</el-dialog>
</template>
<script>
import { ElMessage } from 'element-plus';
export default {
name: "NoteEditor",
data() {
return {
editing: window.editing.set,
editingClass:window.editing.set_class_name,
wordsets: window.wordsets,
new_word: {
word: "",
trans: "",
type: "adj.",
},
editing_word: {
word: "",
trans: "",
type: "adj.",
index: 0,
},
options: [{ label: "adjective(adj.)", value: "adj." }, { label: "verb(v.)", value: "v." }, { label: "noun(n.)", value: "n." }, { label: "adverb(adv.)", value: "adv." }, { label: "prepositions(prep.)", value: "prep." }, { label: "phrase(phr.)", value: "phr." },],
table: [],
word_editing: false,
new_name:"",
}
},
methods: {
focusnext(node) {
node.focus();
},
has_word(word) {
for (let i of this.table) {
if (i.word === word) return true;
}
return false;
},
add_word() {
if (this.has_word(this.new_word.word)) {
ElMessage({
message: `单词 ${this.new_word.word} 已存在`,
type: 'error',
});
return;
}
this.table.push(Object.assign({}, this.new_word));
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已添加 ${this.new_word.word} (${this.new_word.type})`,
type: 'success',
});
this.new_word.word = "";
this.new_word.trans = "";
this.$refs.input1.focus();
},
edit_word(index) {
this.editing_word = Object.assign({}, this.table[index]);
this.editing_word.index = index;
this.word_editing = true;
return;
},
save_word() {
if (this.editing_word.word != this.table[this.editing_word.index].word) {
if (this.has_word(this.editing_word.word)) {
ElMessage({
message: `单词 ${this.new_word.word} 已存在`,
type: 'error',
});
return;
}
}
this.table[this.editing_word.index] = {
word: this.editing_word.word,
type: this.editing_word.type,
trans: this.editing_word.trans,
}
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已保存更改`,
type: 'success',
});
this.word_editing = false;
},
change_name() {
let old_name = this.editing.name;
this.editing.name = this.new_name;
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElMessage({
message: `已更改 ${old_name}${this.new_name}`,
type: 'success',
});
return;
},
del_word(index) {
let word = this.table[index].word.concat();
this.table.splice(index, 1);
localStorage.setItem(this.editing.id, JSON.stringify(this.table));
ElMessage({
message: `已删除 ${word}`,
type: 'warning',
});
},
},
created() {
this.table = JSON.parse(localStorage.getItem(this.editing.id));
},
}
</script>
<style scoped>
#main-container {
height: 87%;
}
.title {
font-weight: 800;
color: var(--text-color);
font-size: 35px;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-height: 60px;
}
.card div {
margin-bottom: 10px;
}
#new div {
margin-bottom: 20px;
}
#sets-container {
background-color: var(--bg-color);
padding: 5px;
border-radius: 8px;
}
.el-collapse {
--el-collapse-header-bg-color: #FFFFFF00;
--el-collapse-content-bg-color: #FFFFFF00;
--el-collapse-header-font-size: 18px;
}
</style>

View File

@ -0,0 +1,66 @@
<template>
<el-container id="main-container" class="container card">
<div style="overflow: auto;">
<el-page-header @back="$router.push('/manage')">
<template #content>
<span class="text-large font-600 mr-3"> 新建单词本 </span>
</template>
</el-page-header>
<div class="colbox">
<div class="mid-text">名称:</div>
<el-input v-model="set_name"></el-input>
<div class="mid-text">分组:</div>
<el-select allow-create filterable v-model="new_set_class" class="m-2" placeholder="Select">
<el-option v-for="item in Object.keys(wordsets)" :key="item" :label="item" :value="item" />
</el-select>
</div>
<el-button style="width: 50%;" type="primary" @click="new_wordset()"></el-button>
</div>
</el-container>
</template>
<script>
import uuid from 'node-uuid';
import { ElMessage} from 'element-plus';
export default {
name: "NewSet",
data() {
return {
wordsets: window.wordsets,
set_name: "",
new_set_class: "",
}
},
methods: {
new_wordset() {
if (!this.new_set_class) {
ElMessage({
message: "集合不能为空",
type: "error"
})
return;
}
if (!this.wordsets[this.new_set_class]) {
this.wordsets[this.new_set_class] = [];
}
let id = uuid.v1();
this.wordsets[this.new_set_class].push({
name: this.set_name,
created: (new Date()).getTime(),
id: id
});
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
localStorage.setItem(id, JSON.stringify([]));
this.mode = 0;
return;
},
}
}
</script>
<style scoped>
#main-container {
height: 87%;
}
</style>

View File

@ -0,0 +1,186 @@
<template>
<el-container id="main-container" class="container card">
<el-header id="header" class="colbox">
<div class="no">共有{{ Object.keys(wordsets).length }}个单词集合</div>
<div>
<el-button @click="export_set" type="success"><box-icon color="white" name='export'
size="15px"></box-icon></el-button>
<el-button @click="import_set" type="warning"><box-icon color="white" name='import'
size="15px"></box-icon></el-button>
<el-button @click="$router.push('/manage/new')" type="primary"><box-icon color="white" name='plus'></box-icon></el-button>
</div>
</el-header>
<el-main id="wordsets-container">
<div class="colbox" if="sets-container">
<el-collapse accordion v-model="active_set_class" style="width: 100%;border: none;">
<el-collapse-item v-for="(set_class, class_name) in wordsets" :title="class_name" :key="class_name"
:name="class_name">
<div class="colbox wordclass">
<div v-for="(wordset, index) in set_class" :key="index" class="wordset rowbox">
<div class="no">
{{ index + 1 }}
</div>
<div class="title">
{{ wordset.name }}
</div>
<div style="font-size: 17px;font-weight: 200;">
创建日期{{ (new Date(wordset.created)).toLocaleString() }}
</div>
<div class="option">
<box-icon class="btn" name='edit' color="var(--text-color)"
@click="edit(wordset, class_name)"></box-icon>
<box-icon class="btn" name='trash' color="var(--text-color)"
@click="del(class_name, wordset.id, index)"></box-icon>
</div>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
</el-main>
</el-container>
</template>
<script>
import { ElNotification, ElMessage, ElMessageBox } from 'element-plus';
export default {
name: "SetList",
data() {
return {
wordsets:window.wordsets,
active_set_class: "",
}
},
methods:{
del(set_class_name, id, index) {
ElMessageBox.confirm("确定要删除吗?")
.then(() => {
localStorage.removeItem(id);
this.wordsets[set_class_name].splice(index, 1);
if (!this.wordsets[set_class_name].length) {
delete this.wordsets[set_class_name];
}
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElMessage(`已经删除 ${set_class_name} `);
});
},
edit(set, set_class_name) {
window.editing = {set,set_class_name};
this.$router.push({
path:"/manage/edit",
})
},
async export_set() {
let fileHandle = await window.showSaveFilePicker({
types: [
{
description: "JSON file",
accept: {
'text/json': ['.json'],
},
},
],
});
let writestream = await fileHandle.createWritable();
let data = {
wordsets: this.wordsets,
words: {}
};
for (let i of Object.values(this.wordsets)) {
for (let j of i) {
let temp = localStorage.getItem(j.id);
data.words[j.id] = temp;
}
}
writestream.write(JSON.stringify(data));
writestream.close();
},
async import_set() {
let [fileHandle] = await window.showOpenFilePicker({
types: [
{
description: "JSON file",
accept: {
'text/json': ['.json'],
},
},
],
});
let file = await fileHandle.getFile();
let data = JSON.parse(await file.text());
let cnt = 0;
for (let i of Object.keys(data.wordsets)) {
for (let j of data.wordsets[i]) {
if (!localStorage.getItem(j.id)) {
if (!this.wordsets[i]) this.wordsets[i] = [];
this.wordsets[i].push(j);
localStorage.setItem(j.id, data.words[j.id]);
cnt++;
}
}
}
localStorage.setItem("wordsets", JSON.stringify(this.wordsets));
ElNotification({
type: "success",
title: "添加成功",
message: `已添加 ${cnt} 本单词本`
});
}
},
created() {
this.active_set_class = Object.keys(this.wordsets)[0];
}
}
</script>
<style scoped>
.title {
font-weight: 800;
color: var(--text-color);
font-size: 35px;
flex-grow: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-height: 60px;
}
.option {
display: flex;
justify-content: space-around;
opacity: 0;
transition: .5s;
}
.wordset:hover .option{
opacity: 1;
}
#header {
/* border-bottom: solid 1px #bcbcbc; */
justify-content: space-between;
height: 40px;
}
.no {
font-size: 20px;
font-weight: 700;
}
#wordsets-container {
overflow-x: auto;
height: 100%;
}
#main-container {
height: 87%;
}
.wordclass {
flex-wrap: wrap
}
.card div {
margin-bottom: 10px;
}
</style>

View File

@ -1,12 +1,20 @@
import {createRouter,createWebHashHistory} from 'vue-router' import {createRouter,createWebHashHistory} from 'vue-router'
import editor from './components/Editor.vue' const manage = ()=>import('./components/Manage.vue');
import recite from './components/Recite.vue' const editor = ()=>import('./components/manage/Editor.vue');
import home from "./components/Home.vue" const home = ()=>import("./components/Home.vue");
const recite = ()=>import('./components/Recite.vue');
const setlist = ()=>import('./components/manage/SetList.vue');
const newset = ()=>import('./components/manage/NewSet.vue');
const routes = [ const routes = [
{ path: '/', component: home }, { path: '/', component: home },
{ path: '/recite', component: recite }, { path: '/recite', component: recite },
{ path: '/editor', component: editor }, { path: '/manage', component: manage,
children:[
{path: '',component:setlist},
{path: 'new',component:newset},
{path: 'edit',component:editor}
]},
] ]
export default createRouter({ export default createRouter({

View File

@ -1,4 +1,8 @@
const { defineConfig } = require('@vue/cli-service') const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({ module.exports = defineConfig({
transpileDependencies: true transpileDependencies: true,
publicPath:"./",
devServer: {
proxy: 'http://localhost:3000'
}
}) })