当前位置: 首页 > article >正文

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

在这里插入图片描述


http://www.kler.cn/a/272000.html

相关文章:

  • 探索WPF中的RelativeSource:灵活的资源绑定利器
  • 安卓动态设置Unity图形API
  • Unity自学之旅04
  • WPF 引发类型为“System.Windows.Forms.AxHost+InvalidActiveXStateException”的异常 解决办法
  • 解锁C# EF/EF Core:从入门到进阶的技术飞跃
  • RabbitMQ的消息可靠性保证
  • 教你申请腾讯云免费服务器,准备好账号
  • SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
  • echo,date,bc命令详解
  • 模型、算法、数据模型、模型结构是什么?它们之间有什么关联和区别?
  • git |常用命令
  • 【Python】新手入门学习:什么是相对路径,应用相对路径有哪些注意事项
  • 2024年3月职业健康安全管理体系基础考试真题
  • Golang 中 map[string]string 如何在 TOML 文件中配置
  • cannot find -xml2: No such file or directory的解决方法
  • redis的基本知识点
  • node.js快速入门-day03
  • Python零基础---爬虫技术相关
  • LangChain支持Claude3接口
  • 线程常用方法
  • CentOS7.9 安装SIPp3.6
  • 力扣细节题:字符串中的最大奇数
  • 使用ChatGPT高效完成简历制作[中篇]-有爱AI实战教程(五)
  • Node.js的事件驱动模型(非阻塞I/O)
  • 【JS】html字符转义
  • 【算法】火柴排队(离散化、归并排序)