处理弹窗的放大缩小

This commit is contained in:
MTrun 2021-12-20 13:36:54 +08:00
parent f37ed1f3d3
commit 8dc4769b64
19 changed files with 345 additions and 106 deletions

View File

@ -12,15 +12,16 @@
"mockjs": "^1.1.0", "mockjs": "^1.1.0",
"naive-ui": "^2.19.9", "naive-ui": "^2.19.9",
"pinia": "^2.0.6", "pinia": "^2.0.6",
"screenfull": "^6.0.0",
"vue": "^3.2.16", "vue": "^3.2.16",
"vue-i18n": "^9.2.0-beta.23", "vue-i18n": "^9.2.0-beta.23",
"vue-router": "4.0.12" "vue-router": "4.0.12"
}, },
"devDependencies": { "devDependencies": {
"@vicons/ionicons5": "~0.11.0",
"@types/node": "^16.11.1", "@types/node": "^16.11.1",
"@typescript-eslint/eslint-plugin": "^5.6.0", "@typescript-eslint/eslint-plugin": "^5.6.0",
"@typescript-eslint/parser": "^5.6.0", "@typescript-eslint/parser": "^5.6.0",
"@vicons/ionicons5": "~0.11.0",
"@vitejs/plugin-vue": "^1.9.3", "@vitejs/plugin-vue": "^1.9.3",
"@vitejs/plugin-vue-jsx": "^1.2.0", "@vitejs/plugin-vue-jsx": "^1.2.0",
"@vue/compiler-sfc": "^3.2.20", "@vue/compiler-sfc": "^3.2.20",
@ -31,7 +32,7 @@
"eslint-plugin-import": "^2.25.3", "eslint-plugin-import": "^2.25.3",
"eslint-plugin-prettier": "^4.0.0", "eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.2.0", "eslint-plugin-vue": "^8.2.0",
"lodash": "^4.17.21", "lodash": "~4.17.21",
"prettier": "^2.5.1", "prettier": "^2.5.1",
"sass": "^1.43.2", "sass": "^1.43.2",
"sass-loader": "^12.2.0", "sass-loader": "^12.2.0",

15
pnpm-lock.yaml generated
View File

@ -16,13 +16,14 @@ specifiers:
eslint-plugin-import: ^2.25.3 eslint-plugin-import: ^2.25.3
eslint-plugin-prettier: ^4.0.0 eslint-plugin-prettier: ^4.0.0
eslint-plugin-vue: ^8.2.0 eslint-plugin-vue: ^8.2.0
lodash: ^4.17.21 lodash: ~4.17.21
mockjs: ^1.1.0 mockjs: ^1.1.0
naive-ui: ^2.19.9 naive-ui: ^2.19.9
pinia: ^2.0.6 pinia: ^2.0.6
prettier: ^2.5.1 prettier: ^2.5.1
sass: ^1.43.2 sass: ^1.43.2
sass-loader: ^12.2.0 sass-loader: ^12.2.0
screenfull: ^6.0.0
typescript: ^4.4.4 typescript: ^4.4.4
vite: ^2.6.10 vite: ^2.6.10
vite-plugin-importer: ^0.2.5 vite-plugin-importer: ^0.2.5
@ -34,11 +35,11 @@ specifiers:
vue-tsc: ^0.28.7 vue-tsc: ^0.28.7
dependencies: dependencies:
'@vicons/ionicons5': rg.cnpmjs.org/@vicons/ionicons5/0.11.0
axios: rg.cnpmjs.org/axios/0.23.0 axios: rg.cnpmjs.org/axios/0.23.0
mockjs: rg.cnpmjs.org/mockjs/1.1.0 mockjs: rg.cnpmjs.org/mockjs/1.1.0
naive-ui: rg.cnpmjs.org/naive-ui/2.21.5_vue@3.2.24 naive-ui: rg.cnpmjs.org/naive-ui/2.21.5_vue@3.2.24
pinia: rg.cnpmjs.org/pinia/2.0.6_typescript@4.5.2+vue@3.2.24 pinia: rg.cnpmjs.org/pinia/2.0.6_typescript@4.5.2+vue@3.2.24
screenfull: rg.cnpmjs.org/screenfull/6.0.0
vue: rg.cnpmjs.org/vue/3.2.24 vue: rg.cnpmjs.org/vue/3.2.24
vue-i18n: rg.cnpmjs.org/vue-i18n/9.2.0-beta.23_vue@3.2.24 vue-i18n: rg.cnpmjs.org/vue-i18n/9.2.0-beta.23_vue@3.2.24
vue-router: rg.cnpmjs.org/vue-router/4.0.12_vue@3.2.24 vue-router: rg.cnpmjs.org/vue-router/4.0.12_vue@3.2.24
@ -47,6 +48,7 @@ devDependencies:
'@types/node': rg.cnpmjs.org/@types/node/16.11.12 '@types/node': rg.cnpmjs.org/@types/node/16.11.12
'@typescript-eslint/eslint-plugin': rg.cnpmjs.org/@typescript-eslint/eslint-plugin/5.6.0_16d83f5c41c3abb1061a82b07c18e4f3 '@typescript-eslint/eslint-plugin': rg.cnpmjs.org/@typescript-eslint/eslint-plugin/5.6.0_16d83f5c41c3abb1061a82b07c18e4f3
'@typescript-eslint/parser': rg.cnpmjs.org/@typescript-eslint/parser/5.6.0_eslint@8.4.1+typescript@4.5.2 '@typescript-eslint/parser': rg.cnpmjs.org/@typescript-eslint/parser/5.6.0_eslint@8.4.1+typescript@4.5.2
'@vicons/ionicons5': rg.cnpmjs.org/@vicons/ionicons5/0.11.0
'@vitejs/plugin-vue': rg.cnpmjs.org/@vitejs/plugin-vue/1.10.2_vite@2.7.1 '@vitejs/plugin-vue': rg.cnpmjs.org/@vitejs/plugin-vue/1.10.2_vite@2.7.1
'@vitejs/plugin-vue-jsx': rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1 '@vitejs/plugin-vue-jsx': rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1
'@vue/compiler-sfc': rg.cnpmjs.org/@vue/compiler-sfc/3.2.24 '@vue/compiler-sfc': rg.cnpmjs.org/@vue/compiler-sfc/3.2.24
@ -877,7 +879,7 @@ packages:
resolution: {integrity: sha1-VBhb+lcqCd9wCU2xlU8ov78TY+0=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vicons/ionicons5/download/@vicons/ionicons5-0.11.0.tgz} resolution: {integrity: sha1-VBhb+lcqCd9wCU2xlU8ov78TY+0=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vicons/ionicons5/download/@vicons/ionicons5-0.11.0.tgz}
name: '@vicons/ionicons5' name: '@vicons/ionicons5'
version: 0.11.0 version: 0.11.0
dev: false dev: true
rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1: rg.cnpmjs.org/@vitejs/plugin-vue-jsx/1.3.1:
resolution: {integrity: sha512-Ku0pnlG0CuFfkvwOe3TEHS7noqBIBR61JbdvH6F6i3IqJv8+0+tcyusR+EoFwi7YrA2vdP26oorWyGv3wDt5kg==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vitejs/plugin-vue-jsx/download/@vitejs/plugin-vue-jsx-1.3.1.tgz} resolution: {integrity: sha512-Ku0pnlG0CuFfkvwOe3TEHS7noqBIBR61JbdvH6F6i3IqJv8+0+tcyusR+EoFwi7YrA2vdP26oorWyGv3wDt5kg==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/@vitejs/plugin-vue-jsx/download/@vitejs/plugin-vue-jsx-1.3.1.tgz}
@ -3729,6 +3731,13 @@ packages:
immutable: rg.cnpmjs.org/immutable/4.0.0 immutable: rg.cnpmjs.org/immutable/4.0.0
dev: true dev: true
rg.cnpmjs.org/screenfull/6.0.0:
resolution: {integrity: sha1-b383v+GcXuUJMaxDjB/jgNW1/0Q=, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/screenfull/download/screenfull-6.0.0.tgz}
name: screenfull
version: 6.0.0
engines: {node: ^14.13.1 || >=16.0.0}
dev: false
rg.cnpmjs.org/seemly/0.3.3: rg.cnpmjs.org/seemly/0.3.3:
resolution: {integrity: sha512-mAyqemz41e9HiZPMXAn7NtTExJgztwco5cdZjrt/iViU/oFeav+Q8K1c93M/tIZZ00QkT65JMr4xXQk7Vv5hWQ==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/seemly/download/seemly-0.3.3.tgz} resolution: {integrity: sha512-mAyqemz41e9HiZPMXAn7NtTExJgztwco5cdZjrt/iViU/oFeav+Q8K1c93M/tIZZ00QkT65JMr4xXQk7Vv5hWQ==, registry: http://r.cnpmjs.org/, tarball: https://rg.cnpmjs.org/seemly/download/seemly-0.3.3.tgz}
name: seemly name: seemly

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="go-apple-control-btn"> <div class="go-apple-control-btn">
<template v-for="item in btnList" :key="item.key"> <template v-for="item in filterBtnList" :key="item.key">
<div <div
class="btn" class="btn"
:class="[item.key, disabled && 'disabled']" :class="[item.key, disabled && 'disabled']"
@ -14,13 +14,28 @@
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { renderIcon } from '@/utils/index'
import { icon } from '@/plugins' import { icon } from '@/plugins'
import { computed } from 'vue'
import { screenfullFn } from '@/utils'
const emit = defineEmits(['close', 'remove', 'resize']) const emit = defineEmits(['close', 'remove', 'resize', 'fullResize'])
const props = defineProps({ const props = defineProps({
//
disabled: { disabled: {
request: false,
type: Boolean,
default: false
},
//
hidden: {
request: false,
type: Array,
default: []
},
// 使
narrow: {
request: false,
type: Boolean, type: Boolean,
default: false default: false
} }
@ -28,6 +43,16 @@ const props = defineProps({
const { CloseIcon, RemoveIcon, ResizeIcon } = icon.ionicons5 const { CloseIcon, RemoveIcon, ResizeIcon } = icon.ionicons5
const filterBtnList = computed(() => {
const res = btnList.filter(e => {
return props.hidden.findIndex(p => e.key == p) === -1
})
return res
})
const isFull = computed(() => {
return props.narrow && screenfullFn(true)
})
const btnList = [ const btnList = [
{ {
title: '关闭', title: '关闭',
@ -40,14 +65,16 @@ const btnList = [
icon: RemoveIcon icon: RemoveIcon
}, },
{ {
title: '放大', title: isFull ? '缩小' : '放大',
key: 'resize', key: props.narrow ? 'fullResize' : 'resize',
icon: ResizeIcon icon: ResizeIcon
} }
] ]
const handleClick = (key: 'close' | 'remove' | 'resize') => { const handleClick = (key: 'close' | 'remove' | 'resize' | 'fullResize') => {
console.log(key) if (key === 'fullResize') screenfullFn()
//
if (key === 'remove') screenfullFn(true) && screenfullFn()
emit(key) emit(key)
} }
</script> </script>
@ -74,7 +101,7 @@ const handleClick = (key: 'close' | 'remove' | 'resize') => {
font-weight: bold; font-weight: bold;
border-radius: 50%; border-radius: 50%;
&.disabled { &.disabled {
pointer-events:none; pointer-events: none;
} }
.icon-base { .icon-base {
opacity: 0; opacity: 0;
@ -89,7 +116,8 @@ const handleClick = (key: 'close' | 'remove' | 'resize') => {
.remove { .remove {
background-color: $--color-warn; background-color: $--color-warn;
} }
.resize { .resize,
.fullResize {
background-color: $--color-success; background-color: $--color-success;
} }
} }

View File

@ -1,7 +1,7 @@
//语言 //语言
import { lang } from '@/settings/designSetting' import { lang } from '@/settings/designSetting'
import { createI18n } from 'vue-i18n' //引入vue-i18n组件 import { createI18n } from 'vue-i18n' //引入vue-i18n组件
import { getLocalStorage } from '@/utils/index' import { getLocalStorage } from '@/utils/storage'
import { GO_LANG_SELECT } from '@/settings/storageConst' import { GO_LANG_SELECT } from '@/settings/storageConst'
import zh from './zh/index' import zh from './zh/index'
import en from './en/index' import en from './en/index'

View File

@ -6,10 +6,11 @@ import {
CopyOutline as CopyIcon, CopyOutline as CopyIcon,
Trash as TrashIcon, Trash as TrashIcon,
Pencil as PencilIcon, Pencil as PencilIcon,
Hammer as HammerIcon, HammerOutline as HammerIcon,
ApertureSharp as ApertureSharpIcon, ApertureSharp as ApertureSharpIcon,
DownloadOutline as DownloadIcon, DownloadOutline as DownloadIcon,
Open as OpenIcon Open as OpenIcon,
Send as SendIcon
} from '@vicons/ionicons5' } from '@vicons/ionicons5'
// ionicons5 在这里 // ionicons5 在这里
@ -35,7 +36,9 @@ const ionicons5 = {
// 下载 // 下载
DownloadIcon, DownloadIcon,
// 导出 // 导出
OpenIcon OpenIcon,
// 导出
SendIcon,
} }
// https://www.xicons.org/#/ 还有很多 // https://www.xicons.org/#/ 还有很多

View File

@ -41,7 +41,7 @@ export const theme = {
// 默认是否开启深色主题 // 默认是否开启深色主题
darkTheme: true, darkTheme: true,
//系统主题色 //系统主题色
appTheme: '#63e2b7', appTheme: '#51d6a9',
//系统内置主题色列表 //系统内置主题色列表
appThemeList appThemeList
} }
@ -53,7 +53,7 @@ export const asideWidth = '270'
export const asideCollapsedWidth = '60' export const asideCollapsedWidth = '60'
// 修改边框圆角 // 修改边框圆角
export const borderRadius = '4px' export const borderRadius = '6px'
// 轮播间隔 // 轮播间隔
export const carouselInterval = 4000 export const carouselInterval = 4000

View File

@ -2,7 +2,7 @@ import { defineStore } from 'pinia'
import { store } from '@/store' import { store } from '@/store'
import { theme } from '@/settings/designSetting' import { theme } from '@/settings/designSetting'
import { DesignStateType } from './designStore.d' import { DesignStateType } from './designStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils/index' import { setLocalStorage, getLocalStorage } from '@/utils/storage'
import { GO_Theme_SELECT } from '@/settings/storageConst' import { GO_Theme_SELECT } from '@/settings/storageConst'
import { ThemeEnum } from '@/enums/styleEnum' import { ThemeEnum } from '@/enums/styleEnum'

View File

@ -3,7 +3,7 @@ import { lang } from '@/settings/designSetting'
import { LangStateType } from './langStore.d' import { LangStateType } from './langStore.d'
import { LangEnum } from '@/enums/styleEnum' import { LangEnum } from '@/enums/styleEnum'
import i18n from '@/i18n/index' import i18n from '@/i18n/index'
import { setLocalStorage } from '@/utils/index' import { setLocalStorage } from '@/utils/storage'
import { GO_LANG_SELECT } from '@/settings/storageConst' import { GO_LANG_SELECT } from '@/settings/storageConst'
export const useLangStore = defineStore({ export const useLangStore = defineStore({

View File

@ -3,11 +3,13 @@
$light: ( $light: (
// 文字颜色 // 文字颜色
color: $--color-text, color: $--color-text,
// aside 背景
aside-background_color: $--color-light-fill-1,
//背景 //背景
background_color: $--color-light-fill-3, background_color: $--color-light-fill-3,
//渐变背景 //渐变背景
background-image: background-image:
linear-gradient(120deg, $--color-text-1 0%, $--color-text-1 100%), linear-gradient(120deg, $--color-light-fill 0%, $--color-light-fill 100%),
// 斑点背景 // 斑点背景
background-point: background-point:
( (

View File

@ -12,7 +12,7 @@ $--color-text-4: #f2f3f5;
// 白色 // 白色
$--color-light-fill: #fff; $--color-light-fill: #fff;
$--color-light-fill-1: #f7f8fa; $--color-light-fill-1: #fafafc;
$--color-light-fill-2: #f2f3f5; $--color-light-fill-2: #f2f3f5;
$--color-light-fill-3: #e5e6eb; $--color-light-fill-3: #e5e6eb;
$--color-light-fill-4: #c9cdd4; $--color-light-fill-4: #c9cdd4;

View File

@ -1,6 +1,6 @@
import { h } from 'vue' import { h } from 'vue'
import { NIcon } from 'naive-ui' import { NIcon } from 'naive-ui'
import screenfull from 'screenfull'
/** /**
* * ID * * ID
* @param { Number } randomLength * @param { Number } randomLength
@ -64,56 +64,17 @@ export const requireUrl = (path: string, name: string) => {
return new URL(`${path}/${name}`, import.meta.url).href return new URL(`${path}/${name}`, import.meta.url).href
} }
/** export const screenfullFn = (isFullscreen?: boolean, isEnabled?: boolean) => {
* * // 是否是全屏
* @param k if (isFullscreen) return screenfull.isFullscreen
* @param v
* @returns RemovableRef
*/
export const setLocalStorage = <T>(k: string, v: T) => {
try {
window.localStorage.setItem(k, JSON.stringify(v))
} catch (error) {
return false
}
}
/** // 是否支持全屏
* * if (isEnabled) return screenfull.isEnabled
* @returns any
*/
export const getLocalStorage: (k: string) => any = (k: string) => {
const item = window.localStorage.getItem(k)
try {
return item ? JSON.parse(item) : item
} catch (err) {
return item
}
}
/** if (screenfull.isEnabled) {
* * screenfull.toggle()
* @param k return
* @param v
* @returns RemovableRef
*/
export const setSessionStorage = <T>(k: string, v: T) => {
try {
window.sessionStorage.setItem(k, JSON.stringify(v))
} catch (error) {
return false
}
}
/**
* *
* @returns any
*/
export const getSessionStorage: (k: string) => any = (k: string) => {
const item = window.sessionStorage.getItem(k)
try {
return item ? JSON.parse(item) : item
} catch (err) {
return item
} }
// TODO lang
window['$message'].warning('您的浏览器不支持全屏功能!')
} }

54
src/utils/storage.ts Normal file
View File

@ -0,0 +1,54 @@
/**
* *
* @param k
* @param v
* @returns RemovableRef
*/
export const setLocalStorage = <T>(k: string, v: T) => {
try {
window.localStorage.setItem(k, JSON.stringify(v))
} catch (error) {
return false
}
}
/**
* *
* @returns any
*/
export const getLocalStorage: (k: string) => any = (k: string) => {
const item = window.localStorage.getItem(k)
try {
return item ? JSON.parse(item) : item
} catch (err) {
return item
}
}
/**
* *
* @param k
* @param v
* @returns RemovableRef
*/
export const setSessionStorage = <T>(k: string, v: T) => {
try {
window.sessionStorage.setItem(k, JSON.stringify(v))
} catch (error) {
return false
}
}
/**
* *
* @returns any
*/
export const getSessionStorage: (k: string) => any = (k: string) => {
const item = window.sessionStorage.getItem(k)
try {
return item ? JSON.parse(item) : item
} catch (err) {
return item
}
}

View File

@ -4,37 +4,41 @@
<div class="list-content"> <div class="list-content">
<!-- 顶部按钮 --> <!-- 顶部按钮 -->
<n-space class="list-content-top"> <n-space class="list-content-top">
<AppleControlBtn @close="deleteHanlde" /> <AppleControlBtn @close="deleteHanlde" @resize="resizeHandle" />
</n-space> </n-space>
<!-- 中间 --> <!-- 中间 -->
<div class="list-content-img"> <div class="list-content-img">
<n-image <n-image
object-fit="contain" object-fit="contain"
height="200" height="200"
preview-disabled
:src="requireUrl('.', '20211219181327.png')" :src="requireUrl('.', '20211219181327.png')"
:alt="CardData.title" :alt="cardData.title"
/> />
</div> </div>
</div> </div>
<template #action> <template #action>
<Skeleton v-if="loading" :loading="loading" text round size="small" /> <n-space class="list-footer" justify="space-between">
<n-space v-else justify="space-between">
<n-text> <n-text>
{{ CardData.title || '' }} {{ cardData.title || '' }}
</n-text> </n-text>
<!-- 工具 --> <!-- 工具 -->
<n-space> <n-space>
<n-text> <n-text>
<n-badge class="animation-twinkle" dot :color="CardData.release ? '#34c749' : '#fcbc40'" /> <n-badge
{{ CardData.release ? '已发布' : '未发布' }} class="animation-twinkle"
dot
:color="cardData.release ? '#34c749' : '#fcbc40'"
/>
{{ cardData.release ? '已发布' : '未发布' }}
</n-text> </n-text>
<template v-for="item in fnBtnList" :key="item.key"> <template v-for="item in fnBtnList" :key="item.key">
<template v-if="item.key === 'select'"> <template v-if="item.key === 'select'">
<n-dropdown <n-dropdown
trigger="hover" trigger="hover"
placement="bottom-start" placement="bottom"
:options="selectOptions" :options="selectOptions"
:show-arrow="true" :show-arrow="true"
@select="handleSelect" @select="handleSelect"
@ -47,12 +51,17 @@
</n-dropdown> </n-dropdown>
</template> </template>
<n-button v-else size="small"> <n-tooltip v-else placement="bottom" trigger="hover">
<template #trigger>
<n-button size="small">
<template #icon> <template #icon>
<component :is="item.icon" /> <component :is="item.icon" />
</template> </template>
</n-button> </n-button>
</template> </template>
<span> {{ item.label }}</span>
</n-tooltip>
</template>
</n-space> </n-space>
<!-- end --> <!-- end -->
</n-space> </n-space>
@ -73,17 +82,26 @@ const {
TrashIcon, TrashIcon,
PencilIcon, PencilIcon,
ApertureSharpIcon, ApertureSharpIcon,
DownloadIcon DownloadIcon,
HammerIcon,
SendIcon
} = icon.ionicons5 } = icon.ionicons5
const loading = ref<boolean>(true)
const dialog = useDialog() const dialog = useDialog()
const message = useMessage() const message = useMessage()
defineProps({
CardData: Object const emit = defineEmits(['resize'])
const props = defineProps({
cardData: Object
}) })
const fnBtnList = [ const fnBtnList = [
{
label: '编辑',
key: 'edit',
icon: renderIcon(HammerIcon)
},
{ {
lable: '更多', lable: '更多',
key: 'select', key: 'select',
@ -107,6 +125,15 @@ const selectOptions = [
key: 'rename', key: 'rename',
icon: renderIcon(PencilIcon) icon: renderIcon(PencilIcon)
}, },
{
type: 'divider',
key: 'd1'
},
{
label: props.cardData?.release ? '取消发布' : '发布',
key: 'send',
icon: renderIcon(SendIcon)
},
{ {
label: '下载', label: '下载',
key: 'download', key: 'download',
@ -114,7 +141,7 @@ const selectOptions = [
}, },
{ {
type: 'divider', type: 'divider',
key: 'd1' key: 'd2'
}, },
{ {
label: '删除', label: '删除',
@ -131,6 +158,7 @@ const requireUrl = (path: string, name: string) => {
return new URL(`${path}/${name}`, import.meta.url).href return new URL(`${path}/${name}`, import.meta.url).href
} }
//
const deleteHanlde = () => { const deleteHanlde = () => {
goDialog(dialog.warning, { goDialog(dialog.warning, {
type: 'delete', type: 'delete',
@ -140,9 +168,10 @@ const deleteHanlde = () => {
}) })
} }
setTimeout(() => { //
loading.value = false const resizeHandle = () => {
}, 1500) emit('resize', props.cardData)
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -157,7 +186,7 @@ $contentHeight: 200px;
@extend .go-point-bg; @extend .go-point-bg;
&-top { &-top {
position: absolute; position: absolute;
top: 5px; top: 10px;
left: 10px; left: 10px;
height: 22px; height: 22px;
} }
@ -172,5 +201,8 @@ $contentHeight: 200px;
} }
} }
} }
.list-footer {
line-height: 30px;
}
} }
</style> </style>

View File

@ -7,24 +7,21 @@
responsive="screen" responsive="screen"
> >
<n-grid-item v-for="item in list" :key="item.id"> <n-grid-item v-for="item in list" :key="item.id">
<Card :CardData="item" /> <Card :cardData="item" @resize="resizeHandle" />
</n-grid-item> </n-grid-item>
</n-grid> </n-grid>
</div> </div>
<ModalCard :show="modalShow" :cardData="modalData" @close="closeModal" />
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { reactive, ref } from 'vue' import { reactive, ref } from 'vue'
import { Card } from '../Card/index' import { Card } from '../Card/index'
import { ModalCard } from '../ModalCard/index'
import { import {
EllipsisHorizontalSharp as EllipsisHorizontalCircleSharpIcon, EllipsisHorizontalSharp as EllipsisHorizontalCircleSharpIcon,
CopyOutline as CopyIcon CopyOutline as CopyIcon
} from '@vicons/ionicons5' } from '@vicons/ionicons5'
const loading = ref<boolean>(true)
setTimeout(() => {
loading.value = false
}, 500)
const list = reactive([ const list = reactive([
{ {
@ -34,21 +31,40 @@ const list = reactive([
}, },
{ {
id: 2, id: 2,
title: '物料1' title: '物料2',
release: false
}, },
{ {
id: 3, id: 3,
title: '物料1' title: '物料3',
release: false
}, },
{ {
id: 4, id: 4,
title: '物料1' title: '物料4',
release: false
}, },
{ {
id: 5, id: 5,
title: '物料1' title: '物料5',
release: false
} }
]) ])
const modalData = ref({})
const modalShow = ref(false)
// modal
const closeModal = () => {
modalShow.value = false
}
// modal
const resizeHandle = (cardData: object) => {
modalShow.value = true
modalData.value = cardData
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

@ -0,0 +1,3 @@
import ModalCard from './index.vue'
export { ModalCard }

View File

@ -0,0 +1,127 @@
<template>
<n-modal class="go-modal-card" v-model:show="showModal">
<slot name="default">
<n-card hoverable size="small">
<div class="list-content">
<!-- 顶部按钮 -->
<n-space class="list-content-top">
<AppleControlBtn
:narrow="true"
:hidden="['close']"
@remove="closeHandle"
/>
</n-space>
<!-- 中间 -->
<div class="list-content-img">
<img
:src="requireUrl('.', '20211219181327.png')"
:alt="cardData?.title"
/>
</div>
</div>
<template #action>
<n-space class="list-footer" justify="space-between">
<n-text>
{{ cardData?.title || '' }}
</n-text>
<!-- 工具 -->
<n-space>
<n-text>
<n-badge
class="animation-twinkle"
dot
:color="cardData?.release ? '#34c749' : '#fcbc40'"
/>
{{ cardData?.release ? '已发布' : '未发布' }}
</n-text>
<template v-for="item in fnBtnList" :key="item.key">
<n-tooltip placement="bottom" trigger="hover">
<template #trigger>
<n-button size="small">
<template #icon>
<component :is="item.icon" />
</template>
</n-button>
</template>
<span> {{ item.label }}</span>
</n-tooltip>
</template>
</n-space>
<!-- end -->
</n-space>
</template>
</n-card>
</slot>
</n-modal>
</template>
<script setup lang="ts">
import { renderIcon } from '@/utils/index'
import { icon } from '@/plugins'
import { AppleControlBtn } from '@/components/AppleControlBtn'
const { HammerIcon } = icon.ionicons5
const emit = defineEmits(['close'])
const props = defineProps({
modalShow: Boolean,
cardData: Object
})
const handleSelect = (key: string) => {
console.log(key)
}
const requireUrl = (path: string, name: string) => {
return new URL(`${path}/${name}`, import.meta.url).href
}
const fnBtnList = [
{
label: '编辑',
key: 'edit',
icon: renderIcon(HammerIcon)
}
]
//
const resizeHandle = () => {}
//
const closeHandle = () => {
emit('close')
}
</script>
<style lang="scss" scoped>
$padding: 30px;
$contentHeight: calc(80vh);
@include go('modal-card') {
position: relative;
width: 82vw;
.list-content {
margin-top: 20px;
border-radius: $--border-radius-base;
overflow: hidden;
@include background-point('background-point');
@extend .go-point-bg;
&-top {
position: absolute;
top: 10px;
left: 10px;
height: 22px;
}
&-img {
@extend .go-flex-center;
img {
height: $contentHeight;
@extend .go-border-radius;
}
}
}
.list-footer {
line-height: 30px;
}
}
</style>

View File

@ -1,6 +1,6 @@
<template> <template>
<n-layout-sider <n-layout-sider
class="go-project-layout-sider" class="go-project-sider"
bordered bordered
collapse-mode="width" collapse-mode="width"
show-trigger="bar" show-trigger="bar"
@ -68,6 +68,7 @@ $siderHeight: 100vh;
@include go(project) { @include go(project) {
&-sider { &-sider {
@include filter-bg-color('aside-background_color');
&-top { &-top {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -3,3 +3,5 @@ declare module '*.vue' {
const component: DefineComponent<{}, {}, any> const component: DefineComponent<{}, {}, any>
export default component export default component
} }
declare module 'lodash'