element显示服务器的图片,Vue+ElementUI+SpringMVC实现图片上传和回显
Vue+ElementUI+SpringMVC實(shí)現(xiàn)圖片上傳和table回顯
而我們也常遇到表單中包含圖片上傳的需求,并且需要在table中顯示圖片,所以這里我就講一下結(jié)合后端的SpringMVC框架如何實(shí)現(xiàn)圖片上傳并提交到表單中,在table表格中回顯照片。
本案例對(duì)應(yīng)的開(kāi)源項(xiàng)目地址請(qǐng)看我的GitHub倉(cāng)庫(kù):
寫(xiě)在前面
本篇博文主要講Vue.js+ElementUI如何實(shí)現(xiàn)圖片上傳和提交表單,前端技術(shù)會(huì)講多一點(diǎn),因此:
如果你對(duì)SpringMVC文件上傳和下載不是很清楚,請(qǐng)查看我這篇博文: SpringMVC實(shí)現(xiàn)文件上傳和下載
因?yàn)榘咐赟SM框架,如果你你對(duì)SSM框架不是很清楚,請(qǐng)查看我這篇博文:SSM框架整合??GitHub
準(zhǔn)備
首先,請(qǐng)一定閱讀一下我的 SpringMVC實(shí)現(xiàn)文件上傳和下載 本篇博文將不在詳細(xì)講這部分內(nèi)容。
前端:
你會(huì)用到以下技術(shù):
Vue.js
Vue-resource.js
ElementUI
我們將實(shí)現(xiàn)的效果是什么呢?
圖片上傳:
table展示:
思路分析
想要實(shí)現(xiàn)圖片上傳和table的回顯,讓我們先分析以下實(shí)現(xiàn)思路:
圖片上傳和表單提交
那么你就要明白圖片上傳和表單提交是兩個(gè)功能,其對(duì)應(yīng)不同的接口,表單中并不是保存了這個(gè)圖片,而僅僅是保存了儲(chǔ)存圖片的路徑地址。我們需要分析以下幾點(diǎn):
1、圖片如何上傳,什么時(shí)候上傳?
圖片應(yīng)該在點(diǎn)擊upload上傳組件的時(shí)候就觸發(fā)了對(duì)應(yīng)的事件,當(dāng)選擇了要上傳的圖片,點(diǎn)擊確定的時(shí)候就請(qǐng)求了后端的接口保存了圖片。也就是說(shuō)你在瀏覽器中彈出的選擇框中選擇了要上傳的圖片,當(dāng)你點(diǎn)擊確定的一瞬間就已將圖片保存到了服務(wù)器上;而再點(diǎn)擊提交表單的時(shí)候,儲(chǔ)存在表單中的圖片數(shù)據(jù)僅僅是剛才上傳的圖片存儲(chǔ)地址。
2、如何獲取到已經(jīng)上傳的圖片的儲(chǔ)存地址?
因?yàn)樵跒g覽器上傳選擇框被確定選擇的瞬間已經(jīng)請(qǐng)求了后端接口保存了圖片,我們?cè)撛趺粗缊D片在哪里儲(chǔ)存呢?
前端: 比如我們使用了ElementUI提供的上傳組件,其就存在一個(gè)上傳成功的回調(diào)函數(shù):on-success,這個(gè)回調(diào)函數(shù)被觸發(fā)的時(shí)間點(diǎn)就是圖片成功上傳后的瞬間,我們就是要在這個(gè)回調(diào)函數(shù)觸發(fā)的時(shí)候獲取到圖片儲(chǔ)存的地址。
后端: 上面講了獲取地址,這個(gè)地址就是后端返回給前端的數(shù)據(jù)(JSON格式)。因?yàn)楹蠖藞D片上傳接口配置圖片儲(chǔ)存的地址,如果圖片上傳成功,就將圖片儲(chǔ)存的地址以JSON格式返回給前端。
3、如何提交表單
說(shuō)如何提交表單,這就顯得很簡(jiǎn)單了,因?yàn)樯厦嫖覀円呀?jīng)完成了:1、圖片成功上傳;2、獲取到了圖片在服務(wù)器上的儲(chǔ)存地址。利用Vue的雙向綁定思想,在圖片成功上傳的回調(diào)函數(shù)on-success中獲取到后端返回的圖片儲(chǔ)存地址,將這個(gè)地址賦值給Vue實(shí)例data(){}中定義的表單對(duì)象。這樣在提交表單的時(shí)候僅需要將這個(gè)表單對(duì)象發(fā)送給后端,保存到數(shù)據(jù)庫(kù)就行了。
圖片在table的回顯
想要將圖片回顯到table表格中其實(shí)很簡(jiǎn)單,前提只要你在數(shù)據(jù)庫(kù)中保存了正確的圖片儲(chǔ)存地址;在table表格中我們僅需要在
列中新定義一列即可完成圖片回顯。渲染table數(shù)據(jù)的時(shí)候循環(huán)給中的src賦值數(shù)據(jù)庫(kù)中保存的圖片url即可。后端實(shí)現(xiàn)
圖片上傳接口
注意: 關(guān)于SpringMVC如何實(shí)現(xiàn)文件上傳和下載,請(qǐng)看我的博文: SpringMVC實(shí)現(xiàn)文件上傳和下載 。這里我給出代碼,就不再解釋了(#^.^#):
這里我將文件上傳和下載接口單獨(dú)抽離在一個(gè)Controller類(lèi)中:
import com.instrument.entity.Result;
@RestController
public class UploadDownController {
/**
* 文件上傳
* home.php?mod=space&uid=952169 picture
* @param request
* @return
*/
@RequestMapping("/upload")
public Result upload(@RequestParam("picture") MultipartFile picture, HttpServletRequest request) {
//獲取文件在服務(wù)器的儲(chǔ)存位置
String path = request.getSession().getServletContext().getRealPath("/upload");
File filePath = new File(path);
System.out.println("文件的保存路徑:" + path);
if (!filePath.exists() && !filePath.isDirectory()) {
System.out.println("目錄不存在,創(chuàng)建目錄:" + filePath);
filePath.mkdir();
}
//獲取原始文件名稱(chēng)(包含格式)
String originalFileName = picture.getOriginalFilename();
System.out.println("原始文件名稱(chēng):" + originalFileName);
//獲取文件類(lèi)型,以最后一個(gè)`.`為標(biāo)識(shí)
String type = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
System.out.println("文件類(lèi)型:" + type);
//獲取文件名稱(chēng)(不包含格式)
String name = originalFileName.substring(0, originalFileName.lastIndexOf("."));
//設(shè)置文件新名稱(chēng): 當(dāng)前時(shí)間+文件名稱(chēng)(不包含格式)
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
String date = sdf.format(d);
String fileName = date + name + "." + type;
System.out.println("新文件名稱(chēng):" + fileName);
//在指定路徑下創(chuàng)建一個(gè)文件
File targetFile = new File(path, fileName);
//將文件保存到服務(wù)器指定位置
try {
picture.transferTo(targetFile);
System.out.println("上傳成功");
//將文件在服務(wù)器的存儲(chǔ)路徑返回
return new Result(true,"/upload/" + fileName);
} catch (IOException e) {
System.out.println("上傳失敗");
e.printStackTrace();
return new Result(false, "上傳失敗");
}
}
}
為什么返回一個(gè)Result數(shù)據(jù)類(lèi)型?
注意這個(gè)Result是我自己聲明的一個(gè)實(shí)體類(lèi),用于封裝返回的結(jié)果信息,配合@RestController注解實(shí)現(xiàn)將封裝的信息以JSON格式return給前端,最后看下我定義的Result:
public class Result implements Serializable {
//判斷結(jié)果
private boolean success;
//返回信息
private String message;
public Result(boolean success, String message) {
this.success = success;
this.message = message;
}
public boolean isSuccess() {
return success;
}
setter/getter...
}
表單提交接口
表單提交大家都比較熟悉了,配合圖片上傳,僅僅是在實(shí)體類(lèi)中多了一個(gè)字段存放圖片的URL地址:
@RestController
@RequestMapping("/instrument")
public class InstrumentController {
//注入
@Autowired
private InstrumentService instrumentService;
/**
* 添加
*
* @param instrument
* @return
*/
@RequestMapping("/save")
public Result save(Instrument instrument) {
if(instrument != null){
try{
instrumentService.save(instrument);
return new Result(true,"添加成功");
}catch (Exception e){
e.printStackTrace();
}
}
return new Result(false, "發(fā)生未知錯(cuò)誤");
}
}
如上
大家可能會(huì)疑惑這個(gè)為什么返回Result類(lèi)型的數(shù)據(jù)? 答:為了前端方便判斷接口執(zhí)行成功與否。因?yàn)槲仪岸耸褂玫氖荋TML頁(yè)面,想要從后端域?qū)ο笾腥?shù)據(jù)顯然就有點(diǎn)不現(xiàn)實(shí)了。
我寫(xiě)Controller的時(shí)候定義了全局的@RestController注解,和@Controller注解的區(qū)別是,前者多了@ResponseBody注解,這樣整合Controller類(lèi)返回的數(shù)據(jù)都將給自動(dòng)轉(zhuǎn)換成JSON格式。
前端實(shí)現(xiàn)
實(shí)現(xiàn)圖片上傳
這里我使用了ElementUI的文件上傳組件: 官方文檔
配合ElementUI的上傳組件,我們會(huì)這樣定義(這是form表單中的一部分):
ref="upload"
action="/upload.do"
name="picture"
list-type="picture-card"
:limit="1"
:file-list="fileList"
:on-exceed="onExceed"
:before-upload="beforeUpload"
:on-preview="handlePreview"
:on-success="handleSuccess"
:on-remove="handleRemove">
? ?? ???
注意,我這里僅展示了文件上傳的form-item,ElementUI的表單聲明是: 注意 表單中不需要指定enctype="multipart/form-data"這個(gè)參數(shù),與我們普通的文件上傳表單是不同的。
了解幾個(gè)參數(shù):
ref ref是Vue原生參數(shù),用來(lái)給組件注冊(cè)引用信息。引用信息將會(huì)注冊(cè)到父組件的$refs對(duì)象上,如果定義在普通的DOM元素上,那么$refs指向的就是DOM元素。
action action表示此上傳組件對(duì)應(yīng)的上傳接口,此時(shí)我們使用的是后端Controller定義的接口
name name表示當(dāng)前組件上傳的文件字段名,需要和后端的上傳接口字段名相同 。
list-type 文件列表的類(lèi)型,主要是文件列表的樣式定義。這里是卡片化。
:limit 最大允許上傳的文件個(gè)數(shù)。
file-list 上傳的文件列表,這個(gè)參數(shù)用于在這個(gè)上傳組件中回顯圖片,包含兩個(gè)參數(shù):name、url如果你想在這個(gè)文件上傳組件中咱叔圖片,賦值對(duì)應(yīng)的參數(shù)即可顯示,比如更新數(shù)據(jù)時(shí),其表單樣式完全和添加表單是相同的。但是table中回顯圖片是完全不需要用這個(gè)方式的。
:on-exceed 上傳文件超出個(gè)數(shù)時(shí)的鉤子函數(shù)。
:before-upload 上傳文件前的鉤子函數(shù),參數(shù)為上傳的文件,返回false,就停止上傳。
:on-preview 點(diǎn)擊文件列表中已上傳的文件時(shí)的鉤子函數(shù)
:on-success 文件上傳成功的鉤子函數(shù)
:on-remove 文件列表移除時(shí)的鉤子函數(shù)
:src 圖片上傳的URL。
JS部分
//設(shè)置全局表單提交格式
Vue.http.options.emulateJSON = true;
new Vue({
el: '#app',
data(){
return{
//文件上傳的參數(shù)
dialogImageUrl: '',
dialogVisible: false,
//圖片列表(用于在上傳組件中回顯圖片)
fileList: [{name: '', url: ''}],
}
},
methods(){
//文件上傳成功的鉤子函數(shù)
handleSuccess(res, file) {
this.$message({
type: 'info',
message: '圖片上傳成功',
duration: 6000
});
if (file.response.success) {
this.editor.picture = file.response.message; //將返回的文件儲(chǔ)存路徑賦值picture字段
}
},
//刪除文件之前的鉤子函數(shù)
handleRemove(file, fileList) {
this.$message({
type: 'info',
message: '已刪除原有圖片',
duration: 6000
});
},
//點(diǎn)擊列表中已上傳的文件事的鉤子函數(shù)
handlePreview(file) {
},
//上傳的文件個(gè)數(shù)超出設(shè)定時(shí)觸發(fā)的函數(shù)
onExceed(files, fileList) {
this.$message({
type: 'info',
message: '最多只能上傳一個(gè)圖片',
duration: 6000
});
},
//文件上傳前的前的鉤子函數(shù)
//參數(shù)是上傳的文件,若返回false,或返回Primary且被reject,則停止上傳
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg';
const isGIF = file.type === 'image/gif';
const isPNG = file.type === 'image/png';
const isBMP = file.type === 'image/bmp';
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isJPG && !isGIF && !isPNG && !isBMP) {
this.$message.error('上傳圖片必須是JPG/GIF/PNG/BMP 格式!');
}
if (!isLt2M) {
this.$message.error('上傳圖片大小不能超過(guò) 2MB!');
}
return (isJPG || isBMP || isGIF || isPNG) && isLt2M;
},
}
});
解釋
如上的JS代碼,主要是定義一些鉤子函數(shù),這里我么里梳理一下邏輯:
1、點(diǎn)擊ElementUI的上傳組件,瀏覽器自動(dòng)彈出文件上傳選擇窗口,我們選擇要上傳的圖片。
2、選擇好了要上傳的圖片,點(diǎn)擊彈窗右下角的確定按鈕觸發(fā)JS中定義的鉤子函數(shù)。
3、首先觸發(fā)的鉤子函數(shù)是beforeUpload(file)函數(shù),其中的參數(shù)file即代表當(dāng)前上傳的文件對(duì)象,beforeUpload()定義了對(duì)上傳文件格式校驗(yàn)。如果不是允許的格式就彈出錯(cuò)誤信息,并阻止文件上傳,若我那件格式允許,則繼續(xù)執(zhí)行。
4、通過(guò)了beforeUpload()函數(shù)的校驗(yàn),文件開(kāi)始調(diào)用后端接口將數(shù)據(jù)發(fā)送給后端。文件的字段名:picture,格式:multipart/form-data,雖然我們的表單沒(méi)有定義enctype="multipart/form-data"屬性,但是HTTP請(qǐng)求頭會(huì)自動(dòng)設(shè)置為multipart/form-data類(lèi)型。
5、這時(shí),如果后端邏輯沒(méi)有錯(cuò)誤,已經(jīng)正常的將圖片上傳到服務(wù)器上了,可以在指定文件夾中查看到已上傳的圖片,那么此時(shí)JS中會(huì)自動(dòng)調(diào)用handleSuccess()鉤子函數(shù),因?yàn)槲覀冊(cè)O(shè)置后端上傳接口上傳成功返回的數(shù)據(jù)是文件的保存路徑:
那我們就將這個(gè)路徑通過(guò)Vue的雙向綁定,賦值給表單對(duì)象的字段picture,那么提交表單的時(shí)候,該字段對(duì)應(yīng)的值就是這個(gè)路徑了。
6、如果我們?cè)冱c(diǎn)擊上傳文件按鈕,就會(huì)觸發(fā)onExceed()函數(shù),因?yàn)槲覀冊(cè)O(shè)置的limit最多上傳一個(gè)。
7、如果點(diǎn)擊圖片中的刪除按鈕,就會(huì)觸發(fā)handleRemove()函數(shù),并刪除此圖片。
8、如果點(diǎn)擊了已上傳的文件列表,就會(huì)觸發(fā)handlePreview()函數(shù)。
實(shí)現(xiàn)表單提交
表單提交就比較簡(jiǎn)單了,就是觸發(fā)對(duì)應(yīng)的click事件,觸發(fā)其中定義的函數(shù),將已在data(){}中定義的表單數(shù)據(jù)發(fā)送給后端接口:
提交數(shù)據(jù):
后端接口
@RequestMapping("/save")
public Result save(Instrument instrument) {
if(instrument != null){
try{
instrumentService.save(instrument);
return new Result(true,"添加成功");
}catch (Exception e){
e.printStackTrace();
}
}
return new Result(false, "發(fā)生未知錯(cuò)誤");
}
數(shù)據(jù)庫(kù)中保存的數(shù)據(jù):
實(shí)現(xiàn)table回顯圖片
table回顯圖片也是很簡(jiǎn)單的,僅需要在列中增加一列:
? ?? ?? ?? ?
label="運(yùn)行狀態(tài)"
width="80"
prop="operatingStatus">
因?yàn)槭褂肰ue,根據(jù)其雙向綁定的思想,再結(jié)合Element-UI提供渲染表格的方式是在的:data中指定對(duì)應(yīng)要渲染的數(shù)據(jù)即可。
注意 ElementUI渲染table的方式是:1、中定義:data;2、中定義prop="data中的參數(shù)"。但是因?yàn)槲覀円@示的是圖片而不是文本數(shù)據(jù),所以要在中定義:src="data中的變量"即可實(shí)現(xiàn)渲染。
后端就是正常的查詢(xún)數(shù)據(jù)庫(kù)數(shù)據(jù)即可了,為什么數(shù)據(jù)庫(kù)中保存了這個(gè)URL圖片就能直接顯示到HTML中,請(qǐng)看我這篇博文: SpringMVC實(shí)現(xiàn)文件上傳和下載
總結(jié)
以上是生活随笔為你收集整理的element显示服务器的图片,Vue+ElementUI+SpringMVC实现图片上传和回显的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pppoe 服务器 无线,无线路由器怎么
- 下一篇: 智能骨传导眼镜vue_穿戴设备迎新机遇,