refactor: 组件解耦 预览页支持展示全部功能按钮

This commit is contained in:
ZiuChen 2022-09-16 11:01:07 +08:00
parent e64d8051bf
commit 9d51968859
8 changed files with 137 additions and 152 deletions

View File

@ -3,20 +3,12 @@
<Transition name="fade">
<div class="clip-full-wrapper" v-show="isShow">
<div class="clip-full-operate-list">
<template v-for="{ id, name } of btns">
<div
class="clip-full-operate-list-item"
v-if="
id !== 'word-split' ||
(id === 'word-split' &&
fullData.type !== 'file' &&
fullData?.data?.length <= '\u0035\u0030\u0030')
"
@click="handleBtnClick(id)"
>
{{ name }}
</div>
</template>
<ClipOperate
:item="fullData"
:isFullData="true"
@onDataRemove="emit('onDataRemove')"
@onOperateExecute="emit('onOverlayClick')"
></ClipOperate>
</div>
<template v-if="fullData.type === 'text'">
<div class="clip-full-content" v-text="fullData.data"></div>
@ -32,6 +24,7 @@
<script setup>
import FileList from './FileList.vue'
import ClipOperate from './ClipOperate.vue'
import { onMounted } from 'vue'
const props = defineProps({
@ -45,32 +38,7 @@ const props = defineProps({
}
})
const emit = defineEmits(['onOverlayClick'])
const btns = [
{
id: 'copy-all',
name: '📄 复制全部'
},
{
id: 'word-split',
name: '🎁 智慧分词'
}
]
const handleBtnClick = (id) => {
switch (id) {
case 'copy-all':
window.copy(props.fullData)
emit('onOverlayClick') // 退
window.toTop()
break
case 'word-split':
utools.redirect('超级分词', props.fullData.data)
// fetchWordBreakResult(props.fullData.data)
break
}
}
const emit = defineEmits(['onOverlayClick', 'onDataRemove'])
const onOverlayClick = () => {
emit('onOverlayClick')

View File

@ -45,32 +45,12 @@
</template>
</div>
</div>
<div class="clip-operate" v-show="activeIndex === index && !isMultiple">
<template v-for="{ id, title, icon } of operation">
<div
v-if="
(id !== 'collect' &&
id !== 'view' &&
id !== 'open-folder' &&
id !== 'un-collect' &&
id !== 'word-break') ||
(id === 'collect' && item.collect !== true) ||
(id === 'view' && item.type !== 'image') ||
(id === 'open-folder' && item.type === 'file') ||
(id === 'un-collect' && item.collect === true) ||
(id === 'word-break' &&
item.type === 'text' &&
item.data.length <= 500 &&
item.data.length >= 2)
"
:class="id"
:title="title"
@click.stop="handleOperateClick({ id, item })"
>
{{ icon }}
</div>
</template>
</div>
<ClipOperate
v-show="isMultiple || activeIndex === index"
:item="item"
@onDataChange="() => emit('onDataChange', item)"
@onDataRemove="() => emit('onDataRemove')"
></ClipOperate>
<div class="clip-count" v-show="isMultiple || activeIndex !== index">
{{ index + 1 }}
</div>
@ -81,6 +61,7 @@
<script setup>
import { ref, onMounted, watch } from 'vue'
import FileList from './FileList.vue'
import ClipOperate from './ClipOperate.vue'
import { dateFormat } from '../utils'
const props = defineProps({
showList: {
@ -193,49 +174,6 @@ const handleItemClick = (ev, item) => {
}
const activeIndex = ref(0)
const handleMouseOver = (index) => (activeIndex.value = index)
const operation = [
{ id: 'copy', title: '复制', icon: '📄' },
{ id: 'view', title: '查看全部', icon: '💬' },
{ id: 'open-folder', title: '打开文件夹', icon: '📁' },
{ id: 'collect', title: '收藏', icon: '⭐' },
{ id: 'un-collect', title: '取消收藏', icon: '📤' },
{ id: 'word-break', title: '分词', icon: '💣' },
{ id: 'remove', title: '删除', icon: '❌' }
]
const handleOperateClick = ({ id, item }) => {
switch (id) {
case 'copy':
window.copy(item, false)
break
case 'view':
emit('onDataChange', item)
break
case 'open-folder':
const { data } = item
const fl = JSON.parse(data)
window.openFileFolder(fl[0].path) //
break
case 'collect':
item.collect = true
window.db.updateDataBaseLocal(db)
break
case 'word-break':
const success = utools.redirect('超级分词', item.data)
if (success) {
} else {
utools.shellOpenExternal('https://ziuchen.github.io/project/SmartWordBreak/')
}
break
case 'un-collect':
item.collect = undefined
window.db.updateDataBaseLocal(db)
break
case 'remove':
window.remove(item)
emit('onDataRemove')
break
}
}
// getter
watch(
() => props.showList,

90
src/cpns/ClipOperate.vue Normal file
View File

@ -0,0 +1,90 @@
<template>
<div class="clip-operate">
<template v-for="{ id, title, icon } of operation">
<div
v-if="
(id !== 'collect' &&
id !== 'view' &&
id !== 'open-folder' &&
id !== 'un-collect' &&
id !== 'word-break') ||
(id === 'collect' && item.collect !== true) ||
(id === 'view' && !isFullData && item.type !== 'image') ||
(id === 'open-folder' && item.type === 'file') ||
(id === 'un-collect' && item.collect === true) ||
(id === 'word-break' &&
item.type === 'text' &&
item.data.length <= 500 &&
item.data.length >= 2)
"
:class="id"
:title="title"
@click.stop="handleOperateClick({ id, item })"
>
{{ icon }}
</div>
</template>
</div>
</template>
<script setup>
const props = defineProps({
item: {
type: Object,
required: true
},
isFullData: {
type: Boolean,
default: false
}
})
const emit = defineEmits(['onDataChange', 'onDataRemove', 'onOperateExecute'])
const operation = [
{ id: 'copy', title: '复制', icon: '📄' },
{ id: 'view', title: '查看全部', icon: '💬' },
{ id: 'open-folder', title: '打开文件夹', icon: '📁' },
{ id: 'collect', title: '收藏', icon: '⭐' },
{ id: 'un-collect', title: '取消收藏', icon: '📤' },
{ id: 'word-break', title: '分词', icon: '💣' },
{ id: 'remove', title: '删除', icon: '❌' }
]
const handleOperateClick = ({ id, item }) => {
switch (id) {
case 'copy':
window.copy(item, false)
break
case 'view':
emit('onDataChange', item)
break
case 'open-folder':
const { data } = item
const fl = JSON.parse(data)
window.openFileFolder(fl[0].path) //
break
case 'collect':
item.collect = true
window.db.updateDataBaseLocal(db)
break
case 'word-break':
const success = utools.redirect('超级分词', item.data)
if (success) {
} else {
utools.shellOpenExternal('https://ziuchen.github.io/project/SmartWordBreak/')
}
break
case 'un-collect':
item.collect = undefined
window.db.updateDataBaseLocal(db)
break
case 'remove':
window.remove(item)
emit('onDataRemove')
break
}
emit('onOperateExecute')
}
</script>
<style lang="less" scoped>
@import '../style';
</style>

View File

@ -17,23 +17,9 @@
justify-content: flex-end;
color: @text-color;
background-color: @text-bg-color;
padding: 5px 10px;
padding: 5px 5px;
margin-bottom: 5px;
border-radius: 5px;
&-item {
padding: 10px;
border-radius: 5px;
cursor: pointer;
user-select: none;
margin: 5px 5px;
background-color: @bg-color;
transition: all 0.15s;
&:hover {
color: @bg-color;
background-color: @primary-color;
transition: all 0.15s;
}
}
}
.clip-full-content {
background-color: @text-bg-color;

View File

@ -86,32 +86,5 @@
color: @text-color-lighter;
padding: 10px;
}
.clip-operate {
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
min-width: 180px;
padding: 0px 10px;
flex-wrap: wrap;
& * {
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
color: @primary-color;
background: @text-bg-color;
margin: 0px 2px;
border-radius: 5px;
width: 30px;
height: 30px;
transition: all 0.15s;
&:hover {
color: @bg-color;
background: @primary-color;
transition: all 0.15s;
}
}
}
}
}

View File

@ -0,0 +1,28 @@
.clip-operate {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
min-width: 180px;
padding: 0px 10px;
flex-wrap: wrap;
& div {
display: flex;
align-items: center;
justify-content: center;
font-size: 13px;
color: @primary-color;
background: @text-bg-color;
cursor: pointer;
margin: 0px 2px;
border-radius: 5px;
width: 30px;
height: 30px;
transition: all 0.15s;
&:hover {
color: @bg-color;
background: @primary-color;
transition: all 0.15s;
}
}
}

View File

@ -3,6 +3,7 @@
@import (multiple) './cpns/clip-float-btn.less';
@import (multiple) './cpns/clip-full-data.less';
@import (multiple) './cpns/clip-item-list.less';
@import (multiple) './cpns/clip-operate.less';
@import (multiple) './cpns/clip-search.less';
@import (multiple) './cpns/clip-switch.less';
@import (multiple) './cpns/clip-word-break.less';

View File

@ -4,6 +4,7 @@
<ClipFullData
:isShow="fullDataShow"
:fullData="fullData"
@onDataRemove="handleDataRemove"
@onOverlayClick="toggleFullData({ type: 'text', data: '' })"
></ClipFullData>
<ClipSwitch ref="ClipSwitchRef" @onNavClick="handleNavClick">
@ -171,7 +172,7 @@ const handleNavClick = (type) => {
offset.value = 0 //
}
const fullData = ref({ type: 'text' })
const fullData = ref({ type: 'text', data: '' })
const fullDataShow = ref(false)
const toggleFullData = (item) => {
// ()