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

后端接口

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 表单的提交,里面有个比较重要的功能,就是多图上传的问题。最终的效果如下图:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LangChain: 调研报告

概述 LangChain是一个用于开发由语言模型驱动的应用程序的框架。它允许创建能够连接到上下文源&#xff08;如提示指令、少量示例、内容基础等&#xff09;的应用程序&#xff0c;并且能够进行推理&#xff08;基于提供的上下文如何回答问题、采取何种行动等&#xff09;。提供…

最佳实践:Postman 怎么调试 WebSocket

WebSocket 是一个支持双向通信的网络协议&#xff0c;它在实时性和效率方面具有很大的优势。Postman 是一个流行的 API 开发工具&#xff0c;它提供了许多功能来测试和调试 RESTful API 接口&#xff0c;最新的版本也支持 WebSocket 接口的调试。想要学习更多关于 Postman 的知…

力扣24. 两两交换链表中的节点

新建虚拟头节点&#xff0c;用3个指针记录前3个节点&#xff0c;然后再相互赋值指向&#xff0c;再移动当前节点&#xff0c;当前节点所在的位置&#xff0c;只能交换该节点的后两个节点&#xff08;所以必须建立虚拟头节点&#xff0c;才能操作第1&#xff0c;2个节点&#xf…

机器学习——压缩网络作业

文章目录 任务描述介绍知识蒸馏网络设计 Baseline实践 任务描述 网络压缩&#xff1a;使用小模型模拟大模型的预测/准确性。在这个任务中&#xff0c;需要训练一个非常小的模型来完成HW3&#xff0c;即在food-11数据集上进行分类。 介绍 有许多种网络/模型压缩的类型&#xff0…

【静夜思】为什么我们会如此喜欢夜晚呢

作为一名大学生&#xff0c;熬夜对我来说已是常态。每天都是近乎一点钟才有困意&#xff0c;觉得应该上床睡觉了&#xff0c;即使明天早八&#xff0c;即使明天有很多课。我也观察过身边的朋友&#xff0c;他们中大多数也和我一样&#xff0c;基本都是在12点过后才入睡。当今的…

AIGC笔记--关节点6D位姿按比例融合

1--核心代码 6D位姿一般指平移向量和旋转向量&#xff0c;Maya软件中关节点的6D位姿指的是相对平移向量和欧拉旋转向量&#xff1b; 为了按比例融合两个Pose&#xff0c;首先需要将欧拉旋转向量转换为旋转矩阵&#xff0c;在将旋转矩阵转换为四元数&#xff0c;利用球面线性插值…

指针 六 ---总结

文章目录 前言1.指针和指针变量2.const修饰2.1.const int* p 修饰的是指针指向的内容&#xff0c;保证指针指向的内容不能通过指针来改变。但是指针变量本⾝的内容可变。2.2 int const *p2.3 int *const p2.4 const int* const p 3. 指针数组&#xff08;array of pointers&…

彻底学会系列:一、机器学习之梯度下降(1)

1 梯度下降概念 1.1 概念 梯度下降是一种优化算法&#xff0c;用于最小化一个函数的值&#xff0c;特别是用于训练机器学习模型中的参数&#xff0c;其基本思想是通过不断迭代调整参数的值&#xff0c;使得函数值沿着梯度的反方向逐渐减小&#xff0c;直至达到局部或全局最小…

如何在webapp中手动部署

前言&#xff1a;这个有不知道怎么下载Tomcat的可以看我这篇博客的前面&#xff0c;有相关链接&#xff0c;下载好后我那边也有如何运行成功的 在idea中配置tomcat服务器&#xff0c;部署一个项目-CSDN博客 接下来进入这篇博客的正题&#xff01;怎么手动部署 先找到我们下载…

java.lang.NoSuchMethodException异常解决

标题 java.lang.NoSuchMethodException异常的正确解决方法摘要&#x1f680; 异常介绍&#x1f9d0; 异常原因分析&#x1f6e0; 解决方法核对方法名称和参数使用正确的方法签名调整方法访问权限 &#x1f4dd; 解决步骤详解&#x1f5a5; 代码案例演示❓ QA部分Q: 如何区分jav…

Linux环境开发工具之yum

前言 前面我们已经对基本的指令和权限进行了介绍&#xff0c;本期开始我们将介绍常用的开发工具。例如&#xff1a;软件包管理器yum。 本期内容介绍 Linux上安装软件的方式 什么是yum yum的相关操作 yum的本地配置和yum源 一、Linux上安装软件的方式 在介绍Linux上如何安装一…

uboot的移植——移植uboot官方的uboot到x210开发板(2)

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考内容 1、uboot的移植——移植uboot官方的uboot到x210开发板&#xff08;1&#xff09; 2、uboot启动流程——C阶段的start_armboot函数-CSDN博客 3、以官方uboot移植uboot(SD卡驱动移植)-CSDN博…

Linux 块设备驱动

Linux 三大驱动分别是&#xff1a;字符设备驱动、块设备驱动、网络设备驱动。 块设备是针对存储设备的&#xff0c;比如 SD 卡、EMMC、NAND Flash、Nor Flash、SPI Flash、机械硬盘、固态硬盘等。因此块设备驱动其实就是这些存储设备驱动&#xff0c;块设备驱动相比字符设备驱…

【洞察】区块链、web3、元宇宙等技术共同催生出了什么样的商业未来?

下文为中国信息通信研究院云计算与大数据研究所所长何宝宏为思二勋所著的《分布式商业生态战略&#xff1a;数字商业新逻辑与企业数字化转型新策略》一书所作的推荐序。 近两年来&#xff0c;区块链已从鲜为人知发展到尽人皆知且众说纷纭&#xff0c;从产业初期的静默发展到产…

若你有才能,最好能遇上识才之人,高俅发迹的故事很好诠释了千里马与伯乐的关系

若你有才能&#xff0c;最好能遇上识才之人&#xff0c;高俅发迹的故事很好诠释了千里马与伯乐的关系 其实&#xff0c;“千里马”和“伯乐”都是中国古代传说里的角色。伯乐是古代一个善于相马&#xff08;识别马的好坏&#xff09;的人&#xff0c;而“千里马”则是指一匹能跑…

2、FreeRTOS之队列管理

xQueueReceive() 用于从队列中接收 ( 读取&#xff09;数据单元。接收到的单元同时会从队列 中删除。 xQueuePeek() 也是从从队列中接收数据单元&#xff0c;不同的是并不从队列中删出接收到 的单元。 uxQueueMessagesWaiting()用于查询队列中当前有效数据单元个数。 写队列任…

简介:项目管理九大知识五大过程

前言 项目管理&#xff08;Project Management,PM/Management by Projects,MBP&#xff09; 在有限的资源约束下&#xff0c;运用系统的观点、方法和理论&#xff0c;对项目涉及的全部工作进行有效地管理。即从项目的投资决策开始到项目结束的全过程进行计划、组织、指挥、协调…

【首次抽奖】16G、32G免费送!云服务器选购推荐 京东云 阿里云 腾讯云对比 幻兽帕鲁 雾锁王国 省钱学生党

好消息&#xff1a;抽奖活动开启&#xff01;时间&#xff1a;3月17日——3月24日 最高奖品&#xff1a;16G 6个月&#xff1b;32G 3个月 抽奖规则&#xff1a;B站点赞评论关注即可参与抽奖&#xff0c;3.24日公布获奖名单。 抽奖地址&#xff1a; 【首次抽奖】16G、32G免费…

TTS 擂台: 文本转语音模型的自由搏击场

对文本转语音 (text-to-speech, TTS) 模型的质量进行自动度量非常困难。虽然评估声音的自然度和语调变化对人类来说是一项微不足道的任务&#xff0c;但对人工智能来说要困难得多。为了推进这一领域的发展&#xff0c;我们很高兴推出 TTS 擂台。其灵感来自于LMSys为 LLM 提供的…

检索增强生成(RAG)应用的构建:LangChain与LlamaIndex的比较与选择

对于我要做RAG应用&#xff0c;我应该使用两者中的哪一个。或者说还是都使用&#xff1f; 在人工智能领域&#xff0c;检索增强生成&#xff08;RAG&#xff09;应用正变得越来越受欢迎&#xff0c;因为它们能够结合大型语言模型&#xff08;LLMs&#xff09;的自然语言处理能力…