save
This commit is contained in:
@@ -8,7 +8,7 @@ import {groupBy} from "lodash-es";
|
||||
import {dictionaryResources} from "@/assets/dictionary.ts";
|
||||
import {Dict, DictResource, languageCategoryOptions} from "@/types.ts";
|
||||
import {onMounted} from "vue";
|
||||
import DictGroup from "@/components/list/DictGroup.vue";
|
||||
import DictGroup from "./components/DictGroup.vue";
|
||||
import router from "@/router.ts";
|
||||
|
||||
let index = $ref(1)
|
||||
|
||||
75
src/pages/mobile/components/DictGroup.vue
Normal file
75
src/pages/mobile/components/DictGroup.vue
Normal file
@@ -0,0 +1,75 @@
|
||||
<script setup lang="ts">
|
||||
import {$computed, $ref} from "vue/macros";
|
||||
import {watch} from "vue";
|
||||
import {DictResource} from "@/types.ts";
|
||||
import DictList from "./DictList.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
category: string,
|
||||
groupByTag: any,
|
||||
selectId: string
|
||||
}>()
|
||||
const emit = defineEmits<{
|
||||
selectDict: [val: { dict: DictResource, index: number }]
|
||||
detail: [],
|
||||
}>()
|
||||
const tagList = $computed(() => Object.keys(props.groupByTag))
|
||||
let currentTag = $ref(tagList[0])
|
||||
let list = $computed(() => {
|
||||
return props.groupByTag[currentTag]
|
||||
})
|
||||
|
||||
watch(() => props.groupByTag, () => {
|
||||
currentTag = tagList[0]
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dict-group">
|
||||
<div class="category">{{ category }}</div>
|
||||
<div class="tags">
|
||||
<div class="tag" :class="i === currentTag &&'active'"
|
||||
@click="currentTag = i"
|
||||
v-for="i in Object.keys(groupByTag)">{{ i }}
|
||||
</div>
|
||||
</div>
|
||||
<DictList
|
||||
@selectDict="e => emit('selectDict',e)"
|
||||
:list="list"
|
||||
:select-id="selectId"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dict-group {
|
||||
color: var(--color-font-1);
|
||||
margin-bottom: 40rem;
|
||||
//border-bottom: 1px dashed gray;
|
||||
|
||||
.category {
|
||||
font-size: 24rem;
|
||||
padding-bottom: 10rem;
|
||||
border-bottom: 1px dashed gray;
|
||||
}
|
||||
}
|
||||
|
||||
.tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin: 10rem 0;
|
||||
|
||||
.tag {
|
||||
color: var(--color-font-1);
|
||||
cursor: pointer;
|
||||
padding: 5rem 10rem;
|
||||
border-radius: 20rem;
|
||||
|
||||
&.active {
|
||||
color: var(--color-font-active-1);
|
||||
background: gray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
139
src/pages/mobile/components/DictItem.vue
Normal file
139
src/pages/mobile/components/DictItem.vue
Normal file
@@ -0,0 +1,139 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
import {Dict, DictType} from "@/types.ts";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {$computed} from "vue/macros";
|
||||
|
||||
const props = defineProps<{
|
||||
dict?: Dict,
|
||||
active?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectDict: [val: { dict: Dict, index: number }]
|
||||
add: []
|
||||
}>()
|
||||
|
||||
let length = $computed(() => {
|
||||
let isWord = [DictType.word,DictType.collect,DictType.simple,DictType.wrong].includes(props.dict.type)
|
||||
let len: any = ''
|
||||
if (props.dict.length) {
|
||||
len = props.dict.length
|
||||
len += (isWord ? '词' : '篇')
|
||||
} else {
|
||||
if (isWord) {
|
||||
len = props.dict.originWords.length + '词'
|
||||
} else {
|
||||
len = props.dict.articles.length + '篇'
|
||||
}
|
||||
}
|
||||
return len
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="dict-item anim"
|
||||
:class="active && 'active'"
|
||||
>
|
||||
<template v-if="dict.id">
|
||||
<div class="top">
|
||||
<div class="name">{{ dict.name }}</div>
|
||||
<div class="desc">{{ dict.description }}</div>
|
||||
</div>
|
||||
<div class="bottom">
|
||||
<div class="num">{{ length }}</div>
|
||||
</div>
|
||||
<div class="pin" v-if="dict.type === DictType.article">文章</div>
|
||||
</template>
|
||||
<div v-else class="add" @click.stop="emit('add')">
|
||||
<Icon icon="fluent:add-20-filled" width="38" color="#929596"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dict-item {
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
padding: 10rem;
|
||||
width: 30%;
|
||||
height: 165rem;
|
||||
border-radius: 10rem;
|
||||
position: relative;
|
||||
background: var(--color-third-bg);
|
||||
border: 1px solid var(--color-item-border);
|
||||
color: var(--color-font-1);
|
||||
font-size: 14rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
|
||||
.name {
|
||||
font-size: 16rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box; //作为弹性伸缩盒子模型显示。
|
||||
-webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
|
||||
-webkit-line-clamp: 2; //显示的行
|
||||
}
|
||||
|
||||
.desc {
|
||||
color: var(--color-font-2);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box; //作为弹性伸缩盒子模型显示。
|
||||
-webkit-box-orient: vertical; //设置伸缩盒子的子元素排列方式--从上到下垂直排列
|
||||
-webkit-line-clamp: 2; //显示的行
|
||||
}
|
||||
|
||||
.num {
|
||||
text-align: right;
|
||||
color: var(--color-font-2);
|
||||
//font-weight: bold;
|
||||
}
|
||||
|
||||
.go {
|
||||
position: absolute;
|
||||
right: 10rem;
|
||||
bottom: 15rem;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background: var(--color-item-active);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: var(--color-item-active);
|
||||
}
|
||||
|
||||
.add {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.pin {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
height: 55rem;
|
||||
width: 55rem;
|
||||
color: white;
|
||||
//background-color: skyblue;
|
||||
background-color: var(--color-main-active);
|
||||
clip-path: polygon(0 10%, 0% 100%, 100% 100%);
|
||||
font-size: 12rem;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: flex-end;
|
||||
padding: 4rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
35
src/pages/mobile/components/DictList.vue
Normal file
35
src/pages/mobile/components/DictList.vue
Normal file
@@ -0,0 +1,35 @@
|
||||
<script setup lang="ts">
|
||||
import {Dict} from "@/types.ts";
|
||||
import DictItem from "./DictItem.vue";
|
||||
|
||||
defineProps<{
|
||||
list?: Dict[],
|
||||
selectId?: string
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
selectDict: [val: { dict: any, index: number }]
|
||||
detail: [],
|
||||
add: []
|
||||
}>()
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dict-list">
|
||||
<DictItem v-for="(dict,index) in list"
|
||||
:active="selectId === dict.id"
|
||||
@click="emit('selectDict',{dict,index})"
|
||||
@add="emit('add')"
|
||||
:dict="dict"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.dict-list {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 15rem;
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user