This commit is contained in:
zyronon
2024-06-11 02:33:47 +08:00
parent 5181d612b9
commit b4e16be6e6
6 changed files with 206 additions and 44 deletions

View File

@@ -17,11 +17,17 @@ const props = withDefaults(defineProps<{
activeId?: string,
isActive?: boolean
showBorder?: boolean
del?: Function
batchDel?: Function
add?: Function
}>(), {
activeIndex: -1,
activeId: '',
isActive: false,
showBorder: false,
del: () => void 0,
add: () => void 0,
batchDel: () => void 0
})
const emit = defineEmits<{
@@ -105,8 +111,13 @@ function sort(type: Sort) {
}
}
function handleBatchDel() {
props.batchDel(selectIds)
selectIds = []
}
const s = useSlots()
console.log('s', s)
defineRender(
() => {
const d = (item) => <el-checkbox
@@ -138,13 +149,13 @@ defineRender(
<div class="flex gap-2 relative">
{
selectIds.length ? <BaseIcon
onClick={emit('del')}
onClick={handleBatchDel}
class="del"
title="删除"
icon="solar:trash-bin-minimalistic-linear"/> : null
}
<BaseIcon
onClick={emit('add')}
onClick={props.add}
icon="fluent:add-20-filled"
title="添加单词"/>
<BaseIcon
@@ -183,26 +194,7 @@ defineRender(
<div class="list-item-wrapper"
key={item.id}
>
<div class="common-list-item"
>
<div class="left">
{s.default({checkbox: d, item})}
<div class="title-wrapper">
<div class="item-title">
<span class="word">{item.word}</span>
<span class="phonetic">{item.phonetic0}</span>
<VolumeIcon class="volume"></VolumeIcon>
</div>
<div class="item-sub-title">
</div>
</div>
</div>
<div class="right">
<slot name="suffix"
item={item} index={index}>
</slot>
</div>
</div>
{s.default({checkbox: d, item})}
</div>
)
})

View File

@@ -0,0 +1,151 @@
<script setup lang="ts">
import {Word} from "@/types.ts";
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
import {usePlayWordAudio} from "@/hooks/sound.ts";
const props = withDefaults(defineProps<{
item: Word,
showTranslate?: boolean
showWord?: boolean
}>(), {
showTranslate: true,
showWord: true
})
const playWordAudio = usePlayWordAudio()
</script>
<template>
<div class="word-item"
:class="{
border:true
}"
>
<div class="left">
<slot name="prefix" :item="item"></slot>
<div class="title-wrapper">
<div class="item-title">
<span class="word" :class="!showWord && 'word-shadow'">{{ item.word }}</span>
<span class="phonetic">{{ item.phonetic0 }}</span>
<VolumeIcon class="volume" @click="playWordAudio(item.word)"></VolumeIcon>
</div>
<div class="item-sub-title" v-if="item.trans.length && showTranslate">
<div v-for="v in item.trans">{{ (v.pos ? v.pos + '.' : '') + (v.cn || v.en) }}</div>
</div>
</div>
</div>
<div class="right">
<slot name="suffix" :item="item"></slot>
</div>
</div>
</template>
<style scoped lang="scss">
.word-item {
cursor: pointer;
width: 100%;
box-sizing: border-box;
background: var(--color-item-bg);
color: var(--color-font-1);
font-size: 1.1rem;
border-radius: .5rem;
display: flex;
justify-content: space-between;
transition: all .3s;
padding: .6rem;
gap: .6rem;
border: 1px solid var(--color-item-border);
.left {
display: flex;
gap: .6rem;
.title-wrapper {
display: flex;
flex-direction: column;
gap: .2rem;
word-break: break-word;
}
}
.right {
display: flex;
flex-direction: column;
gap: .3rem;
transition: all .3s;
}
.volume, .collect, .easy {
opacity: 0;
}
&:hover {
background: var(--color-item-hover);
.volume, .collect, .easy {
opacity: 1;
}
}
&.active {
background: var(--color-item-active);
$c: #E6A23C;
.phonetic, .item-sub-title {
color: var(--color-gray) !important;
}
.volume, .collect, .easy, .fill {
color: $c;
}
}
&.border {
&.active {
.item-title {
border-bottom: 2px solid gray !important;
}
}
.item-title {
transition: all .3s;
cursor: pointer;
border-bottom: 2px solid transparent;
}
&:hover {
.item-title {
border-bottom: 2px solid gray !important;
}
}
}
.item-title {
display: flex;
align-items: center;
gap: .5rem;
color: var(--color-font-1);
.word {
font-size: 1.2rem;
display: flex;
}
.phonetic {
font-size: .9rem;
color: gray;
}
}
.item-sub-title {
font-size: 1rem;
color: gray;
}
}
</style>

View File

@@ -1,6 +1,5 @@
<script setup lang="ts">
import {Word} from "@/types.ts";
import VolumeIcon from "@/components/icon/VolumeIcon.vue";
import BaseList from "@/pages/pc/components/list/BaseList.vue";

View File

@@ -10,6 +10,9 @@ import {nanoid} from "nanoid";
import BaseIcon from "@/components/BaseIcon.vue";
import {_checkDictWords, useNav} from "@/utils";
import BaseTable from "@/pages/pc/components/BaseTable.vue";
import WordItem from "@/pages/pc/components/WordItem.vue";
import type {Word} from "@/types.ts";
import type {FormInstance, FormRules} from "element-plus";
const runtimeStore = useRuntimeStore()
const store = useBaseStore()
@@ -31,7 +34,7 @@ onMounted(() => {
runtimeStore.editDict = cloneDeep(runtimeStore.routeData)
_checkDictWords(runtimeStore.editDict)
}
// break
break
case 0:
runtimeStore.editDict = cloneDeep(store.collectWord)
break
@@ -111,21 +114,18 @@ async function onSubmitWord() {
})
}
function delWord(val: {
item: Word
}) {
let rIndex2 = list.findIndex(v => v.id === val.item.id)
function delWord(id: string) {
let rIndex2 = list.findIndex(v => v.id === id)
if (rIndex2 > -1) {
list.splice(rIndex2, 1)
}
if (wordFormData.type === FormMode.Edit && wordForm.word === val.item.word) {
closeWordForm()
}
// if (wordFormData.type === FormMode.Edit && wordForm.word === val.item.word) {
// closeWordForm()
// }
}
function batchDelWord() {
console.log('multipleSelection', multipleSelection)
multipleSelection.map(v => delWord({item: v}))
function batchDel(ids: string[]) {
ids.map(v => delWord(v))
}
function editWord(word: Word,) {
@@ -149,16 +149,10 @@ function closeWordForm() {
}
defineRender(() => {
let d = (i) => {
console.log('i', i)
return <div>
{i.checkbox(i.item)}
</div>
}
return (
<BasePage>
<header class="flex gap-4 mb-2 items-center">
<BaseIcon onClick={back} icon="octicon:arrow-left-24" width="20"/>
<BaseIcon onClick={back} icon="octicon:arrow-left-24" width={20}/>
<div class="left">
<div class="top">
<div class="text-xl">
@@ -176,8 +170,32 @@ defineRender(() => {
<BaseTable
class="h-full"
list={list}
del={delWord}
batchDel={batchDel}
add={addWord}
>
{d}
{
(val) =>
<WordItem item={val.item}>
{{
prefix: () => val.checkbox(val.item),
suffix: () => (
<div class='flex flex-col'>
<BaseIcon
class="del"
onClick={() => editWord(val.item)}
title="编辑"
icon="tabler:edit"/>
<BaseIcon
class="del"
onClick={() => delWord(val.item.id)}
title="删除"
icon="solar:trash-bin-minimalistic-linear"/>
</div>
)
}}
</WordItem>
}
</BaseTable>
</div>
{

View File

@@ -65,6 +65,7 @@ export const DefaultBaseState = (): BaseState => ({
},
{
"id": "calculate",
"word": "calculate",
"trans": [
{
@@ -78,6 +79,7 @@ export const DefaultBaseState = (): BaseState => ({
"phonetic1": "ˈkælkjəˌlet"
},
{
"id": "compete",
"word": "compete",
"trans": [
{
@@ -88,6 +90,7 @@ export const DefaultBaseState = (): BaseState => ({
"phonetic1": "kəmˈpit"
},
{
"id": "furnish",
"word": "furnish",
"trans": [
{

View File

@@ -4,7 +4,6 @@ import jaFlag from "@/assets/img/flags/ja.png";
import deFlag from "@/assets/img/flags/de.png";
import codeFlag from "@/assets/img/flags/code.png";
import myFlag from "@/assets/img/flags/my.png";
import {DefaultChapterWordNumber} from "@/stores/setting.ts";
export type WordTrans = {
pos: string,