需求是做一个类似网盘的界面,需要有左侧的树形控件,顶部的面包屑导航以及内容部分有文件夹和文件
页面效果图:
点击文件:
点击添加:
2022.5.24修改:直接贴上源码,文件、excel等图标可自己找或者+我q932946893
<template>
<div class="warp-main" style="overflow: hidden; padding-left: 10px">
<div class="doc_left">
<div class="home_page" @click="handleToHome"><img src="static/images/img/little_folder.png" style="margin-right: 2px">首页</div>
<el-tree :data="tree" :props="defaultProps" ref="tree" node-key="id" accordion @node-click="handleNodeClick" :render-content="renderContent">
</el-tree>
</div>
<div class="doc_top">
<el-breadcrumb separator-class="el-icon-arrow-right" style="cursor:pointer;">
<el-breadcrumb-item @click.native="handleToHome">首页</el-breadcrumb-item>
<el-breadcrumb-item v-for="item in breadOption" :key="item.id" @click.native="handleIn(item.id)">{{item.title}}</el-breadcrumb-item>
</el-breadcrumb>
</div>
<div class="doc_main">
<div v-for="item in folderData" class="doc_item">
<el-dropdown trigger="click" placement="bottom">
<div class="doc_item_link" @dblclick="handleInto(item.TypeId,item.TypeName)" :title="item.TypeName">
<img class="doc_item_img" src="static/images/img/folder.png"><span>{{item.TypeName| ellipsis}}</span></div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handleDeleteType(item.TypeId)">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div v-for="item in docData" class="doc_item" >
<el-dropdown trigger="click" placement="bottom">
<div class="doc_item_link" :title="item.DocName">
<img class="file_item_img" :src="getImgSrc(item.DocFileType)"><span>{{item.DocName| ellipsis}}</span></div>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item @click.native="handlePreview(item.DocId,item.DocFileType)">预览</el-dropdown-item>
<el-dropdown-item @click.native="handleDownload(item.DocId)">下载</el-dropdown-item>
<el-dropdown-item @click.native="handleDelete(item.DocId)">删除</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
<div class="doc_item_link" style="display: inline">
<div class="doc_item_add" @click="handleAdd"><img class="file_item_img" src="static/images/img/add.png"><span>添加</span></div>
</div>
</div>
<div v-if="dialogVisible">
<el-dialog title="新增" :visible.sync="dialogVisible" width="400px">
<el-select placeholder="请选择新增类型" v-model="addType" style="margin-bottom: 10px" v-show="!form.parent_type_id==''">
<el-option v-for="item in addOptions" :key="item.value" :label="item.label" :value="item.value" ></el-option>
</el-select>
<el-input type="text" v-show="addType==2" placeholder="请输入新增文档类型名称" v-model.trim="form.type_name" style="margin-bottom: 20px"></el-input>
<el-button type="primary" v-show="addType==2" @click="SubmitAdd">确定</el-button>
<el-upload
ref="upload"
v-model="files"
:limit='1'
v-show="addType==1"
:http-request="uploadFile"
class="upload-demo"
:on-change="fileChange"
accept=".xls,.xlsx,.doc,.docx,.ppt,.pptx,.pdf,.jpg,.png,.gif"
drag
action="uploadAction"
multiple
:auto-upload="false">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将单个文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">可支持文档类型word、excel、ppt、pdf及图片格式jpg、png、gif</div>
</el-upload>
<el-button v-show="addType==1" style="margin-top: 10px;" type="primary" @click="submitUpload">上传到服务器</el-button>
</el-dialog>
</div>
</div>
</template>
<script>
import {saveDocType,getAllType,getOneTypeList,saveDocument,deleteDoc,downloadDoc,deleteDocType} from "../../api/api_document";
import axios from 'axios';
export default {
inject:['reload'],
data(){
return {
uploadAction:serverConfig.serverUrl+'/Document/SaveDocument',
uploadForm: new FormData(),
files:[],
form:{
parent_type_id:'',
type_name:'',
},
breadOption:[],
addType:'2',
dialogVisible:false,
tree:[],
folderData:[],
docData:[],
defaultProps: {
children: 'SubTypes',
label: 'TypeName',
id:'TypeId'
},
addOptions:[{
label:'上传文件',
value:'1'
},{
label:'添加文档类型',
value:'2'
}],
}
},
methods:{
/*点击文件图标进入下级*/
handleInto(Id,Name){
this.breadOption.push({'title':Name,'id':Id});
this.handleIntoOneTypeList(Id);
},
/*这段是面包屑点击事件,循环判断点击的面包屑的id与面包屑数组的最后一项的id是否相同,如果不同则移除最后一项,
如果相同则跳出循环,以此达到点击某个面包屑,往后所有面包屑全部移除并且进入所点击面包屑的文件夹的目的*/
handleIn(id){
for(let i=this.breadOption.length;i>0;i--){
if(this.breadOption[i-1].id!=id){
this.breadOption.pop();
}else{
break;
}
}
this.handleIntoOneTypeList(id);
},
/*统一处理跳入某个文件夹*/
handleIntoOneTypeList(id){
//将添加的默认类型设置为上传文件
if(this.form.parent_type_id===''){
this.addType='1'
}
getOneTypeList({'type_id':id}).then(res=>{
if(res.data.Successful===true){
this.form.parent_type_id=id;
this.folderData=res.data.Data.TypeList;
this.docData=res.data.Data.DocList
}else{
this.$message.error('获取数据出错,请稍后再试');
}
})
},
/*点击树形控件*/
handleNodeClick(data,node) {
this.breadOption=[];
/*临时变量nodeData储存被点击节点的node信息,判断如果此节点有父节点,
那么将相关信息添加到面包屑的首位,并将父节点赋值给临时节点,继续判断该节点是否有父节点*/
let nodeData=node;
while (nodeData.parent!=null){
this.breadOption.unshift({'title':nodeData.data.TypeName,'id':nodeData.data.TypeId});
nodeData=nodeData.parent;
}
this.handleIntoOneTypeList(data.TypeId);
},
fileChange(file, fileList){
let fileName = file.name;
let regex = /(.xls|.xlsx|.doc|.docx|.ppt|.pptx|.pdf|.jpg|.png|.gif)$/;
if (regex.test(fileName.toLowerCase())) {
this.files=fileList;
} else {
//移除最后一个元素
fileList.pop();
this.$message.error('请选择指定格式文件');
}
},
getTypes(){
getAllType().then(res=>{
this.tree=res.data.Data
})
},
getList(){
getOneTypeList(this.queryForm).then(res=>{
this.folderData=res.data.Data.TypeList;
this.docData=res.data.Data.DocList
})
},
/*由于element多文件是分别上传,所以这里覆盖默认的上传行为,将文件添加到FormData中*/
uploadFile(file) {
this.uploadForm.append('files', file.file);
},
/*上传文件*/
submitUpload() {
if(this.files.length>0){
this.$refs.upload.submit();
this.uploadForm.append('doc_type_id', this.form.parent_type_id);
axios.post(saveDocument(),this.uploadForm).then(res=>{
if(res.data.Successful===true){
this.$message({type: 'success', message: '提交成功!'});
//清空数据
this.uploadForm=new FormData();
this.files=[];
this.handleIntoOneTypeList(this.form.parent_type_id);
this.dialogVisible=false;
}
})
}else{
this.$message({type: 'error', message: '请选择需要上传的文件!'});
}
},
handleAdd(){
this.dialogVisible=true;
},
/*添加文件夹*/
SubmitAdd(){
if(this.form.type_name==''){
this.$message({type: 'error', message: '名称不能为空,请重新输入!'});
}else{
saveDocType(this.form).then(res=>{
if(res.data.Successful===true){
this.$message({type: 'success', message: '添加成功!'});
this.form.type_name='';
this.handleIntoOneTypeList(this.form.parent_type_id);
this.getTypes();
this.dialogVisible=false;
}else{
this.$message({type: 'error', message: '添加失败!'});
this.form.type_name='';
this.handleIntoOneTypeList(this.form.parent_type_id);
this.dialogVisible=false;
}
})
}
},
handlePreview(Id,Type){
if (Type===0){
}else{
window.open("http://view.officeapps.live.com/op/view.aspx?src="+downloadDoc(Id));
}
},
/*下载文件*/
handleDownload(Id){
let a = document.createElement('a');
a.href=downloadDoc(Id);
console.log(a.href);
a.click();
},
/*删除文件*/
handleDelete(data){
this.$confirm('文件删除后无法恢复,确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
deleteDoc(data).then(res=>{
if(res.data.Successful===true){
this.$message({type: 'success', message: '删除成功!'});
this.handleIntoOneTypeList(this.form.parent_type_id)
}else{
this.$message({type: 'success', message: '删除失败!'});
this.handleIntoOneTypeList(this.form.parent_type_id)
}
})
}).catch(()=>{
})
},
/*删除文件夹*/
handleDeleteType(data){
this.$confirm('文件夹内所有内容将一并删除且不可恢复!!!!!!确认删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(()=>{
deleteDocType(data).then(res=>{
if(res.data.Successful===true){
this.$message({type: 'success', message: '删除成功!'});
this.getTypes();
this.handleIntoOneTypeList(this.form.parent_type_id);
}else{
this.$message({type: 'success', message: '删除失败!'});
this.getTypes();
this.handleIntoOneTypeList(this.form.parent_type_id);
}
})
}).catch(()=>{
})
},
/*根据文件类型添加返回图片src*/
getImgSrc(data){
return "static/images/img/filetype/"+data+".png";
},
/*点击面包屑首页*/
handleToHome(){
this.reload();
},
/*初始化树,添加文件图标*/
renderContent(h, { node, data, store }) {
return (
<span style="flex: 1; display: flex; align-items: center; justify-content: space-between; font-size: 14px; padding-right: 8px;">
<span>
<img src="static/images/img/little_folder.png"/>
<span> {node.label}</span>
</span>
</span>);
}
},
created(){
this.getTypes();
this.getList();
},
/*过滤器,文件名超过四个字显示...*/
filters: {
ellipsis (value) {
if (!value) return '';
if (value.length > 6) {
return value.slice(0,6) + '...'
}
return value
}
},
}
</script>
<style>
.doc_item{
float: left;
color: black;
display: inline-block;
height: 130px;
width: 100px;
margin-right: 30px;
text-align: center;
font-weight: 400;
font-size: 14px;
}
.doc_item_add{
float: left;
color: black;
display: inline-block;
height: 130px;
width: 100px;
margin-right: 30px;
text-align: center;
font-weight: 400;
font-size: 14px;
}
.doc_item_link{
cursor:pointer;
}
.doc_item_img{
height: 100px;
width: 100px;
}
.file_item_img{
/*position: relative;*/
/*top: -5px;*/
/*margin-left: 10px;*/
/*margin-right: 10px;*/
padding:10px;
height: 100px;
width: 100px;
}
.doc_main{
margin-top: 40px;
}
.doc_left{
border-right: 10px solid #f4f4f4;
overflow-y: scroll;
float: left;
width: 175px;
min-height: 510px;
margin-right: 30px;
margin-top: 30px;
margin-left: 10px;
}
.doc_top{
float: left;
margin-top: 10px;
margin-bottom: 10px;
}
a:visited {
color: black;
}
.doc_add_img{
height: 70px;
width: 70px;
margin-top: 15px;
margin-bottom: 13px;
}
.home_page{
cursor: pointer;
vertical-align: middle;
margin: 5px 10px;
}
</style>