mirror of
https://github.com/jekip/naive-ui-admin.git
synced 2026-02-04 13:42:27 +08:00
style(BasicUpload): center upload icon and text in BasicForm
This commit is contained in:
@@ -4,11 +4,11 @@
|
|||||||
<div class="upload-card">
|
<div class="upload-card">
|
||||||
<!--图片列表-->
|
<!--图片列表-->
|
||||||
<div
|
<div
|
||||||
class="upload-card-item"
|
class="upload-card-item"
|
||||||
:style="getCSSProperties"
|
:style="getCSSProperties"
|
||||||
v-for="(item, index) in imgList"
|
v-for="(item, index) in imgList"
|
||||||
:key="`img_${index}`"
|
:key="`img_${index}`"
|
||||||
>
|
>
|
||||||
<div class="upload-card-item-info">
|
<div class="upload-card-item-info">
|
||||||
<div class="img-box">
|
<div class="img-box">
|
||||||
<img :src="item" />
|
<img :src="item" />
|
||||||
@@ -26,11 +26,12 @@
|
|||||||
|
|
||||||
<!--上传图片-->
|
<!--上传图片-->
|
||||||
<div
|
<div
|
||||||
class="upload-card-item upload-card-item-select-picture"
|
class="upload-card-item upload-card-item-select-picture"
|
||||||
:style="getCSSProperties"
|
:style="getCSSProperties"
|
||||||
v-if="imgList.length < maxNumber"
|
v-if="imgList.length < maxNumber"
|
||||||
>
|
>
|
||||||
<n-upload
|
<n-upload
|
||||||
|
class="w-auto"
|
||||||
v-bind="$props"
|
v-bind="$props"
|
||||||
:file-list-style="{ display: 'none' }"
|
:file-list-style="{ display: 'none' }"
|
||||||
@before-upload="beforeUpload"
|
@before-upload="beforeUpload"
|
||||||
@@ -68,243 +69,243 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, toRefs, reactive, computed, watch } from 'vue';
|
import { defineComponent, toRefs, reactive, computed, watch } from 'vue';
|
||||||
import { EyeOutlined, DeleteOutlined, PlusOutlined } from '@vicons/antd';
|
import { EyeOutlined, DeleteOutlined, PlusOutlined } from '@vicons/antd';
|
||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
import { useMessage, useDialog } from 'naive-ui';
|
import { useMessage, useDialog } from 'naive-ui';
|
||||||
import { ResultEnum } from '@/enums/httpEnum';
|
import { ResultEnum } from '@/enums/httpEnum';
|
||||||
import componentSetting from '@/settings/componentSetting';
|
import componentSetting from '@/settings/componentSetting';
|
||||||
import { useGlobSetting } from '@/hooks/setting';
|
import { useGlobSetting } from '@/hooks/setting';
|
||||||
import { isString } from '@/utils/is';
|
import { isString } from '@/utils/is';
|
||||||
|
|
||||||
const globSetting = useGlobSetting();
|
const globSetting = useGlobSetting();
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BasicUpload',
|
name: 'BasicUpload',
|
||||||
|
|
||||||
components: { EyeOutlined, DeleteOutlined, PlusOutlined },
|
|
||||||
props: {
|
|
||||||
...basicProps,
|
|
||||||
},
|
|
||||||
emits: ['uploadChange', 'delete'],
|
|
||||||
setup(props, { emit }) {
|
|
||||||
const getCSSProperties = computed(() => {
|
|
||||||
return {
|
|
||||||
width: `${props.width}px`,
|
|
||||||
height: `${props.height}px`,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
const message = useMessage();
|
|
||||||
const dialog = useDialog();
|
|
||||||
|
|
||||||
const state = reactive({
|
|
||||||
showModal: false,
|
|
||||||
previewUrl: '',
|
|
||||||
originalImgList: [] as string[],
|
|
||||||
imgList: [] as string[],
|
|
||||||
});
|
|
||||||
|
|
||||||
//赋值默认图片显示
|
|
||||||
watch(
|
|
||||||
() => props.value,
|
|
||||||
() => {
|
|
||||||
state.imgList = props.value.map((item) => {
|
|
||||||
return getImgUrl(item);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
{ immediate: true }
|
|
||||||
);
|
|
||||||
|
|
||||||
//预览
|
|
||||||
function preview(url: string) {
|
|
||||||
state.showModal = true;
|
|
||||||
state.previewUrl = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
//删除
|
|
||||||
function remove(index: number) {
|
|
||||||
dialog.info({
|
|
||||||
title: '提示',
|
|
||||||
content: '你确定要删除吗?',
|
|
||||||
positiveText: '确定',
|
|
||||||
negativeText: '取消',
|
|
||||||
onPositiveClick: () => {
|
|
||||||
state.imgList.splice(index, 1);
|
|
||||||
state.originalImgList.splice(index, 1);
|
|
||||||
emit('uploadChange', state.originalImgList);
|
|
||||||
emit('delete', state.originalImgList);
|
|
||||||
},
|
|
||||||
onNegativeClick: () => {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//组装完整图片地址
|
|
||||||
function getImgUrl(url: string): string {
|
|
||||||
const { imgUrl } = globSetting;
|
|
||||||
return /(^http|https:\/\/)/g.test(url) ? url : `${imgUrl}${url}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkFileType(fileType: string) {
|
|
||||||
return componentSetting.upload.fileType.includes(fileType);
|
|
||||||
}
|
|
||||||
|
|
||||||
//上传之前
|
|
||||||
function beforeUpload({ file }) {
|
|
||||||
const fileInfo = file.file;
|
|
||||||
const { maxSize, accept } = props;
|
|
||||||
const acceptRef = (isString(accept) && accept.split(',')) || [];
|
|
||||||
|
|
||||||
// 设置最大值,则判断
|
|
||||||
if (maxSize && fileInfo.size / 1024 / 1024 >= maxSize) {
|
|
||||||
message.error(`上传文件最大值不能超过${maxSize}M`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 设置类型,则判断
|
|
||||||
const fileType = componentSetting.upload.fileType;
|
|
||||||
if (acceptRef.length > 0 && !checkFileType(fileInfo.type)) {
|
|
||||||
message.error(`只能上传文件类型为${fileType.join(',')}`);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//上传结束
|
|
||||||
function finish({ event: Event }) {
|
|
||||||
const res = eval('(' + Event.target.response + ')');
|
|
||||||
const infoField = componentSetting.upload.apiSetting.infoField;
|
|
||||||
const { code } = res;
|
|
||||||
const message = res.msg || res.message || '上传失败';
|
|
||||||
const result = res[infoField];
|
|
||||||
//成功
|
|
||||||
if (code === ResultEnum.SUCCESS) {
|
|
||||||
let imgUrl: string = getImgUrl(result.photo);
|
|
||||||
state.imgList.push(imgUrl);
|
|
||||||
state.originalImgList.push(result.photo);
|
|
||||||
emit('uploadChange', state.originalImgList);
|
|
||||||
} else message.error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
components: { EyeOutlined, DeleteOutlined, PlusOutlined },
|
||||||
|
props: {
|
||||||
|
...basicProps,
|
||||||
|
},
|
||||||
|
emits: ['uploadChange', 'delete'],
|
||||||
|
setup(props, { emit }) {
|
||||||
|
const getCSSProperties = computed(() => {
|
||||||
return {
|
return {
|
||||||
...toRefs(state),
|
width: `${props.width}px`,
|
||||||
finish,
|
height: `${props.height}px`,
|
||||||
preview,
|
|
||||||
remove,
|
|
||||||
beforeUpload,
|
|
||||||
getCSSProperties,
|
|
||||||
};
|
};
|
||||||
},
|
});
|
||||||
});
|
|
||||||
|
const message = useMessage();
|
||||||
|
const dialog = useDialog();
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
showModal: false,
|
||||||
|
previewUrl: '',
|
||||||
|
originalImgList: [] as string[],
|
||||||
|
imgList: [] as string[],
|
||||||
|
});
|
||||||
|
|
||||||
|
//赋值默认图片显示
|
||||||
|
watch(
|
||||||
|
() => props.value,
|
||||||
|
() => {
|
||||||
|
state.imgList = props.value.map((item) => {
|
||||||
|
return getImgUrl(item);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{ immediate: true }
|
||||||
|
);
|
||||||
|
|
||||||
|
//预览
|
||||||
|
function preview(url: string) {
|
||||||
|
state.showModal = true;
|
||||||
|
state.previewUrl = url;
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除
|
||||||
|
function remove(index: number) {
|
||||||
|
dialog.info({
|
||||||
|
title: '提示',
|
||||||
|
content: '你确定要删除吗?',
|
||||||
|
positiveText: '确定',
|
||||||
|
negativeText: '取消',
|
||||||
|
onPositiveClick: () => {
|
||||||
|
state.imgList.splice(index, 1);
|
||||||
|
state.originalImgList.splice(index, 1);
|
||||||
|
emit('uploadChange', state.originalImgList);
|
||||||
|
emit('delete', state.originalImgList);
|
||||||
|
},
|
||||||
|
onNegativeClick: () => {},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//组装完整图片地址
|
||||||
|
function getImgUrl(url: string): string {
|
||||||
|
const { imgUrl } = globSetting;
|
||||||
|
return /(^http|https:\/\/)/g.test(url) ? url : `${imgUrl}${url}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkFileType(fileType: string) {
|
||||||
|
return componentSetting.upload.fileType.includes(fileType);
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传之前
|
||||||
|
function beforeUpload({ file }) {
|
||||||
|
const fileInfo = file.file;
|
||||||
|
const { maxSize, accept } = props;
|
||||||
|
const acceptRef = (isString(accept) && accept.split(',')) || [];
|
||||||
|
|
||||||
|
// 设置最大值,则判断
|
||||||
|
if (maxSize && fileInfo.size / 1024 / 1024 >= maxSize) {
|
||||||
|
message.error(`上传文件最大值不能超过${maxSize}M`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置类型,则判断
|
||||||
|
const fileType = componentSetting.upload.fileType;
|
||||||
|
if (acceptRef.length > 0 && !checkFileType(fileInfo.type)) {
|
||||||
|
message.error(`只能上传文件类型为${fileType.join(',')}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//上传结束
|
||||||
|
function finish({ event: Event }) {
|
||||||
|
const res = eval('(' + Event.target.response + ')');
|
||||||
|
const infoField = componentSetting.upload.apiSetting.infoField;
|
||||||
|
const { code } = res;
|
||||||
|
const message = res.msg || res.message || '上传失败';
|
||||||
|
const result = res[infoField];
|
||||||
|
//成功
|
||||||
|
if (code === ResultEnum.SUCCESS) {
|
||||||
|
let imgUrl: string = getImgUrl(result.photo);
|
||||||
|
state.imgList.push(imgUrl);
|
||||||
|
state.originalImgList.push(result.photo);
|
||||||
|
emit('uploadChange', state.originalImgList);
|
||||||
|
} else message.error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
...toRefs(state),
|
||||||
|
finish,
|
||||||
|
preview,
|
||||||
|
remove,
|
||||||
|
beforeUpload,
|
||||||
|
getCSSProperties,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
.upload {
|
.upload {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&-card {
|
&-card {
|
||||||
width: auto;
|
width: auto;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&-item {
|
||||||
|
margin: 0 8px 8px 0;
|
||||||
|
position: relative;
|
||||||
|
padding: 8px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 2px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
&-item {
|
&:hover {
|
||||||
margin: 0 8px 8px 0;
|
background: 0 0;
|
||||||
position: relative;
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
&:hover {
|
.upload-card-item-info::before {
|
||||||
background: 0 0;
|
opacity: 1;
|
||||||
|
|
||||||
.upload-card-item-info::before {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&-info::before {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&-info {
|
&-info::before {
|
||||||
position: relative;
|
opacity: 1;
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.img-box-actions {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&::before {
|
|
||||||
position: absolute;
|
|
||||||
z-index: 1;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
background-color: rgba(0, 0, 0, 0.5);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.3s;
|
|
||||||
content: ' ';
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-box {
|
|
||||||
position: relative;
|
|
||||||
//padding: 8px;
|
|
||||||
//border: 1px solid #d9d9d9;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-box-actions {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
z-index: 10;
|
|
||||||
white-space: nowrap;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
opacity: 0;
|
|
||||||
transition: all 0.3s;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: 0 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-icon {
|
|
||||||
color: rgba(255, 255, 255, 0.85);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-item-select-picture {
|
&-info {
|
||||||
border: 1px dashed #d9d9d9;
|
position: relative;
|
||||||
border-radius: 2px;
|
height: 100%;
|
||||||
cursor: pointer;
|
width: 100%;
|
||||||
background: #fafafa;
|
padding: 0;
|
||||||
color: #666;
|
overflow: hidden;
|
||||||
|
|
||||||
.upload-title {
|
&:hover {
|
||||||
color: #666;
|
.img-box-actions {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 1;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s;
|
||||||
|
content: ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-box {
|
||||||
|
position: relative;
|
||||||
|
//padding: 8px;
|
||||||
|
//border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img-box-actions {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
z-index: 10;
|
||||||
|
white-space: nowrap;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
opacity: 0;
|
||||||
|
transition: all 0.3s;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-icon {
|
||||||
|
color: rgba(255, 255, 255, 0.85);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
cursor: pointer;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&-item-select-picture {
|
||||||
|
border: 1px dashed #d9d9d9;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #fafafa;
|
||||||
|
color: #666;
|
||||||
|
|
||||||
|
.upload-title {
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user