ノードアップロードファイル + vue3 + elementPlus コンポーネントのカプセル化

1.ノード

 1.入力されたフォームデータを処理するために、 ノード環境にmulter (node.js ミドルウェア) パッケージをインストールします。multipart/form-data

 npm install --save multer

2.userRouter

var express = require('express');
const multer  = require('multer')
const upload = multer({ dest: 'public/avataruploads/' })

const UserController =  require('../../controllers/admin/UserController');

var router = express.Router();

// 上传图片接口                   
router.post('/adminapi/upload', upload.single('file'), UserController.upload);

module.exports = router;

public/avataruploads/: アップロードが保存されるパス アドレス

Upload.single('file'): ファイル は、フロントエンドによって渡されるファイルのキーです。

3.UserController.アップロード

const UserController = {
    // 上传图片
    upload: async (req, res, next) => { 
        console.log(req.file, 'req.file');
        res.send({code:200,msg:'上传成功',data:{url:'/avataruploads/' + req.file.filename}})
    }
}

module.exports = UserController;

二、Vue

1.コンポーネントのアップロード
 

<template>
  <div>
    <!-- :auto-upload="false" -->
    <el-upload
      class="avatar-uploader"
      :action="baseURL + url"
      :headers="{ Authorization: useStore.token }"
      :show-file-list="false"
      :on-success="handleAvatarSuccess"
      :on-error="handleAvatarError"
    >
      <img v-if="imageUrl" :src="imageUrl" class="avatar" />
      <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
    </el-upload>
  </div>
</template>

<script setup lang="ts">
import { ElMessage, type UploadProps } from 'element-plus'
import { Plus } from '@element-plus/icons-vue'
import { baseURL, httpUrl } from '@/utils/request'
import { useUserStore } from '@/stores'
import { useRouter } from 'vue-router'

const router = useRouter()
const useStore = useUserStore()

const props = defineProps({
  file: {
    type: String,
    default: ''
  },
  url: {
    type: String,
    default:  '/adminapi/upload'
  }
})

const emit = defineEmits(['uploadSuccess'])

const imageUrl = ref('')

const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  console.log(response, uploadFile)
  if (response.code === 200) {
    imageUrl.value = response.data.url
    emit('uploadSuccess', response.data.url)
  } else {
    ElMessage.error(response.msg)
  }

  //   imageUrl.value = URL.createObjectURL(uploadFile.raw!)
}

const handleAvatarError: UploadProps['onError'] = (err: Error, uploadFile) => {
  if (err.status === 401) {
    ElMessage.error('登录已过期,请重新登录')
    useStore.delUser()
    return router.replace('/login')
  }
  console.dir(err, uploadFile)
}

watch(imageUrl, (newUrl) => {
  if (newUrl && !newUrl.includes('http')) {
    imageUrl.value = httpUrl + newUrl
  }
})

watch(
  () => props.file,
  (newFile) => {
    imageUrl.value = newFile
  },
  { immediate: true }
)
</script>

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

watch を使用してデータの変更を監視し、ドメイン名を持たないアドレスを取得したため (サーバーのデプロイ時にイメージの損失を防ぐため)、変更後、構成されたドメイン名を取得しました。

2. アップロードコンポーネントを使用する

<template>
  <Upload :file="ruleForm.avatar" @uploadSuccess="uploadSuccessHandler"></Upload>
</template>

<script lang="ts" setup>

const ruleForm = reactive<RuleForm>({
  avatar: ''
})


const uploadSuccessHandler = (url: string) => {
  console.log(url)
  ruleForm.avatar = url
}

</script>

おすすめ

転載: blog.csdn.net/m0_46846526/article/details/132142221