You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel9-Vue3博客多图上传改造技术求助

单图上传改多图上传实现方案(Laravel9+Vue3)

一、前端(CreatePost.vue)修改

1. 新增文件选择与预览区域

复制原单图输入框,扩展为4组对应多图上传,调整索引与标识:

<!-- 图片1 -->
<label for="image1"><span>Image 1</span></label>
<input type="file" :id="'image1'" @change="grabFile(0)" />
<span v-if="errors.files && errors.files[0]" class="error">{{ errors.files[0] }}</span>
<div class="preview" v-if="urls[0]">
  <img :src="urls[0]" alt="Post image 1" />
</div>

<!-- 图片2 -->
<label for="image2"><span>Image 2</span></label>
<input type="file" :id="'image2'" @change="grabFile(1)" />
<div class="preview" v-if="urls[1]">
  <img :src="urls[1]" alt="Post image 2" />
</div>

<!-- 图片3 -->
<label for="image3"><span>Image 3</span></label>
<input type="file" :id="'image3'" @change="grabFile(2)" />
<div class="preview" v-if="urls[2]">
  <img :src="urls[2]" alt="Post image 3" />
</div>

<!-- 图片4 -->
<label for="image4"><span>Image 4</span></label>
<input type="file" :id="'image4'" @change="grabFile(3)" />
<div class="preview" v-if="urls[3]">
  <img :src="urls[3]" alt="Post image 4" />
</div>

2. 调整数据与提交逻辑

将单个文件/预览变量改为数组,适配多图存储与提交:

export default {
  data() {
    return {
      // 保留原有其他数据...
      files: [], // 存储4个文件对象
      urls: [] // 存储4个预览URL
    }
  },
  methods: {
    grabFile(index) {
      const file = event.target.files[0];
      this.files[index] = file;
      // 生成本地预览链接
      this.urls[index] = URL.createObjectURL(file);
    },
    async submitPost() {
      const formData = new FormData();
      // 追加原有表单字段
      formData.append('title', this.title);
      formData.append('slug', this.slug);
      formData.append('category_id', this.category_id);
      formData.append('body', this.body);
      
      // 追加多图文件(存在则添加)
      if (this.files[0]) formData.append('image', this.files[0]);
      if (this.files[1]) formData.append('image2', this.files[1]);
      if (this.files[2]) formData.append('image3', this.files[2]);
      if (this.files[3]) formData.append('image4', this.files[3]);
      
      // 保留原有提交逻辑
      try {
        await this.$axios.post('/api/posts', formData, {
          headers: { 'Content-Type': 'multipart/form-data' }
        });
        // 提交成功后的跳转/提示逻辑...
      } catch (error) {
        this.errors = error.response.data.errors;
      }
    }
  }
}

二、后端修改

1. 更新Post模型可填充字段

打开app/Models/Post.php,新增多图字段到$fillable:

protected $fillable = [
    'title',
    'slug',
    'user_id',
    'category_id',
    'body',
    'imagePath',
    'imagePath2',
    'imagePath3',
    'imagePath4'
];

2. 修改PostController的store方法

打开app/Http/Controllers/Api/PostController.php,扩展文件上传与存储逻辑:

public function store(Request $request) {
    // 调整验证规则,image2-4设为可选
    $validated = $request->validate([
        'title' => 'required|max:255',
        'slug' => 'required|unique:posts|max:255',
        'category_id' => 'required',
        'body' => 'required',
        'image' => 'required|image|mimes:jpeg,png,jpg,gif|max:2048',
        'image2' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        'image3' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
        'image4' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
    ]);

    // 处理主图上传
    $imagePath = $request->file('image')->store('posts', 'public');
    
    // 处理其他图片(存在则上传)
    $imagePath2 = $request->file('image2') ? $request->file('image2')->store('posts', 'public') : null;
    $imagePath3 = $request->file('image3') ? $request->file('image3')->store('posts', 'public') : null;
    $imagePath4 = $request->file('image4') ? $request->file('image4')->store('posts', 'public') : null;

    // 创建文章并写入多图路径
    $post = auth()->user()->posts()->create([
        'title' => $validated['title'],
        'slug' => $validated['slug'],
        'category_id' => $validated['category_id'],
        'body' => $validated['body'],
        'imagePath' => $imagePath,
        'imagePath2' => $imagePath2,
        'imagePath3' => $imagePath3,
        'imagePath4' => $imagePath4,
    ]);

    return response()->json($post, 201);
}

三、前端展示多图(以ShowPost.vue为例)

在文章详情页判断图片路径是否存在,渲染所有有效图片:

<template>
  <!-- 原有文章内容区域 -->
  <div class="post-images">
    <img :src="`/storage/${post.imagePath}`" alt="Post main image" />
    <img v-if="post.imagePath2" :src="`/storage/${post.imagePath2}`" alt="Post image 2" />
    <img v-if="post.imagePath3" :src="`/storage/${post.imagePath3}`" alt="Post image 3" />
    <img v-if="post.imagePath4" :src="`/storage/${post.imagePath4}`" alt="Post image 4" />
  </div>
</template>

<script>
export default {
  props: ['post'],
  // 其他逻辑...
}
</script>

内容的提问来源于stack exchange,提问作者hunter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 15:19:59