🚧 development of image display interfaces
This commit is contained in:
12
components.d.ts
vendored
12
components.d.ts
vendored
@@ -45,6 +45,7 @@ declare module 'vue' {
|
||||
ASkeleton: typeof import('ant-design-vue/es')['Skeleton']
|
||||
ASpace: typeof import('ant-design-vue/es')['Space']
|
||||
ASpin: typeof import('ant-design-vue/es')['Spin']
|
||||
ASwitch: typeof import('ant-design-vue/es')['Switch']
|
||||
ATabPane: typeof import('ant-design-vue/es')['TabPane']
|
||||
ATabs: typeof import('ant-design-vue/es')['Tabs']
|
||||
ATag: typeof import('ant-design-vue/es')['Tag']
|
||||
@@ -64,7 +65,10 @@ declare module 'vue' {
|
||||
Carousel: typeof import('./src/components/MyUI/Carousel/Carousel.vue')['default']
|
||||
Cascader: typeof import('./src/components/MyUI/Cascader/Cascader.vue')['default']
|
||||
Checkbox: typeof import('./src/components/MyUI/Checkbox/Checkbox.vue')['default']
|
||||
CheckCard: typeof import('./src/components/MyUI/CheckCard/CheckCard.vue')['default']
|
||||
CheckOutlined: typeof import('@ant-design/icons-vue')['CheckOutlined']
|
||||
CloseCircleOutlined: typeof import('@ant-design/icons-vue')['CloseCircleOutlined']
|
||||
CloseOutlined: typeof import('@ant-design/icons-vue')['CloseOutlined']
|
||||
Clouds: typeof import('./src/components/Clouds/Clouds.vue')['default']
|
||||
Col: typeof import('./src/components/MyUI/Grid/Col.vue')['default']
|
||||
Collapse: typeof import('./src/components/MyUI/Collapse/Collapse.vue')['default']
|
||||
@@ -74,9 +78,11 @@ declare module 'vue' {
|
||||
CompareImage: typeof import('./src/views/Upscale/CompareImage.vue')['default']
|
||||
Countdown: typeof import('./src/components/MyUI/Countdown/Countdown.vue')['default']
|
||||
DatePicker: typeof import('./src/components/MyUI/DatePicker/DatePicker.vue')['default']
|
||||
DeleteOutlined: typeof import('@ant-design/icons-vue')['DeleteOutlined']
|
||||
Descriptions: typeof import('./src/components/MyUI/Descriptions/Descriptions.vue')['default']
|
||||
Dialog: typeof import('./src/components/MyUI/Dialog/Dialog.vue')['default']
|
||||
Divider: typeof import('./src/components/MyUI/Divider/Divider.vue')['default']
|
||||
DownloadOutlined: typeof import('@ant-design/icons-vue')['DownloadOutlined']
|
||||
Drawer: typeof import('./src/components/MyUI/Drawer/Drawer.vue')['default']
|
||||
DynamicTitle: typeof import('./src/components/DynamicTitle/DynamicTitle.vue')['default']
|
||||
Ellipsis: typeof import('./src/components/MyUI/Ellipsis/Ellipsis.vue')['default']
|
||||
@@ -90,9 +96,11 @@ declare module 'vue' {
|
||||
GradientText: typeof import('./src/components/MyUI/GradientText/GradientText.vue')['default']
|
||||
Image: typeof import('./src/components/MyUI/Image/Image.vue')['default']
|
||||
ImageShare: typeof import('./src/views/ImageShare/ImageShare.vue')['default']
|
||||
ImageWaterfall: typeof import('./src/components/MyUI/Waterfall/ImageWaterfall.vue')['default']
|
||||
Input: typeof import('./src/components/MyUI/Input/Input.vue')['default']
|
||||
InputSearch: typeof import('./src/components/MyUI/InputSearch/InputSearch.vue')['default']
|
||||
LandingPage: typeof import('./src/views/Landing/LandingPage.vue')['default']
|
||||
LazyImage: typeof import('./src/components/MyUI/LazyImage/LazyImage.vue')['default']
|
||||
List: typeof import('./src/components/MyUI/List/List.vue')['default']
|
||||
LoadingBar: typeof import('./src/components/MyUI/LoadingBar/LoadingBar.vue')['default']
|
||||
LoadingGraphic: typeof import('./src/components/LoadingGraphic/LoadingGraphic.vue')['default']
|
||||
@@ -113,6 +121,7 @@ declare module 'vue' {
|
||||
Phoalbum: typeof import('./src/views/Album/Phoalbum/Phoalbum.vue')['default']
|
||||
PhoneUpload: typeof import('./src/views/PhoneUpload/PhoneUpload.vue')['default']
|
||||
PlusOutlined: typeof import('@ant-design/icons-vue')['PlusOutlined']
|
||||
PlusSquareOutlined: typeof import('@ant-design/icons-vue')['PlusSquareOutlined']
|
||||
Popconfirm: typeof import('./src/components/MyUI/Popconfirm/Popconfirm.vue')['default']
|
||||
Popover: typeof import('./src/components/MyUI/Popover/Popover.vue')['default']
|
||||
Progress: typeof import('./src/components/MyUI/Progress/Progress.vue')['default']
|
||||
@@ -135,6 +144,7 @@ declare module 'vue' {
|
||||
Segmented: typeof import('./src/components/MyUI/Segmented/Segmented.vue')['default']
|
||||
Select: typeof import('./src/components/MyUI/Select/Select.vue')['default']
|
||||
SendOutlined: typeof import('@ant-design/icons-vue')['SendOutlined']
|
||||
ShareAltOutlined: typeof import('@ant-design/icons-vue')['ShareAltOutlined']
|
||||
Skeleton: typeof import('./src/components/MyUI/Skeleton/Skeleton.vue')['default']
|
||||
Slider: typeof import('./src/components/MyUI/Slider/Slider.vue')['default']
|
||||
Space: typeof import('./src/components/MyUI/Space/Space.vue')['default']
|
||||
@@ -162,6 +172,6 @@ declare module 'vue' {
|
||||
Video: typeof import('./src/components/MyUI/Video/Video.vue')['default']
|
||||
VueCompareImage: typeof import('./src/components/VueCompareImage/VueCompareImage.vue')['default']
|
||||
WarningOutlined: typeof import('@ant-design/icons-vue')['WarningOutlined']
|
||||
Waterfall: typeof import('./src/components/MyUI/Waterfall/Waterfall.vue')['default']
|
||||
Waterfall: typeof import('./src/components/MyUI/Waterfall/ImageWaterfall.vue')['default']
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@ import pluginVue from "eslint-plugin-vue";
|
||||
import {fileURLToPath} from "node:url";
|
||||
import {dirname, resolve} from "path";
|
||||
import {readFileSync} from "node:fs";
|
||||
import vueI18n from '@intlify/eslint-plugin-vue-i18n';
|
||||
// 动态读取 .eslintrc-auto-import.json 文件内容
|
||||
const autoImportConfig = JSON.parse(
|
||||
readFileSync(
|
||||
@@ -14,6 +15,7 @@ const autoImportConfig = JSON.parse(
|
||||
);
|
||||
|
||||
export default [
|
||||
...vueI18n.configs['flat/recommended'],
|
||||
{files: ["**/*.{js,mjs,cjs,ts,vue}"]},
|
||||
{languageOptions: {globals: {...globals.browser, ...globals.node, ...autoImportConfig.globals}}},
|
||||
pluginJs.configs.recommended,
|
||||
@@ -37,6 +39,26 @@ export default [
|
||||
"ignoreRestSiblings": true
|
||||
}
|
||||
],
|
||||
'@intlify/vue-i18n/no-dynamic-keys': 'error',
|
||||
'@intlify/vue-i18n/no-unused-keys': [
|
||||
'error',
|
||||
{
|
||||
extensions: ['.ts', '.vue']
|
||||
}
|
||||
],
|
||||
"@intlify/vue-i18n/no-duplicate-keys-in-locale": [
|
||||
"error",
|
||||
{
|
||||
"ignoreI18nBlock": false
|
||||
}
|
||||
],
|
||||
"@intlify/vue-i18n/no-raw-text": 'off',
|
||||
},
|
||||
settings: {
|
||||
'vue-i18n': {
|
||||
localeDir: '/src/locales/language/*.{ts}',
|
||||
messageSyntaxVersion: '^9.0.0'
|
||||
}
|
||||
}
|
||||
}
|
||||
];
|
||||
|
12
package.json
12
package.json
@@ -12,6 +12,7 @@
|
||||
"dependencies": {
|
||||
"@alova/adapter-axios": "^2.0.12",
|
||||
"@ant-design/icons-vue": "^7.0.1",
|
||||
"@intlify/eslint-plugin-vue-i18n": "^3.2.0",
|
||||
"@tensorflow/tfjs": "^4.22.0",
|
||||
"@tensorflow/tfjs-backend-webgl": "^4.22.0",
|
||||
"@tensorflow/tfjs-backend-webgpu": "^4.22.0",
|
||||
@@ -53,8 +54,9 @@
|
||||
"vite-plugin-node-polyfills": "^0.22.0",
|
||||
"vue": "^3.5.13",
|
||||
"vue-dompurify-html": "^5.2.0",
|
||||
"vue-i18n": "^10.0.5",
|
||||
"vue-i18n": "^11.0.1",
|
||||
"vue-router": "^4.5.0",
|
||||
"vue-waterfall-plugin-next": "^2.6.4",
|
||||
"ws": "^8.18.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -63,12 +65,12 @@
|
||||
"eslint-plugin-vue": "^9.32.0",
|
||||
"globals": "^15.14.0",
|
||||
"sass": "^1.83.0",
|
||||
"typescript": "^5.6.3",
|
||||
"typescript-eslint": "^8.18.1",
|
||||
"typescript": "^5.7.2",
|
||||
"typescript-eslint": "^8.18.2",
|
||||
"unplugin-vue-components": "^0.28.0",
|
||||
"vite": "^6.0.5",
|
||||
"vite": "^6.0.6",
|
||||
"vite-plugin-bundle-obfuscator": "1.4.0",
|
||||
"vite-plugin-chunk-split": "^0.5.0",
|
||||
"vue-tsc": "2.1.10"
|
||||
"vue-tsc": "2.2.0"
|
||||
}
|
||||
}
|
||||
|
@@ -3,9 +3,9 @@
|
||||
:locale="lang.lang === 'en' ? enUS : zhCN"
|
||||
:theme="app.themeConfig"
|
||||
>
|
||||
<router-view v-slot="{ Component, route }">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="animation" mode="out-in">
|
||||
<component :is="Component" :key="route.path"/>
|
||||
<component :is="Component"/>
|
||||
</transition>
|
||||
</router-view>
|
||||
</AConfigProvider>
|
||||
|
BIN
src/assets/gif/loading.gif
Normal file
BIN
src/assets/gif/loading.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 752 KiB |
1
src/assets/svgs/cancle.svg
Normal file
1
src/assets/svgs/cancle.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1735317945913" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="42606" width="200" height="200"><path d="M518.9632 930.6112a424.704 424.704 0 1 1 424.96-424.704 424.96 424.96 0 0 1-424.96 424.704z m0-757.248a332.544 332.544 0 1 0 332.8 332.8 332.8 332.8 0 0 0-332.8-332.8z" fill="#FC5B67" p-id="42607"></path><path d="M683.2128 551.9872H354.7648a46.08 46.08 0 0 1 0-92.16h328.448a46.08 46.08 0 0 1 0 92.16z" fill="#FC5B67" p-id="42608"></path></svg>
|
After Width: | Height: | Size: 501 B |
1
src/assets/svgs/complete.svg
Normal file
1
src/assets/svgs/complete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1735317843676" class="icon" viewBox="0 0 1040 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="37944" width="200" height="200"><path d="M32 512a496 488 90 1 0 976 0 496 488 90 1 0-976 0Z" fill="#3770EB" p-id="37945"></path><path d="M485.344 755.968L251.504 522.16l98.576-98.592 140.288 140.272L736.864 317.392l93.536 93.52-345.072 345.056z" fill="#FFFFFF" p-id="37946"></path></svg>
|
After Width: | Height: | Size: 403 B |
1
src/assets/svgs/grey-complete.svg
Normal file
1
src/assets/svgs/grey-complete.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1735315086517" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="14336" width="200" height="200"><path d="M736 336zM336 736h-0.01 0.02-0.01zM688 736h0.01-0.01zM736 688z" fill="#666666" p-id="14337"></path><path d="M512 64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.57 448-448S759.42 64 512 64z m220.62 346.18L472.4 670.39a40 40 0 0 1-56.57 0L291.38 545.94a40 40 0 0 1 0-56.57 40 40 0 0 1 56.57 0l96.17 96.17 231.93-231.93a40 40 0 0 1 56.57 0 40 40 0 0 1 0 56.57z" fill="#999999" p-id="14338"></path><path d="M732.62 353.61a40 40 0 0 0-56.57 0L444.12 585.54 348 489.37a40 40 0 0 0-56.57 0 40 40 0 0 0 0 56.57l124.4 124.45a40 40 0 0 0 56.57 0l260.22-260.21a40 40 0 0 0 0-56.57z" fill="#FFFFFF" p-id="14339"></path></svg>
|
After Width: | Height: | Size: 780 B |
1
src/assets/svgs/no-image.svg
Normal file
1
src/assets/svgs/no-image.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1735358313214" class="icon" viewBox="0 0 1166 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4000" width="200" height="200"><path d="M842.731517 407.355404a109.993623 109.993623 0 0 0 0-155.693942c-42.970688-42.897198-112.576274-42.844705-155.504967 0.094487-42.918195 42.949691-42.918195 112.555276 0 155.504967 42.918195 42.939192 112.523781 42.981187 155.504967 0.094488zM619.699683 768.076115l3.370044-4.304418-4.28342 4.304418-36.556056-46.918154-173.97197-223.934712a54.529625 54.529625 0 0 0-87.442673 0L72.818151 797.325159V146.549679a68.849688 68.849688 0 0 1 64.293304-73.12261h391.754514l31.49574-73.427069H145.636302C65.049202 0.503932 0 65.962578 0 146.549679v731.205101c0.167977 80.5871 65.364159 145.909265 145.940761 146.24522h294.758133l204.911285-201.394261-25.910496-54.529624z" fill="#A9A9A9" p-id="4001"></path><path d="M1020.650953 0H698.155572l-38.057353 73.427069h360.552734a78.602869 78.602869 0 0 1 72.818151 73.12261v648.045849l-175.189805-223.934712a57.920666 57.920666 0 0 0-95.67356-7.328009l-120.450208 121.048628 67.148918 75.474292-143.904037 264.144273h395.250541c80.461117-0.503932 145.468325-65.784102 145.636302-146.24522V146.549679C1166.287255 65.962578 1101.238053 0.503932 1020.650953 0z" fill="#A9A9A9" p-id="4002"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/svgs/upload-1.svg
Normal file
1
src/assets/svgs/upload-1.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1735134309122" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8818" width="200" height="200"><path d="M512 1024c282.760533 0 512-229.239467 512-512 0-282.760533-229.239467-512-512-512C229.239467 0 0 229.239467 0 512c0 282.760533 229.239467 512 512 512z m103.8336-680.618667c4.983467 5.597867 23.722667 25.2928 5.802667 37.5808-17.885867 12.288-33.450667-10.171733-39.150934-16.554666l-47.4112-51.541334v249.070934s0 30.651733-23.2448 31.095466c-23.278933 0.477867-23.278933-32.938667-23.278933-32.938666V312.900267l-47.377067 51.5072c-5.7344 6.382933-29.354667 22.493867-39.594666 10.308266-10.24-12.219733 0.443733-25.736533 5.461333-31.300266l81.5104-93.184a31.163733 31.163733 0 0 1 46.523733 0.034133l80.759467 93.149867z m104.721067 373.691734v-157.4912c0-17.408-1.365333-31.505067 15.940266-31.505067 17.271467 0 15.36 14.097067 15.36 31.505067v157.4912a31.402667 31.402667 0 0 1-31.300266 31.505066H304.5376a31.402667 31.402667 0 0 1-31.300267-31.505066v-157.4912c0-17.408 0.341333-31.505067 17.6128-31.505067 17.3056 0 17.169067 14.097067 17.169067 31.505067v157.4912H720.554667z" fill="#8FD2C7" p-id="8819"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
187
src/components/MyUI/CheckCard/CheckCard.vue
Normal file
187
src/components/MyUI/CheckCard/CheckCard.vue
Normal file
@@ -0,0 +1,187 @@
|
||||
<template>
|
||||
<div class="check-card" :class="{ 'selected': isSelected }" @click="handleClick" :style="cardStyle">
|
||||
<div class="hover-circle" @click.stop="toggleSelection"
|
||||
v-if="showHoverCircle"
|
||||
:style="{ width: iconSize + 'px', height: iconSize + 'px' }">
|
||||
<img :src="greyComplete" alt="Hover" class="hover-icon"
|
||||
:style="{ width: iconSize + 'px', height: iconSize + 'px' }"/>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="card-selected-icon" v-if="isSelected" :class="iconPositionClass"
|
||||
:style="{ width: iconSize + 'px', height: iconSize + 'px' }">
|
||||
<img :src="icon" alt="Selected" class="selected-icon"
|
||||
@click.stop="toggleSelection"
|
||||
:style="{ width: iconSize + 'px', height: iconSize + 'px' }"/>
|
||||
<img :src="cancel" alt="Delete" class="delete-icon" @click.stop="toggleSelection"
|
||||
:style="{ width: iconSize + 'px', height: iconSize + 'px' }"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import complete from '@/assets/svgs/complete.svg';
|
||||
import cancel from '@/assets/svgs/cancle.svg';
|
||||
import greyComplete from '@/assets/svgs/grey-complete.svg';
|
||||
|
||||
interface Props {
|
||||
value: string | number;
|
||||
modelValue?: (string | number)[];
|
||||
icon?: string;
|
||||
iconPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
|
||||
margin?: string;
|
||||
borderRadius?: string;
|
||||
backgroundColor?: string;
|
||||
showHoverCircle?: boolean; // 控制是否显示悬停圆环
|
||||
iconSize?: number; // 控制图标大小
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
icon: complete,
|
||||
iconPosition: 'top-left',
|
||||
margin: '16px',
|
||||
borderRadius: '8px',
|
||||
backgroundColor: '#e5eeff',
|
||||
showHoverCircle: true, // 默认显示悬停圆环
|
||||
iconSize: 24, // 默认图标大小
|
||||
});
|
||||
|
||||
const emits = defineEmits(['update:modelValue']);
|
||||
|
||||
const isSelected = computed(() => {
|
||||
return props.modelValue?.includes(props.value);
|
||||
});
|
||||
|
||||
const iconPositionClass = computed(() => {
|
||||
return `icon-${props.iconPosition}`;
|
||||
});
|
||||
|
||||
const cardStyle = computed(() => {
|
||||
return {
|
||||
margin: props.margin,
|
||||
borderRadius: props.borderRadius,
|
||||
backgroundColor: props.backgroundColor,
|
||||
};
|
||||
});
|
||||
|
||||
function handleClick() {
|
||||
if (!props.showHoverCircle) {
|
||||
toggleSelection();
|
||||
}
|
||||
}
|
||||
|
||||
function toggleSelection() {
|
||||
if (isSelected.value) {
|
||||
emits('update:modelValue', props.modelValue?.filter((val) => val !== props.value));
|
||||
} else {
|
||||
emits('update:modelValue', [...(props.modelValue || []), props.value]);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.check-card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.3s, background-color 0.3s;
|
||||
overflow: visible; /* Ensure the icon is not cut off */
|
||||
}
|
||||
.check-card.selected {
|
||||
border: 1px solid rgba(125, 167, 255, 0.68);
|
||||
box-shadow: 0 0 2px rgba(77, 167, 255, 0.89);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.card-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.card-selected-icon {
|
||||
position: absolute;
|
||||
background-color: white;
|
||||
border-radius: 50%; /* Optional: Make it circular */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: 1px solid #ccc; /* Optional: Add a border */
|
||||
}
|
||||
|
||||
.icon-top-left {
|
||||
top: 3px;
|
||||
left: 3px;
|
||||
}
|
||||
|
||||
.icon-top-right {
|
||||
top: 3px;
|
||||
right: 3px;
|
||||
}
|
||||
|
||||
.icon-bottom-left {
|
||||
bottom: 3px;
|
||||
left: 3px;
|
||||
}
|
||||
|
||||
.icon-bottom-right {
|
||||
bottom: 3px;
|
||||
right: 3px;
|
||||
}
|
||||
|
||||
.card-selected-icon img {
|
||||
z-index: 3; /* Ensure the icon is on top */
|
||||
}
|
||||
|
||||
.selected-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.delete-icon {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.card-selected-icon:hover .selected-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-selected-icon:hover .delete-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hover-circle {
|
||||
position: absolute;
|
||||
top: 3px; /* 与 .card-selected-icon 的 top 值相同 */
|
||||
left: 3px; /* 与 .card-selected-icon 的 left 值相同 */
|
||||
border: 2px solid white; /* 与 .card-selected-icon 的 border 值相同 */
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
background-color: transparent;
|
||||
z-index: 1; /* Ensure the hover circle is on top */
|
||||
opacity: 0;
|
||||
transform: scale(0); /* 初始状态为0 */
|
||||
transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; /* 添加动画效果 */
|
||||
}
|
||||
|
||||
.hover-circle .hover-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.check-card:hover .hover-circle {
|
||||
opacity: 1; /* 鼠标悬停时变为可见 */
|
||||
transform: scale(1); /* 鼠标悬停时放大到1倍 */
|
||||
}
|
||||
|
||||
.check-card:hover .hover-circle .hover-icon {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.check-card.selected:hover .hover-circle {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
@@ -156,7 +156,7 @@ function onChecked() {
|
||||
|
||||
&:not(.checkbox-disabled):hover {
|
||||
.checkbox-box {
|
||||
border-color: @themeColor;
|
||||
border-color: #40a9ff;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -195,8 +195,8 @@ function onChecked() {
|
||||
}
|
||||
|
||||
.checkbox-checked {
|
||||
background-color: @themeColor;
|
||||
border-color: @themeColor;
|
||||
background-color: #40a9ff;
|
||||
border-color: #40a9ff;
|
||||
|
||||
&::after {
|
||||
opacity: 1;
|
||||
@@ -211,7 +211,7 @@ function onChecked() {
|
||||
left: 50%;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background-color: @themeColor;
|
||||
background-color: #40a9ff;
|
||||
border: 0;
|
||||
transform: translate(-50%, -50%) scale(1);
|
||||
opacity: 1;
|
||||
|
@@ -70,7 +70,7 @@ const showAfter = computed(() => {
|
||||
return slotsExist.addonAfter || props.addonAfter;
|
||||
});
|
||||
const lazyInput = computed(() => {
|
||||
return 'lazy' in props.valueModifiers;
|
||||
return 'lazy.ts' in props.valueModifiers;
|
||||
});
|
||||
|
||||
function onInput(e: InputEvent) {
|
||||
|
@@ -70,7 +70,7 @@ const showBefore = computed(() => {
|
||||
return slotsExist.addonBefore || props.addonBefore;
|
||||
});
|
||||
const lazyInput = computed(() => {
|
||||
return 'lazy' in props.valueModifiers;
|
||||
return 'lazy.ts' in props.valueModifiers;
|
||||
});
|
||||
|
||||
function onInput(e: InputEvent) {
|
||||
|
@@ -67,7 +67,7 @@ const showCountNum = computed(() => {
|
||||
return props.value.length;
|
||||
});
|
||||
const lazyTextarea = computed(() => {
|
||||
return 'lazy' in props.valueModifiers;
|
||||
return 'lazy.ts' in props.valueModifiers;
|
||||
});
|
||||
watch(
|
||||
() => props.value,
|
||||
|
@@ -9,5 +9,5 @@ import lazyLoad from "@/directives/v-lazy-load.ts";
|
||||
*/
|
||||
export const registerDirectives = (app: any) => {
|
||||
app.directive('click-outside', clickOutside);
|
||||
app.directive('lazy-load', lazyLoad);
|
||||
app.directive('lazy.ts-load', lazyLoad);
|
||||
};
|
||||
|
@@ -11,13 +11,13 @@
|
||||
@select="handleClick"
|
||||
>
|
||||
<AMenuItemGroup :title="t('album.photo')" type="group" key="photo">
|
||||
<AMenuItem :title="t('album.allAlbums')" key="photo/all">
|
||||
<AMenuItem :title="t('album.allAlbums')" key="photo/all" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="allPhoto"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.allAlbums') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.recentUploads')" key="photo/recent">
|
||||
<AMenuItem :title="t('album.recentUploads')" key="photo/recent" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="recentUpload"/>
|
||||
</template>
|
||||
@@ -25,25 +25,25 @@
|
||||
</AMenuItem>
|
||||
</AMenuItemGroup>
|
||||
<AMenuItemGroup :title="t('album.albums')" key="album">
|
||||
<AMenuItem :title="t('album.albums')" key="album/albums">
|
||||
<AMenuItem :title="t('album.albums')" key="album/albums" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="album"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.albums') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.peopleAlbums')" key="album/people">
|
||||
<AMenuItem :title="t('album.peopleAlbums')" key="album/people" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="peopleAlbum"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.peopleAlbums') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.locationAlbums')" key="album/location">
|
||||
<AMenuItem :title="t('album.locationAlbums')" key="album/location" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="loactionAlbum"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.locationAlbums') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.thingsAlbums')" key="album/thing">
|
||||
<AMenuItem :title="t('album.thingsAlbums')" key="album/thing" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="thingAlbum"/>
|
||||
</template>
|
||||
@@ -51,19 +51,19 @@
|
||||
</AMenuItem>
|
||||
</AMenuItemGroup>
|
||||
<ADivider/>
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/share">
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/share" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="share"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.share') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/recycling">
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/recycling" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="recyclingbin"/>
|
||||
</template>
|
||||
<span class="ant-menu-item-title">{{ t('album.recyclingBin') }}</span>
|
||||
</AMenuItem>
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/upscale">
|
||||
<AMenuItem :title="t('album.recyclingBin')" key="photo/upscale" :style="menuCSSStyle">
|
||||
<template #icon>
|
||||
<AAvatar shape="square" size="small" :src="ai"/>
|
||||
</template>
|
||||
@@ -101,8 +101,6 @@ const {t} = useI18n();
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* handle click event of menu item
|
||||
* @param key
|
||||
@@ -111,6 +109,32 @@ function handleClick({key}) {
|
||||
router.push(`/main/${key}`);
|
||||
}
|
||||
|
||||
const menuCSSStyle: any = reactive({
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
});
|
||||
|
||||
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
scrollToSelectedMenuItem();
|
||||
}
|
||||
);
|
||||
|
||||
// scroll to selected menu item
|
||||
function scrollToSelectedMenuItem() {
|
||||
nextTick(() => {
|
||||
const selected = document.querySelector(`.ant-menu-item-selected`);
|
||||
if (selected) {
|
||||
selected.scrollIntoView({behavior: 'smooth', block: 'center'});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
scrollToSelectedMenuItem();
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss" src="./index.scss">
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
width: 220px;
|
||||
height: calc(100vh - 271px);
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||
overflow-y: scroll;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
background-color: #fff;
|
||||
|
||||
|
@@ -28,17 +28,13 @@
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import useStore from "@/store";
|
||||
// import {h, onMounted, onUnmounted} from "vue";
|
||||
import Header from "@/layout/default/Header/Header.vue";
|
||||
// import {notification} from "ant-design-vue";
|
||||
// import {SmileOutlined} from "@ant-design/icons-vue";
|
||||
import Sidebar from "@/layout/default/Sidebar/Sidebar.vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import translation from '@/assets/svgs/translation.svg';
|
||||
import darkMode from '@/assets/svgs/dark-mode.svg';
|
||||
import other from '@/assets/svgs/other.svg';
|
||||
// const websocket = useStore().websocket;
|
||||
// const userInfo = useStore().user;
|
||||
|
||||
const lang = useStore().lang;
|
||||
const {locale} = useI18n();
|
||||
|
||||
@@ -50,24 +46,6 @@ async function changeLanguage() {
|
||||
locale.value = lang.lang;
|
||||
}
|
||||
|
||||
// const wsOptions = {
|
||||
// url: import.meta.env.VITE_MESSAGE_SOCKET_URL + "?user_id=" + userInfo.user.uid + "&token=" + userInfo.user.access_token,
|
||||
// };
|
||||
//
|
||||
// onMounted(() => {
|
||||
// websocket.initialize(wsOptions);
|
||||
// websocket.on("message", async (data: any) => {
|
||||
// notification.open({
|
||||
// message: '消息来了',
|
||||
// description:
|
||||
// data,
|
||||
// icon: () => h(SmileOutlined, {style: 'color: #108ee9'}),
|
||||
// });
|
||||
// });
|
||||
// });
|
||||
// onUnmounted(() => {
|
||||
// websocket.close(false);
|
||||
// });
|
||||
</script>
|
||||
<style scoped lang="less" src="./index.scss">
|
||||
|
||||
|
@@ -1,9 +1,276 @@
|
||||
<template>
|
||||
<div class="all-photo">
|
||||
<div class="photo-header">
|
||||
<AButton type="primary" shape="round" size="middle">
|
||||
<template #icon>
|
||||
<PlusOutlined/>
|
||||
</template>
|
||||
上传照片
|
||||
</AButton>
|
||||
<AButton type="default" shape="round" size="middle">
|
||||
<template #icon>
|
||||
<PlusSquareOutlined/>
|
||||
</template>
|
||||
创建相册
|
||||
</AButton>
|
||||
</div>
|
||||
<transition name="slide-fade">
|
||||
<div v-show="selected.length !== 0" class="photo-toolbar-header">
|
||||
<div class="photo-toolbar-left">
|
||||
<AButton type="text" shape="circle" size="large" class="photo-toolbar-btn">
|
||||
<template #icon>
|
||||
<CloseOutlined class="photo-toolbar-icon"/>
|
||||
</template>
|
||||
</AButton>
|
||||
<span style="font-size: 16px;font-weight: bold">
|
||||
已选择 {{ selected.length }} 张照片
|
||||
</span>
|
||||
<AButton type="text" shape="default" class="photo-toolbar-btn" size="middle">
|
||||
全选
|
||||
</AButton>
|
||||
</div>
|
||||
<div class="photo-toolbar-right">
|
||||
<AButton type="text" shape="default" size="middle" class="photo-toolbar-btn">
|
||||
<template #icon>
|
||||
<PlusSquareOutlined class="photo-toolbar-icon"/>
|
||||
</template>
|
||||
添加到
|
||||
</AButton>
|
||||
<AButton type="text" shape="default" size="middle" class="photo-toolbar-btn">
|
||||
<template #icon>
|
||||
<DownloadOutlined class="photo-toolbar-icon"/>
|
||||
</template>
|
||||
下载原图
|
||||
</AButton>
|
||||
<AButton type="text" shape="default" size="middle" class="photo-toolbar-btn">
|
||||
<template #icon>
|
||||
<ShareAltOutlined class="photo-toolbar-icon"/>
|
||||
</template>
|
||||
分享
|
||||
</AButton>
|
||||
<AButton type="text" shape="default" size="middle" class="photo-toolbar-btn">
|
||||
<template #icon>
|
||||
<DeleteOutlined class="photo-toolbar-icon"/>
|
||||
</template>
|
||||
删除
|
||||
</AButton>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
<div class="photo-list">
|
||||
<ATabs size="small" :tabBarGutter="50" type="line" tabPosition="top" :tabBarStyle="{position:'unset'}"
|
||||
style="width: 99%;">
|
||||
<template #rightExtra>
|
||||
<ASwitch size="small" v-model:checked="switchValue"/>
|
||||
</template>
|
||||
<ATabPane key="1" tab="全部">
|
||||
<div style="width:100%;height:100%;" v-if="images.length !== 0">
|
||||
<span style="margin-left: 10px;font-size: 13px">2024年12月27日 星期日</span>
|
||||
<AImagePreviewGroup>
|
||||
<Waterfall :list="images"
|
||||
:backgroundColor="`transparent`"
|
||||
:width="400"
|
||||
:gutter="15"
|
||||
align="left"
|
||||
:lazyload="true"
|
||||
:animationDelay="300"
|
||||
:animationDuration="1000"
|
||||
:animationCancel="false"
|
||||
:hasAroundGutter="true"
|
||||
rowKey="id"
|
||||
:imgSelector="'src'"
|
||||
:loadProps="loadProps"
|
||||
:breakpoints="breakpoints">
|
||||
<template #default="{ item, url, index }">
|
||||
<CheckCard :key="index"
|
||||
margin="0"
|
||||
border-radius="0"
|
||||
v-model="selected"
|
||||
:showHoverCircle="true"
|
||||
:iconSize="20"
|
||||
:value="url">
|
||||
<AImage :src="url"
|
||||
:alt="item.title"
|
||||
:key="index"
|
||||
:previewMask="false"
|
||||
loading="lazy"/>
|
||||
</CheckCard>
|
||||
</template>
|
||||
</Waterfall>
|
||||
</AImagePreviewGroup>
|
||||
</div>
|
||||
</ATabPane>
|
||||
<ATabPane key="2" tab="视频">
|
||||
<div style="width:100%;height:100%;">
|
||||
|
||||
</div>
|
||||
</ATabPane>
|
||||
<ATabPane key="3" tab="动图">
|
||||
|
||||
</ATabPane>
|
||||
<ATabPane key="4" tab="截图">
|
||||
|
||||
</ATabPane>
|
||||
</ATabs>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {Waterfall} from 'vue-waterfall-plugin-next';
|
||||
import 'vue-waterfall-plugin-next/dist/style.css';
|
||||
import loading from '@/assets/gif/loading.gif';
|
||||
import error from '@/assets/svgs/no-image.svg';
|
||||
|
||||
const selected = ref<(string | number)[]>([]);
|
||||
const switchValue = ref<boolean>(false);
|
||||
const breakpoints = reactive({
|
||||
breakpoints: {
|
||||
1200: {
|
||||
// 当屏幕宽度小于等于1200
|
||||
rowPerView: 4,
|
||||
},
|
||||
800: {
|
||||
// 当屏幕宽度小于等于800
|
||||
rowPerView: 3,
|
||||
},
|
||||
500: {
|
||||
// 当屏幕宽度小于等于500
|
||||
rowPerView: 2,
|
||||
},
|
||||
},
|
||||
});
|
||||
const loadProps = reactive({
|
||||
loading,
|
||||
error,
|
||||
ratioCalculator: (_width: number, _height: number) => {
|
||||
// 我设置了最小宽高比
|
||||
const minRatio = 3 / 4;
|
||||
const maxRatio = 4 / 3;
|
||||
return Math.random() > 0.5 ? minRatio : maxRatio;
|
||||
},
|
||||
});
|
||||
|
||||
const images = ref<any[]>([]);
|
||||
|
||||
function loadImages() {
|
||||
for (let i = 1; i < 10; i++) {
|
||||
images.value.push({
|
||||
title: `image-${i}`,
|
||||
link: '',
|
||||
src: `https://cdn.jsdelivr.net/gh/themusecatcher/resources@0.0.5/${i}.jpg`,
|
||||
tag: '全部',
|
||||
date: '2022-01-01',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
onBeforeMount(() => { // 组件已完成响应式状态设置,但未创建DOM节点
|
||||
loadImages();
|
||||
});
|
||||
</script>
|
||||
<style scoped lang="scss" src="./index.scss">
|
||||
<style scoped lang="scss">
|
||||
.all-photo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: relative;
|
||||
|
||||
.photo-header {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid #e2e2e2;
|
||||
|
||||
}
|
||||
|
||||
.photo-toolbar-header {
|
||||
position: fixed;
|
||||
width: calc(100% - 220px);
|
||||
height: 70px;
|
||||
top: 70px;
|
||||
z-index: 3;
|
||||
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background-image: linear-gradient(45deg, #5789ff, #5c7bff 100%);
|
||||
color: #fff;
|
||||
box-shadow: 0 3px 10px 0 rgba(0, 0, 0, .06);
|
||||
padding: 0 20px;
|
||||
|
||||
|
||||
.photo-toolbar-left {
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 20px;
|
||||
|
||||
}
|
||||
|
||||
.photo-toolbar-right {
|
||||
height: 100%;
|
||||
width: 50%;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: 30px;
|
||||
}
|
||||
|
||||
.photo-toolbar-icon {
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.photo-toolbar-btn {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.photo-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
height: calc(100% - 65px);
|
||||
}
|
||||
}
|
||||
|
||||
.slide-fade-enter-active, .slide-fade-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.slide-fade-enter-from, .slide-fade-leave-to { /* .slide-fade-leave-active 在离开之前 */
|
||||
transform: translateY(-20px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-fade-enter-from {
|
||||
transform: translateY(-30px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.slide-fade-enter-to {
|
||||
transform: translateY(0);
|
||||
opacity: 1;
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,7 +1,35 @@
|
||||
<template>
|
||||
<div class="recent-upload">
|
||||
<div class="photo-header">
|
||||
<AButton type="primary" shape="round" size="middle">
|
||||
<template #icon>
|
||||
<PlusOutlined/>
|
||||
</template>
|
||||
上传照片
|
||||
</AButton>
|
||||
<AButton type="default" shape="round" size="middle">
|
||||
<template #icon>
|
||||
<PlusSquareOutlined/>
|
||||
</template>
|
||||
创建相册
|
||||
</AButton>
|
||||
</div>
|
||||
<div class="photo-list">
|
||||
<CheckCard style="margin-top: 20px;" v-for="item in items" :key="item.id" :value="item.id" v-model="selectedItems">
|
||||
{{ item.name }}
|
||||
</CheckCard>
|
||||
<div>Selected Items: {{ selectedItems }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
const items = ref([
|
||||
{ id: 1, name: 'Item 1' },
|
||||
{ id: 2, name: 'Item 2' },
|
||||
{ id: 3, name: 'Item 3' },
|
||||
]);
|
||||
|
||||
const selectedItems = ref<(string | number)[]>([]);
|
||||
|
||||
</script>
|
||||
<style scoped lang="scss" src="./index.scss">
|
||||
|
@@ -0,0 +1,19 @@
|
||||
.recent-upload {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
.photo-header {
|
||||
width: 100%;
|
||||
height: 50px;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
gap: 10px;
|
||||
border-bottom: 1px solid #e2e2e2;
|
||||
}
|
||||
}
|
||||
|
@@ -5,14 +5,14 @@
|
||||
<span class="upscale-params-title">类型:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.model_type"
|
||||
:options="upscale.TypeData.map(item => ({label: item, value: item}))">
|
||||
:options="upscale.TypeData.map(item => ({label: item, value: item,key: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="upscale-params-item-content">
|
||||
<span class="upscale-params-title">模型:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.model"
|
||||
:options="upscale.modes.map((item: any) => ({label: item, value: item}))">
|
||||
:options="upscale.modes.map((item: any) => ({label: item, value: item,key: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,7 +21,7 @@
|
||||
<span class="upscale-params-title">比列:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.factor"
|
||||
:options="upscale.scales.map((item: any) => ({label: item, value: item}))">
|
||||
:options="upscale.scales.map((item: any) => ({label: item, value: item,key: item}))">
|
||||
|
||||
</ASelect>
|
||||
</div>
|
||||
@@ -29,7 +29,7 @@
|
||||
<span class="upscale-params-title">分块大小:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.tile_size"
|
||||
:options="upscale.tileSize.map((item: any) => ({label: item, value: item}))">
|
||||
:options="upscale.tileSize.map((item: any) => ({label: item, value: item,key: item}))">
|
||||
|
||||
</ASelect>
|
||||
</div>
|
||||
@@ -39,14 +39,14 @@
|
||||
<span class="upscale-params-title">重复:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.min_lap"
|
||||
:options="upscale.overlapList.map((item: any) => ({label: item, value: item}))">
|
||||
:options="upscale.overlapList.map((item: any) => ({label: item, value: item,key: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
<div class="upscale-params-item-content">
|
||||
<span class="upscale-params-title">运行环境:</span>
|
||||
<ASelect style="width: 100%" size="large"
|
||||
v-model:value="upscale.backend"
|
||||
:options="upscale.backendList.map((item: any) => ({label: item, value: item}))">
|
||||
:options="upscale.backendList.map((item: any) => ({label: item, value: item,key: item}))">
|
||||
</ASelect>
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -174,7 +174,7 @@ export default defineConfig(({mode}: { mode: string }): object => {
|
||||
write: true, // 启用将构建后的文件写入磁盘
|
||||
emptyOutDir: true, // 构建时清空该目录
|
||||
brotliSize: true, // 启用 brotli 压缩大小报告
|
||||
chunkSizeWarningLimit: 10000, // chunk 大小警告的限制
|
||||
chunkSizeWarningLimit: 15000, // chunk 大小警告的限制
|
||||
watch: null, // 设置为 {} 则会启用 rollup 的监听器
|
||||
rollupOptions: { // 自定义底层的 Rollup 打包配置
|
||||
output: {
|
||||
|
Reference in New Issue
Block a user