久久寫一次檔案上傳都要再去爬文?,乾脆自己筆記起來!!
HTML內建的上傳Input
很醜,所以我都把它隱藏起來,要用時再自己手動去觸發他。為了觸發他因此要給他一個 ref
的值,這樣我們才能透過 $refs
直接去接觸DOM
。
<input type="file" style="display: none" ref="fileInput" >
這邊我是用 Quasar 框架的按鈕,用原生的 button
套 CSS
也是可以啦。主要是讓他看起來像上傳的按鈕就好~這邊要做的事情就是按下去讓他去觸發原本按下 Input
時的事件。
<q-btn @click="$refs.fileInput.click()">上傳檔案</q-btn>
選擇好檔案後為了要讓他能觸發上傳的事件,這邊要再改一下剛剛的 Input
,要在後面補上 v-on:change
。
<input type="file" style="display: none" ref="fileInput" @change="uploadFile()">
接著再底下的 script
裡的 methods
新增一個上傳的方法。對了,這裡會透過 Axios
來把檔案丟給 Laravel。
<template>
<q-page class="flex flex-center">
<q-btn @click="$refs.fileInput.click()">上傳檔案</q-btn>
<input type="file" style="display: none" ref="fileInput" @change="uploadFile">
</q-page>
</template>
<script>
import axios from 'axios'
export default {
methods: {
uploadFile () {
// 拿取檔案
const file = this.$refs.fileInput.files[0]
// 然後自己建立一個表單來放要上傳的資料
// 也可以順便帶其他資料例如 userId
const form = new FormData()
form.append('file', file)
form.append('userId', 'test1234')
// 上傳到後端伺服器
axios.post('https://後端網址', form)
}
}
}
</script>
這邊要用到 Laravel 內建的 Storage
功能,所以我們在一個 Controller 的最上面引入他:
use Illuminate\Support\Facades\Storage;
之後開始來處理剛剛丟進來的檔案(這邊假設Router都設定好了)
public function postFile (Request $req) {}
像是圖片的話可以直接用 Storage
的 put
方法存就好,因為他會幫我們把檔名變成亂數,可以不用花時間再去寫怕檔名重複的Code。這裡只要給他要儲存的路徑就好。
$storagePath = Storage::put('/public', $req['file']);
要知道剛剛程式自己存的檔名是什麼,可以透過 basename
去拿檔名:
$fileName = basename($storagePath);
而亂數的檔名會像這樣:61DsAms1VuHcMq1wcFx7S8cEHJA86SwoHPTTRUZV.png
路徑不填的話檔案會存在 storage/app
底下
如果要讓其他人可以從網站存取那就要建立一個與 public 的超連結
php artisan storage:link
這樣在 public/storage
底下就可以看到 storage/app/public
底下的東西囉
所以要從網站上看剛剛上傳的網址就會是
https://你的Laravel網址/storage/剛剛上傳的檔名
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Storage;
class FileController extends Controller
{
public function postFile (Request $req) {
$storagePath = Storage::put('/public', $req['file']);
$fileName = basename($storagePath);
// 接下來可以把檔名存進資料庫等等
// ...
}
}
請教一下博主:
在下拜讀您的文章覺得很值得學習,不過我試著依樣畫葫蘆時,卻遇到控制台一直報錯。
主要就是@click="$refs.fileInput.click()"
這一段
報錯內容:
[Vue warn]: Error in v-on handler: "TypeError: Cannot read property 'imageInput' of undefined"
有空麻煩教導一下
已經解決!謝謝!