Vue3后台管理系统(十)文件上传

这篇具有很好参考价值的文章主要介绍了Vue3后台管理系统(十)文件上传。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、文件上传api 

二、封装组件

三、使用案例


一、文件上传api 

在src/api下新建file文件夹,并在file文件夹下新建index.ts和types.ts

// src/api/file/types.ts
/**
 * 文件API类型声明
 */
export interface FileInfo {
  name: string;
  url: string;
}
// src/api/file/index.ts
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { FileInfo } from './types';

/**
 * 上传文件
 *
 * @param file
 */
export function uploadFileApi(file: File): AxiosPromise<FileInfo> {
  const formData = new FormData();
  formData.append('file', file);
  return request({
    url: '/api/v1/files',
    method: 'post',
    data: formData,
    headers: {
      'Content-Type': 'multipart/form-data'
    }
  });
}

/**
 * 删除文件
 *
 * @param filePath 文件完整路径
 */
export function deleteFileApi(filePath?: string) {
  return request({
    url: '/api/v1/files',
    method: 'delete',
    params: { filePath: filePath }
  });
}

二、封装组件

单文件上传组件多文件上传组件

在src/components下新建Upload文件夹,并在Upload文件夹中新建SingleUpload.vue和MultiUpload.vue

<!--src/components/Upload/SingleUpload.vue-->
<template>
  <!-- 上传组件 -->
  <el-upload
    class="single-uploader"
    v-model="imgUrl"
    :show-file-list="false"
    list-type="picture-card"
    :before-upload="handleBeforeUpload"
    :http-request="uploadFile"
  >
    <img v-if="imgUrl" :src="imgUrl" class="single" />
    <el-icon v-else class="single-uploader-icon"><Plus /></el-icon>
  </el-upload>
</template>

<script setup lang="ts">
import { computed } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import {
  ElMessage,
  ElUpload,
  UploadRawFile,
  UploadRequestOptions
} from 'element-plus';
import { uploadFileApi } from '@/api/file';

const emit = defineEmits(['update:modelValue']);

const props = defineProps({
  modelValue: {
    type: String,
    default: ''
  }
});

const imgUrl = computed<string | undefined>({
  get() {
    return props.modelValue;
  },
  set(val) {
    // imgUrl改变时触发修改父组件绑定的v-model的值
    emit('update:modelValue', val);
  }
});

/**
 * 自定义图片上传
 *
 * @param options
 */
async function uploadFile(options: UploadRequestOptions): Promise<any> {
  const { data: fileInfo } = await uploadFileApi(options.file);
  imgUrl.value = fileInfo.url;
}

/**
 * 限制用户上传文件的格式和大小
 */
function handleBeforeUpload(file: UploadRawFile) {
  if (file.size > 2 * 1048 * 1048) {
    ElMessage.warning('上传图片不能大于2M');
    return false;
  }
  return true;
}
</script>

<style scoped>
.single-uploader .single {
  width: 178px;
  height: 178px;
  display: block;
}
</style>

<style>
.single-uploader .el-upload {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
}

.single-uploader .el-upload:hover {
  border-color: var(--el-color-primary);
}

.el-icon.single-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 178px;
  height: 178px;
  text-align: center;
}
</style>
<!--src/components/Upload/MultiUpload.vue-->
<!--
  多图上传组件
  @author: youlaitech
  @date 2022/11/20
-->

<template>
  <el-upload
    v-model:file-list="fileList"
    list-type="picture-card"
    :before-upload="handleBeforeUpload"
    :http-request="handleUpload"
    :on-remove="handleRemove"
    :on-preview="handlePreview"
    :limit="props.limit"
  >
    <el-icon><Plus /></el-icon>
  </el-upload>

  <el-dialog v-model="dialogVisible">
    <img w-full :src="dialogImageUrl" alt="Preview Image" />
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';
import { Plus } from '@element-plus/icons-vue';
import {
  ElMessage,
  ElUpload,
  UploadRawFile,
  UploadRequestOptions,
  UploadUserFile,
  UploadFile,
  UploadProps
} from 'element-plus';
import { uploadFileApi, deleteFileApi } from '@/api/file';

const emit = defineEmits(['update:modelValue']);

const props = defineProps({
  /**
   * 文件路径集合
   */
  modelValue: {
    type: Array<string>,
    default: [] as Array<string>
  },
  /**
   * 文件上传数量限制
   */
  limit: {
    type: Number,
    default: 5
  }
});

const dialogImageUrl = ref('');
const dialogVisible = ref(false);

const fileList = ref([] as UploadUserFile[]);
watch(
  () => props.modelValue,
  (newVal: string[]) => {
    const filePaths = fileList.value.map(file => file.url);
    // 监听modelValue文件集合值未变化时,跳过赋值
    if (
      filePaths.length > 0 &&
      filePaths.length === newVal.length &&
      filePaths.every(x => newVal.some(y => y === x)) &&
      newVal.every(y => filePaths.some(x => x === y))
    ) {
      return;
    }

    fileList.value = newVal.map(filePath => {
      return { url: filePath } as UploadUserFile;
    });
  },
  { immediate: true }
);

/**
 * 自定义图片上传
 *
 * @param params
 */
async function handleUpload(options: UploadRequestOptions): Promise<any> {
  // 上传API调用
  const { data: fileInfo } = await uploadFileApi(options.file);

  // 上传成功需手动替换文件路径为远程URL,否则图片地址为预览地址 blob:http://
  const fileIndex = fileList.value.findIndex(
    file => file.uid == (options.file as any).uid
  );

  fileList.value.splice(fileIndex, 1, {
    name: fileInfo.name,
    url: fileInfo.url
  } as UploadUserFile);

  emit(
    'update:modelValue',
    fileList.value.map(file => file.url)
  );
}

/**
 * 删除图片
 */
function handleRemove(removeFile: UploadFile) {
  const filePath = removeFile.url;

  if (filePath) {
    deleteFileApi(filePath).then(() => {
      // 删除成功回调
      emit(
        'update:modelValue',
        fileList.value.map(file => file.url)
      );
    });
  }
}

/**
 * 限制用户上传文件的格式和大小
 */
function handleBeforeUpload(file: UploadRawFile) {
  if (file.size > 2 * 1048 * 1048) {
    ElMessage.warning('上传图片不能大于2M');
    return false;
  }
  return true;
}

/**
 * 图片预览
 */
const handlePreview: UploadProps['onPreview'] = uploadFile => {
  dialogImageUrl.value = uploadFile.url!;
  dialogVisible.value = true;
};
</script>

三、使用案例

在src/views/component下新建uploader.vue

<!--src/views/component/uploader.vue-->
<script setup lang="ts">
import SingleUpload from '@/components/Upload/SingleUpload.vue';
import MultiUpload from '@/components/Upload/MultiUpload.vue';
import { ElForm } from 'element-plus';
import { reactive, ref, toRefs } from 'vue';

const dataFormRef = ref(ElForm);

const state = reactive({
  formData: {
    picUrl:
      'https://oss.youlai.tech/default/2022/11/20/18e206dae97b40329661537d1e433639.jpg',
    picUrls: [
      'https://oss.youlai.tech/default/2022/11/20/8af5567816094545b53e76b38ae9c974.webp',
      'https://oss.youlai.tech/default/2022/11/20/13dbfd7feaf848c2acec2b21675eb9d3.webp'
    ]
  }
});

const { formData } = toRefs(state);
</script>
<template>
  <div class="app-container">
    <el-form ref="dataFormRef" :model="formData">
      <el-form-item label="单图上传">
        <single-upload v-model="formData.picUrl"></single-upload>
      </el-form-item>
      <el-form-item label="多图上传">
        <multi-upload v-model="formData.picUrls"></multi-upload>
      </el-form-item>
    </el-form>
  </div>
</template>

vue3文件上传,Vue3后台管理系统搭建和开发,前端,javascript,vue.js

 文章来源地址https://www.toymoban.com/news/detail-759040.html

到了这里,关于Vue3后台管理系统(十)文件上传的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue3+element-plus的后台管理系统模板 和 vue3+ant-design-vue的后台管理系统模板

    规范 :后台系统模板,按照企业级别的规范搭建的。 权限控制 :通过后端返回的路由表(这个路由表是由前端这边在系统配好的然后存储在后端的)来动态渲染菜单和注册路由,同时也根据页面内的接口权限对页面中的按钮做了是否可见的设置。前端这边有 路由、角色、用

    2024年02月08日
    浏览(81)
  • vue3管理系统中后台返回pdf格式的文件流,前端如何预览?以及uniapp微信小程序中后台返回的base64位的pdf文件如何预览?

    后台返回的是base64格式的pdf文件,首先需要解析base64文件的插件 image-tools 1 安装并引入插件 2 封装预览pdf的函数 3 调用接口获取数据

    2024年01月18日
    浏览(93)
  • vue3 + tsrpc +mongodb 实现后台管理系统

    之前上线了一个vue后台管理系统,有小伙伴问我有没有后端代码,咱只是个小前端,这就有点为难我了。不过不能辜负小伙伴的信任,nodejs也可以啊,废话不多说,开搞!后端采用 TSRPC 框架实现 API 接口,前端采用 vue-manage-system 后台管理系统框架,数据库采用 mongodb。TSRPC 是

    2024年01月16日
    浏览(71)
  • vue3后台管理系统之实现分页功能

    例子:用户 请求格式 返回数据类型 设置返回数据类型 属性 首先我们先要了解分页器的属性 v-model:current-page当前页码 v-model:page-size设置每页展示数据的条数 page-sizes每页显示个数选择器的个数 small是否使用小型分页样式 disabled 是否禁用分页 background 是否为分页按钮添加背景

    2024年02月06日
    浏览(44)
  • vue3后台管理系统实现动态侧边导航菜单管理(ElementPlus组件)

    记住 一级(el-sub-menu)的都是只是展示的 点击跳转的都是一级下的子级(el-menu-item) 完整展示 1:在登陆功能进行登陆 获取menu列表 注册路由表的时候 把文件进行创建好 因为注册的方法需要获取这个路径 整个router下的main product等等都要创建 2:侧边菜单界面 router/index.ts

    2024年02月16日
    浏览(54)
  • Vue+SpringBoot后台管理系统:Vue3+TypeScript项目搭建(一)

    查看Note版本 查看npm版本 然后将npm升级至最新版本 将npm下载源换至http://registry.npm.taobao.org 可以在后续的npm下载提高下载速度 安装vue cli node版本v18.16.1 vue-cli版本v5.0.8 创建项目命令 vue_typescript_elementplus_demo 是项目名,可以自定义 选择 Manually select features ,进行自定义 然后选择

    2024年02月13日
    浏览(84)
  • 超详细!10分钟开发一个Vue3的后台管理系统

    有很多人说 vue2 早就过时了,都 23年了竟然还有人在用 vue2?简直就是个土老帽! “你有说话的权利,但我不认同你的观点。”任何公司的技术架构不是一蹴而就的,而是随着业务的增长不断升级变化的。技术越新,用的人不一定会很多。 其实我敢说现在国内跟多公司还在用

    2024年02月16日
    浏览(36)
  • Vue3+element-plus实现后台管理系统

     环境:node.js软件 、Vs code、vite、elemnt-plus、windicss(样式框架)     1、首先,使用npm 命令构建项目( vscode安装的插件 vscode中文显示插件   2、高亮提示插件volar   3、vue 3 sni 代码提示) 快速上手 | Vue.js    a. npm -v 查看node.js 版本    b.  npm  config get registry   查看注册镜像是

    2024年02月09日
    浏览(55)
  • 基于Vue3 + Element Plus 的后台管理系统详细教程

    Vue3 概述 Vue.js 是一种轻量级MVVM框架,它通过双向绑定的方式,将视图与数据进行关联,简化了前端开发的流程。Vue3 是 Vue.js 的下一个版本,与早期版本相比,它具有更高的性能和更好的开发体验。 Composition API Vue 3 中最大的新特性是引入了 Composition API,它允许开发人员按照

    2024年02月09日
    浏览(65)
  • Vue--》Vue3打造可扩展的项目管理系统后台的完整指南(六)

    今天开始使用 vue3 + ts 搭建一个项目管理的后台,因为文章会将项目的每一个地方代码的书写都会讲解到,所以本项目会分成好几篇文章进行讲解,我会在最后一篇文章中会将项目代码开源到我的 GithHub 上,大家可以自行去进行下载运行,希望本文章对有帮助的朋友们能多多

    2024年02月10日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包