vue2+vant2+Laravel7 实现多图上传到七牛云

news2025/1/12 23:15:28

后端接口

1、路由,在 routes/api.php

Route::resource('photos', 'PhotoController')->only('store');

2、创建对应控制器

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;

class PhotoController extends Controller
{
    /***
     * 上传图片
     * @param Request $request
     */
    public function store(Request $request)
    {
        if ($request->hasFile('file') && $request->file('file')->isValid()) {
            $path = $request->file->store('public/images');
            //上传到七牛云
            $file_path = storage_path('app/') . $path;

            qiniu_upload($file_path);
            return response()->json( 'https://image.xxx.com/' . basename($file_path));
        }
    }
}

3、定义辅助函数 qiniu.php

<?php
// 引入鉴权类
use Qiniu\Auth;
// 引入上传类
use Qiniu\Storage\UploadManager;

function qiniu_upload($filePath)
{
    $accessKey = "fAoxxxxxxxxxxxxxxxxxxxxxxxxx";
    $secretKey = "dkCxxxxxxxxxxxxxxxxxxxxxxxxx";
    $bucket = "xxxxx";
    $auth = new Auth($accessKey, $secretKey);
    $token = $auth->uploadToken($bucket);
    // 上传到七牛后保存的文件名
    $key = basename($filePath);
    // 初始化 UploadManager 对象并进行文件的上传。
    $uploadMgr = new UploadManager();
    // 调用 UploadManager 的 putFile 方法进行文件的上传。
    $uploadMgr->putFile($token, $key, $filePath);
    unlink($filePath);
}

这里需要安装七牛云的包,不会用的可以看七牛官网或在评论区给我留言。

前端

1、创建 vue2 项目,此步骤省略,自行完成。
2、安装 axiosvue2-toastVant2 前端 UI 框架,

npm install axios

npm install toast2-vue -S

npm i vant@latest-v2 -S

3、在 main.js 中,全部代码如下,供参考:

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import Vant from 'vant'
import 'vant/lib/index.css'
import axios from 'axios'
import 'vue2-toast/lib/toast.css'
import Toast from 'vue2-toast'

axios.defaults.baseURL = 'https://xxx.xxx.com/'
Vue.prototype.$http = axios
Vue.use(Toast)
Vue.use(Vant)
Vue.config.productionTip = false

new Vue({
  router,
  render: h => h(App)
}).$mount('#app')

4、在 src/router/index.js 中添加路由,代码如下:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const routes = [
  {
    path: '/',
    name: 'Home',
    component: () => import('../views/Home.vue')
  }
]

const router = new VueRouter({
  routes
})

export default router

5、准备视图,在 src/views/Home.vue 中,全部代码如下:

<template>
  <div class="home">
    <h2 class="van-doc-title" style="text-align: center">督查记录表</h2>
    <van-form @submit="onSubmit">
      <h2 class="van-doc-demo-block__title" style="background-color: #f7f8fa;">基础信息</h2>
      <van-field
        v-model="form.name"
        label="督查员:"
        placeholder="请输入姓名"
        :rules="[{ required: true, message: '请填写姓名' }]"
      />
      <van-field
        readonly
        clickable
        name="picker"
        :value="form.department"
        label="督查场部:"
        placeholder="点击选择"
        @click="showPicker = true"
      />
      <van-popup v-model="showPicker" position="bottom">
        <van-picker
          show-toolbar
          :columns="stages"
          @confirm="onConfirm"
          @cancel="showPicker = false"
        />
      </van-popup>
      <van-field
        v-model="form.address"
        label="督查地点:"
        placeholder="请输入地点名称"
        :rules="[{ required: true, message: '请填写地点名称' }]"
      />
      <van-field
        v-model="form.head"
        label="岗位负责人:"
        placeholder="请输入负责人姓名"
        :rules="[{ required: true, message: '请填写负责人姓名' }]"
      />
      <h2 class="van-doc-demo-block__title" style="background-color: #f7f8fa;">检查项目</h2>
      <van-field name="radio" label="卫生情况:">
        <template #input>
          <van-radio-group v-model="form.health" direction="horizontal">
            <van-radio name="1">合格</van-radio>
            <van-radio name="0">不合格</van-radio>
          </van-radio-group>
        </template>
      </van-field>
      <van-field name="uploader" label="附图:">
        <template #input>
          <van-uploader v-model="form.imageList" multiple :max-count="2"
                        :after-read="afterRead"/>
        </template>
      </van-field>
      <van-field
        v-model="form.message"
        rows="2"
        autosize
        label="留言:"
        type="textarea"
        maxlength="50"
        placeholder="请输入留言"
        show-word-limit
      />
      <div style="display: flex;align-items: center;">
        <h2 class="van-doc-demo-block__title"
            style="font-size: 14px;color: #646566;font-weight: normal;padding-right: 15px">评分:</h2>
        <van-rate
          v-model="form.rate"
          :size="25"
          color="#ffd21e"
          void-icon="star"
          void-color="#eee"
          count="10"
          @change="onChange"
        />
      </div>
      <div style="margin: 50px 16px 16px 16px;">
        <van-button round block type="info" native-type="submit">提交</van-button>
      </div>
    </van-form>
  </div>
</template>

<script>
/* eslint-disable */
export default {
  data () {
    return {
      stages: ['总部', '杨湖场', '株山场', '天子山场', '品格饲料厂'],
      showPicker: false,
      form: {
        name: '',
        department: '',
        address: '',
        head: '',
        health: '1',
        imageList: [],
        message: '',
        rate: 0
      }
    }
  },
  methods: {
  	// 选择框
    onConfirm (value) {
      this.form.department = value
      this.showPicker = false
    },
    // 点击评分
    onChange (value) {
      this.form.rate = value
    },
    // 点击上传
    afterRead (file) {
      file.status = 'uploading'
      file.message = '上传中...'

      const formData = new FormData()
      formData.append('file', file.file)

      this.uploadImage(formData).then(response => {
        // 假设返回的response.data是图片的URL
        file.content = response.data
        file.status = 'done'
        file.message = '上传成功'
        this.form.imageList = [...this.form.imageList] // 通过替换imageList数组的内容来更新视图
      })
    },
    // 图片上传至后端服务器
    uploadImage (formData) {
      const uploadUrl = 'https://xxx.xxx.com/api/photos'
      return this.$http.post(uploadUrl, formData, {
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      })
    },
    // 表单提交
    async onSubmit () {
      const res = await this.$http.post('api/check', this.form)
      if (res.data.status === true) {
        this.$toast.center(res.data.message)
        this.form = {}
        this.form.health = '1'
      }
    }
  }
}
</script>

<style>
.van-doc-demo-block__title {
  padding: 10px 16px;
  color: rgba(69, 90, 100, 0.6);
  font-weight: normal;
  font-size: 14px;
  line-height: 16px;
}

.van-cell {
  padding: 15px 16px;
}

.van-button--info {
  background-color: #f4645f;
  border: 1px solid #f4645f;
}

.van-radio__icon--checked .van-icon {
  background-color: #f4645f;
  border-color: #f4645f;
}
</style>

上述代码其实是实现一个 form 表单的提交,里面有个比较重要的功能,就是多图上传的问题。最终的效果如下图:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1524045.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

面部表情参考图

创造表情形变 | Character Creator | Reallusion 皮笑肉不笑&#xff1f;读取情绪的AI说&#xff1a;我太难了_面部

HAProxy高性能负载均衡器

一、HAProxy基础知识 &#xff08;一&#xff09;HAProxy概述 HAProxy是一款基于事件驱动、单进程模型设计的四层与七层负载均衡器&#xff0c;它能够在TCP/UDP层面以及HTTP(S)等应用层协议上实现高效的流量分发。HAProxy不仅适用于Web服务器负载均衡&#xff0c;还能应用于数据…

RabbitMQ学习总结-基础篇

1..RabbitMQ 本身是一个消息中间件&#xff0c;在服务应用中&#xff0c;可解决高性能&#xff0c;高并发&#xff0c;高应用的问题&#xff0c;极大程度上解决了应用的性能问题。 2.MQ的使用分为生产者和消费者&#xff0c;生产者生产消息&#xff0c;消费者去消费消息。 3.…

cesium.js加载模型后,重新设置旋转角度属性值

// 加载模型var position Cesium.Cartesian3.fromDegrees(longitude, latitude, height);// 计算矩阵var rollAngleDegrees 15; // 设置翻滚角度var rollAngleRadians Cesium.Math.toRadians(rollAngleDegrees); // 将角度转换为弧度var orientation Cesium.Transforms.eas…

android 怎么自定义view

首先了解view的绘制流程&#xff1a; 所以onmeasure ---测量view onlayout---确定view大小----》所以继承ViewGroup必须要重写onlayout&#xff0c;确定子view 而onDraw----是继承view时候需要操作的。 所以&#xff1a;自定义ViewGroup一般是利用现有的组件根据特定的布局…

Python电梯楼层数字识别

程序示例精选 Python电梯楼层数字识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《Python电梯楼层数字识别》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学习与应…

操作系统内功篇:硬件结构之如何写出让CPU执行更快的代码?

一 前言 因为CPU要操作的数据都在CPU Cache中的话&#xff0c;就不用再从内存中读取数据了&#xff0c;这样就提高了效率&#xff0c;访问的数据在CPU Cache中越多&#xff0c;有个专业名词称为缓存命中率高&#xff0c;所以说&#xff0c;缓存命中率越高&#xff0c;自然执行…

Jupyter Notebook出错提示An error occurred while retrieving package information解决办法

出错日志信息&#xff1a; To access the notebook, open this file in a browser:file:///C:/Users/colda/AppData/Roaming/jupyter/runtime/nbserver-14564-open.htmlOr copy and paste one of these URLs:http://localhost:8888/?token3c0113e5da07c0b8b8c9de74ffb453c5047…

在idea中配置tomcat服务器,然后部署一个项日

1.下载tomcat Tomcat下载 点击右边的tomcat8 找到zip点击下载 下载完&#xff0c;解压到你想放置的路径下 2.配置环境变量 打开设置找到高级系统设置点击环境变量 点击新建&#xff0c;变量名输入&#xff1a;CATALINA_HOME&#xff0c;变量值就是Tomcat的安装路径&#x…

机器人阻抗控制中的transparency(透明度)

在机器人控制领域&#xff0c;transparency&#xff08;透明性&#xff09;是一个描述机器人在物理交互过程中如何响应外部力或运动的术语。透明性在这里通常意味着机器人的运动和行为对于与其交互的用户或环境来说是直观且可预测的。换句话说&#xff0c;透明性意味着机器人的…

【二分查找详细解析】 【图解】 例题【洛谷P2249 【深基13.例1】查找】

文章目录 二分查找的基础解释例题【洛谷P2249 【深基13.例1】查找】code↓ 二分查找的基础解释 二分的时间复杂度为 O ( l o g n ) O(log n) O(logn)&#xff0c;进行二分查找的序列必须满足单调性 我们可以先定义两个值 l , r l,r l,r &#xff0c;来表示查找到的左端点 l…

接口与多态

通过接口实现多态 接口中声明若干个 bstract方法&#xff1b; 方法体的内容细节由实现接口的类去完成&#xff0c;不同的类有 不同的实现方式 → 则接口变量在回调接口方法时具有多 种形态。 用接口进行程序设计的核心思想 使用接口回调技术&#xff1a;接口变量存放实现该接口…

DP最长上升子序列模型

目录 怪盗基德的滑翔翼代码实现 登山代码实现 合唱队形代码实现 友好城市问题分析代码实现 最大上升子序列和代码实现 *拦截导弹问题分析代码实现扩展 *导弹防御系统问题分析代码实现 *最长公共上升子序列问题分析代码实现 LIS 问题一般有三种解法 朴素版动态规划贪心二分树状…

测试用例要如何写

1、测试点与测试用例 测试点不等于测试用例&#xff0c;这是我们首先需要认识到的。 问题1&#xff1a;这些测试点在内容上有重复&#xff0c;存在冗余。 问题2&#xff1a;一些测试点的测试输入不明确&#xff0c;不知道测试时要测试哪些。 问题3&#xff1a;总是在搭相似…

树与二叉树(数据结构)

本篇博客讲解 树与二叉树&#xff0c;后续会继续讲解堆 —————————————————————— 1.树概念及结构 1.1树的概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看…

CMAKE_CUDA_ARCHITECTURES set to ‘native’多版本与版本号矛盾问题,报错

CMAKE_CUDA_ARCHITECTURES set to ‘native’多版本与版本号矛盾问题&#xff0c;报错 1. 报错提醒如下图2. 原因本地安装多个cuda版本导致native寻找到多个版本&#xff0c;导致报错3. 具体配置需要根据你的显卡型号来确认 1. 报错提醒如下图 2. 原因本地安装多个cuda版本导致…

Redis - String 字符串

前言 下表中包含本博客提到的所有命令 字符串类型是 Redis 最基础的数据类型&#xff0c;关于字符串需要特别注意&#xff1a; 1&#xff09;⾸先 Redis 中所有的键&#xff08;key&#xff09;的类型都是字符串类型&#xff0c;⽽且其他⼏种数据结构也都是在字符串类似基础上…

ffmpeg 滤镜实现不同采样率多音频混音

音频混音在音视频开发中是十分重要的一个环节,所谓音频混音就是将所有需要混音的数据相加得到混音数据,然后通过某个算法进行非法数据的处理;例如相加数值超过最大值,最小值等! 在实际的音频开发中,要实现混音的流程如下: 因此我们的编码实现就分为五部分:寻找…

中经评论:“人工智能+”不止是加法

以下文章来源&#xff1a;经济日报 今年&#xff0c;“人工智能”首次被写入《政府工作报告》&#xff0c;这个新提法为发展数字经济、推进数实融合指明了新路径。值得注意的是&#xff0c;“人工智能”不是简单相加&#xff0c;而是要通过新技术催生新质生产力&#xff0c;为经…

MyBatisPlus 之三:BaseMapper 详解和 CRUD 案例详解

BaseMapper详解 1. SQL 日志开启 为了更好更快学习 MyBatisPlus &#xff0c;需要配置 SQL 日志&#xff0c;这样方便我们能随时看到执行过程中使用的 SQL 语句&#xff0c;有助于理解执行原理及方便 SQL 错误调试 mybatis-plus.configuration.log-implorg.apache.ibatis.logg…