mirror of
https://github.com/ZiuChen/ClipboardManager.git
synced 2025-06-29 05:33:14 +08:00
refactor: 组件解耦 预览页支持展示全部功能按钮
This commit is contained in:
parent
e64d8051bf
commit
9d51968859
@ -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')
|
||||
|
@ -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
90
src/cpns/ClipOperate.vue
Normal 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>
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
28
src/style/cpns/clip-operate.less
Normal file
28
src/style/cpns/clip-operate.less
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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';
|
||||
|
@ -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) => {
|
||||
// 是否显示全部数据 (查看全部)
|
||||
|
Loading…
x
Reference in New Issue
Block a user