前言
该项目作为一个类网盘项目,主要包括上传下载,引用,预览等功能。
大致功能:
- 图片预览
这里的图片预览我使用的一个插件
const state: any = reactive({
j
image: 'https://pic35.photophoto.cn/20150511/0034034892281415_b.jpg',
index: 0
});
const previewEvent = () => {
preview({
images: state.image
});
};
- 上传图片
bash
<el-button type="primary" size="small" @click="dialogVisible = true" :icon=Upload>上传图片</el-button>
- 几个自定义标签
bash
<el-table-column>
<!-- 几个自定义图标-->
<template v-slot="{row}">
<div v-if="isPicture(row)" >
<el-button type="primary" round size="small" style="margin-right: 50px" @click="previewEvent">预览</el-button>
<el-tooltip class="item" effect="dark" content="引用" placement="bottom-start">
<el-button type="text">
<el-icon>
<Link/>
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="下载" placement="bottom-start">
<el-button type="text">
<el-icon>
<Download/>
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="删除" placement="bottom-start" >
<el-button type="text"><el-button type="text">
<el-icon>
<Delete/>
</el-icon>
</el-button></el-button>
</el-tooltip>
</div>
</template>
</el-table-column>
- 文件展示
vue组件源码:
bash
<template>
<div>
<div class="bt">
<el-button type="text" size="medium" @click="back" v-if="path.length >= 1">
<el-icon>
<ArrowLeft/>
</el-icon>
返回上一级
</el-button>
<el-button type="primary" size="small" @click="dialogVisible = true" :icon=Upload>上传图片</el-button>
<el-button size="small" @click="addFolder = true">
新建文件夹
</el-button>
<el-dialog
title="输入文件名字"
v-model="addFolder"
width="20%"
>
<el-input v-model="input" placeholder="请输入内容" :input-style="{}"></el-input>
<span slot="footer" class="dialog-footer">
<el-button @click="addFolder = false">取 消</el-button>
<el-button type="primary" @click="newfolder">确 定</el-button>
</span>
</el-dialog>
<el-dialog
title="上传"
v-model="dialogVisible"
width="30%"
:before-close="handleClose">
<el-upload
class="upload-demo"
drag
action="upload"
:before-upload="beforeUpload"
multiple
v-loading="loading"
element-loading-text="正在上传"
>
<el-icon :size="20">
<Upload />
</el-icon>
<div class="el-upload__text">将图片拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip"></div>
</el-upload>
<span slot="footer" class="dialog-footer">
</span>
</el-dialog>
<div id="search">
<input placeholder="请输入内容" class="search" v-model="keywords" />
<el-icon v-if="keywords > 0" style="margin-right: 10px">
<Close @click="backSearch" />
</el-icon>
<el-icon >
<Search/>
</el-icon>
</div>
</div>
<el-table :data="filteredTableData" :height="height">
<el-table-column prop="name" label="文件名" width="600px">
<template v-slot="{row}">
<img :src="thumbnail(row)" class="img-mini"/>
<a href="javascript:void(0)" class="fileName" @click="next(row)">{{ row.name }}</a>
</template>
</el-table-column>
<el-table-column>
<!-- 几个自定义图标-->
<template v-slot="{row}">
<div v-if="isPicture(row)" >
<el-button type="primary" round size="small" style="margin-right: 50px" @click="previewEvent">预览</el-button>
<el-tooltip class="item" effect="dark" content="引用" placement="bottom-start">
<el-button type="text">
<el-icon>
<Link/>
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="下载" placement="bottom-start">
<el-button type="text">
<el-icon>
<Download/>
</el-icon>
</el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="删除" placement="bottom-start" >
<el-button type="text"><el-button type="text">
<el-icon>
<Delete/>
</el-icon>
</el-button></el-button>
</el-tooltip>
</div>
</template>
</el-table-column>
<el-table-column prop="size" label="大小" width="270"></el-table-column>
<el-table-column prop="time" label="修改日期" width="220"></el-table-column>
</el-table>
</div>
</template>
<script lang="ts" setup>
import {Upload, Search, Download, Delete, Link, ArrowLeft, Close} from "@element-plus/icons-vue";
import {computed, reactive, ref} from "vue";
import {preview, vPreview, Vue3ImagePreview} from 'vue3-image-preview';
const height = window.innerHeight - 62 - 80 - 40;
let keywords = ref('');
//当前文件夹目录
let path = ref([]);
const next = (row) => {
tableData.value = newTableData;
path.value.push(row.name);
console.log(path)
}
const back = () => {
tableData.value.unshift(
{ name: '文件夹', img: 'image2.jpg', size: '-', time: '2023-08-20' },
)
path.value.pop();
console.log(path);
}
function search(){
return [];
}
const backSearch = () =>{
console.log("执行了backSearch")
keywords.value = '';
}
const filteredTableData = computed(() => {
if (!keywords.value) {
return tableData.value;
}
const lowerKeywords = keywords.value.toLowerCase();
return tableData.value.filter(item => item.name.toLowerCase().includes(lowerKeywords));
});
const addFolder = ref(false);
const input = ref();
const dialogVisible = ref(false);
//核心图片数据区
const tableData = ref([
{ name: '文件夹', img: 'image2.jpg', size: '-', time: '2023-08-20' },
{ name: "文件1", img: 'image1.jpg', size: '1MB', time: '2023-08-21' },
{ name: '文件2', img: 'image2.jpg', size: '500KB', time: '2023-08-20' },
// ...
]);
const newTableData = [
{ name: "文件1", img: 'image1.jpg', size: '1MB', time: '2023-08-21' },
{ name: '文件2', img: 'image2.jpg', size: '500KB', time: '2023-08-20' },
]
//是否是图片
const isPicture = (row: { size: string | any[]; }) => {
return row.size.length > 1;
}
//获取缩略图
const thumbnail = (row: { size: string | any[]; }) => {
if(row.size.length > 1){
return "../src/static/img/picture.svg";
}else{
return "../src/static/img/folder.svg";
}
}
//打开预览框
const state: any = reactive<any>({
image: 'https://pic35.photophoto.cn/20150511/0034034892281415_b.jpg',
index: 0
});
const previewEvent = () => {
preview({
images: state.image
});
};
</script>
<style lang="less" scoped>
.bt {
max-width: 100%;
background-color: white;
height: 40px;
font: 12px/1.5 "Microsoft YaHei", arial, SimSun, "宋体";
line-height: 30px;
}
.nav{
max-width: 100%;
background-color: white;
height: 20px;
/*font: 12px/1.5 "Microsoft YaHei", arial, SimSun, "宋体";*/
font-size: 8px;
line-height: 20px;
}
.el-table-column {
max-height: 48px;
line-height: 48px;
}
.el-table {
max-width: 100%;
font: 12px/1.5 "Microsoft YaHei", arial, SimSun, "宋体";
}
#search {
width: 315px;
border-radius: 33px;
background-color: #f7f7f7;
float: right;
text-align: center;
height: 32px;
line-height: 32px;
input{
outline: none;
}
}
.search {
border: none;
background-color: #f7f7f7;
height: 30px;
width: 248px;
}
img {
width: 30px;
height: 30px;
}
a {
color: #424e67;
text-decoration: none;
}
a:hover {
color: #09AAFF;
}
.el-icon-delete{
color:#F56C6C;
}
.dialog-footer{
display: flex;
justify-content: space-between;
}
span{
margin-top: 5%;
}
.img-mini{
display: inline-block;
vertical-align: middle
}
.fileName{
margin-left: 5px;
}
.custom-icon{
}
</style>