vue的 v-for 循环中图片加载路径问题
先看一下產(chǎn)品需求,如下圖所示,
產(chǎn)品要求圖片和它的名稱一一對(duì)應(yīng),本來是非常簡(jiǎn)單的需求,后臺(tái)直接返回圖片路徑和名稱,前臺(tái)直接讀取就可以了,但是我們沒有存儲(chǔ)圖片的服務(wù)器,再加上是一個(gè)實(shí)驗(yàn)性的需求,圖片需要存放到前臺(tái)。當(dāng)時(shí)我想,vue?中的img?的src?可以動(dòng)態(tài)綁定到一個(gè)變量上, 很簡(jiǎn)單嗎,就沒有考慮太多,直接開始做了。
首先和后臺(tái)商量一下數(shù)據(jù)結(jié)構(gòu),因?yàn)閳D片要和名稱一一對(duì)應(yīng),所以后臺(tái)要返回中英文的名稱的映射,我把前臺(tái)的圖片名稱直接設(shè)置給后臺(tái)給的英文名稱,從而讀取圖片,圖片和中文名稱就一一對(duì)應(yīng)了。數(shù)據(jù)結(jié)構(gòu)如下:映射關(guān)系用對(duì)象表示,多個(gè)圖片,所以放到一個(gè)數(shù)組中
[{CnName:'荷花',EnName: 'lotus'},{CnName:'康乃馨',EnName: 'carnations'},{CnName:'牡丹',EnName: 'peony'}]現(xiàn)在前臺(tái)用vue-cli,?后臺(tái)用express?來模擬一下當(dāng)時(shí)的開發(fā)場(chǎng)景,也可以還原一下錯(cuò)誤和業(yè)務(wù)的迭代過程。新建一個(gè)文件夾,就叫vue-img吧,然后再在該文件夾中新建兩個(gè)文件夾,client, server, client?表示客戶端代碼,server?表示服務(wù)端代碼。?在client?文件夾中,打開命令窗口,執(zhí)行 vue init webpack-simple .?命令,后面的點(diǎn)表示當(dāng)前文件夾,為了簡(jiǎn)單,這里使用了simple?模版. server?文件夾,打開命令窗口,先執(zhí)行npm init?初始化為node?項(xiàng)目,然后npm install express cors --save,?安裝依賴,cors?是解決跨域的。
先來寫前端代碼,把a(bǔ)pp.vue?中的template和script中的內(nèi)容清空,保留它的css?樣式內(nèi)容,我們就不用寫樣式了。前端頁面,有兩個(gè)部分,一個(gè)是button,?點(diǎn)擊按鈕來發(fā)送請(qǐng)求,一個(gè)是圖片展示區(qū)域,它用的就是v-for? 循環(huán), template?內(nèi)容如下
<div id="app"><button @click='getFlower'>點(diǎn)擊加載請(qǐng)求</button><!-- 由于當(dāng)時(shí)想當(dāng)然地以為,src 就是綁定一個(gè)變量,所以就設(shè)置了一個(gè)默認(rèn)變量,這是出錯(cuò)的過程 --><ul><li v-for ="item in flowers" :key="item"><img :src="defaultImg" alt="flowers"><p>{{item}}</p></li></ul> </div> </template>由于template中用到了方法 getFlower,? 變量defaultImg 和?flowers,?所以要在script中進(jìn)行聲明。defaultImg?是一個(gè)圖片,所以還要引入進(jìn)來,?在src? 目錄中新建一個(gè)img文件夾,放幾張圖片。flowers是一個(gè)數(shù)組,我先預(yù)寫了一個(gè)['荷花', '康乃馨'],getFlower,因?yàn)闆]有后臺(tái),所以先沒有寫,?注意如果數(shù)據(jù)量大的,交互復(fù)雜,是要寫mock?數(shù)據(jù)的,這里比較簡(jiǎn)單就沒有寫。這也是出錯(cuò)的原因。代碼如下
import defaultImg from './img/lotus.jpg'; // import 引入圖片 export default {data() {return {flowers: ['荷花', '康乃馨'],defaultImg: defaultImg};},methods: {getFlower() {}} };整個(gè)頁面顯示如下,我以為沒有問題了。
現(xiàn)在再來寫后臺(tái)代碼,?用express?寫一個(gè)后臺(tái)接口,還是非常簡(jiǎn)單的。在server?文件夾中,建一個(gè)文件server.js?來寫后臺(tái)代碼
var express = require('express'); var cors = require('cors'); // 引入cors 中間件,解決跨域var app = express(); app.use(cors());// 前端發(fā)送的是get請(qǐng)求,接口是flowers. 返回的數(shù)據(jù)code 表示成功或失敗,obj 表示數(shù)據(jù) // 數(shù)據(jù)中Cn 表示中文名稱,En表示中文名稱 app.get('/flowers', (req, res) => {res.json({code: 0,obj: [{CnName:'荷花',EnName: 'lotus'},{CnName:'康乃馨',EnName: 'carnations'},{CnName:'牡丹',EnName: 'peony'}]}) }) app.listen(3000, () => {console.log('server start at 3000'); })現(xiàn)在用nodemon server.js?啟動(dòng)服務(wù),在瀏覽器地址輸入http://localhost:3000/flowers,?可以看到返回的數(shù)據(jù)表示接口ok.
現(xiàn)在再重新寫一下前端代碼,進(jìn)行前后端聯(lián)調(diào)。由于要發(fā)送請(qǐng)求,還要安裝axios 依賴。首先要根據(jù)后臺(tái)接口改一下template?內(nèi)容的li?
<ul><li v-for ="item in flowers" :key="item.EnName"><img :src="item.EnName" alt="flowers"><p>{{item.CnName}}</p></li></ul>然后,在script中引入 axios, flowers?數(shù)組清空,default img?刪除 ,?引入后臺(tái)數(shù)據(jù)所需要的三張圖片,?同時(shí)getFlower?方法發(fā)送請(qǐng)求
// 引入axios,用于發(fā)送請(qǐng)求,defaults 設(shè)置后臺(tái)請(qǐng)求地址 import axios from 'axios'; axios.defaults.baseURL = "http://localhost:3000"// 引入相關(guān)的圖片, 命名要和后臺(tái)保持一致 import lotus from './img/lotus.jpg'; import carnations from './img/carnations.jpg'; import peony from './img/peony.jpg';export default {data() {return {flowers: [], lotus,carnations,peony};},methods: {getFlower() {axios.get('/flowers').then(res => {if(res.status === 200 && res.data.code === 0) {this.flowers = res.data.obj;}})}} };我以為成功了,點(diǎn)擊按鈕發(fā)送請(qǐng)求,但是看到的如下畫面,沒有圖片
?
當(dāng)時(shí)想不通,img?的src?綁定的是變量,它和defaultImg?不應(yīng)該是一樣嗎?打開瀏覽器控制臺(tái),看到如下內(nèi)容,img?的src?已經(jīng)是一個(gè)字符串,它不是我們想要的變量了。
我想這里可能是它對(duì)item.EnName進(jìn)行了一次解析變成了字符串,就完事了,綁定變量,就是解析一次。而對(duì)于defalutImg?來說,它本來就是變量,無法再進(jìn)行分割解析,所以它會(huì)去data?里面去找,如果找不到,才報(bào)錯(cuò)。
那么我們現(xiàn)在要做的就是把item.EnName?變成圖片的地址,這樣進(jìn)行一次解析的時(shí)候,直接去讀取圖片。要怎么做到呢?當(dāng)時(shí)?我也不是很清楚,就百度了一下,有人提到了require?方法, require?一個(gè)圖片路徑,我想require?什么,以前沒有聽說過require?這個(gè)關(guān)鍵字啊。想了一段時(shí)間,突然就明白了,require?是一個(gè)commonJs?規(guī)范的關(guān)鍵字,當(dāng)我們?cè)趯憂ode?代碼的時(shí)候,都是有require?去讀取資源的。在前端js?中,一直使用import,直接忘記了,不知道怎么用了。webpack?把img?當(dāng)做一種資源,所以使用時(shí)要先引進(jìn)。引進(jìn)方式有兩種,一種是import ,?一種是require,?因?yàn)閣ebpack?同時(shí)支持ES6 module?和?commonJs?規(guī)范.? import?是個(gè)語句,只能在js?代碼頂部使用,?而require?不一樣,它是一個(gè)表達(dá)式,可以進(jìn)行賦值操作。我們?cè)囈幌?#xff0c;用require 引入圖片是怎么樣的效果,在 script 標(biāo)簽時(shí),寫下
var img = require('./img/lotus.jpg'); console.log(img);刷新瀏覽器,在控制臺(tái)上可以看到如下輸出
正好是圖片的路徑,也正是我們想要的內(nèi)容,剛才也說了,require是一個(gè)表達(dá)式,它可以用到任何js 表達(dá)式能用到的地方。我這時(shí)就想,把后臺(tái)返回的代碼進(jìn)行重新組裝,EnName?直接是圖片路徑。getFlower?方法修改如下
getFlower() {axios.get('/flowers').then(res => {if(res.status === 200 && res.data.code === 0) {this.flowers = res.data.obj.map(item => {return {CnName: item.CnName,EnName: require(`./img/${item.EnName}.jpg`) // 利用require 引入圖片,獲得圖片路徑 }})}})}這時(shí)刷新瀏覽器,點(diǎn)擊按鈕發(fā)送請(qǐng)求,可以看到圖片了并且一一對(duì)應(yīng),?成功了。
?
這時(shí)又一想,既然require?是一個(gè)表達(dá)式,在template模版中是直接可以解析js?表達(dá)式,那么直接把img?的src?綁定到require?表達(dá)式就可以了,把getFlower?方法,回退到上一次代碼,然后template?代碼如下
<ul><li v-for ="item in flowers" :key="item.EnName"><img :src="require(`./img/${item.EnName}.jpg`)" alt="flowers"><p>{{item.CnName}}</p></li></ul>同樣也成功了。
最后寫代碼的時(shí)候發(fā)現(xiàn),如果讀取的圖片不存在,上面的方法就會(huì)報(bào)錯(cuò),并且沒有辦法處理。這時(shí)還要回到j(luò)s?的代碼處理。我又把html代碼回到以前,然后在getFlower方法中進(jìn)行錯(cuò)誤處理,既然讀取報(bào)錯(cuò),我們讀取的代碼就放到try中,?如果有報(bào)錯(cuò),就在catch?看處理,提供一個(gè)默認(rèn)圖片,try catch?處理讀取異常。 try catch?的邏輯
try {img = require(`./img/${item.EnName}.jpg`);} catch (err) {img = require('./img/lotus.jpg');}整?個(gè)app.vue?
<template> <div id="app"><button @click='getFlower'>點(diǎn)擊加載請(qǐng)求</button><ul><li v-for ="item in flowers" :key="item.EnName"><img :src="item.EnName" alt="flowers"><p>{{item.CnName}}</p></li></ul> </div> </template><script> // 引入axios,用于發(fā)送請(qǐng)求,defaults 設(shè)置后臺(tái)請(qǐng)求地址 import axios from 'axios'; axios.defaults.baseURL = "http://localhost:3000";export default {data() {return {flowers: []};},methods: {getFlower() {axios.get('/flowers').then(res => {if(res.status === 200 && res.data.code === 0) {this.flowers = res.data.obj.map(item => {var img = null;try {img = require(`./img/${item.EnName}.jpg`);} catch (err) {img = require('./img/lotus.jpg');}return {CnName: item.CnName,EnName: img}})}})}} }; </script>?
轉(zhuǎn)載于:https://www.cnblogs.com/SamWeb/p/8519735.html
總結(jié)
以上是生活随笔為你收集整理的vue的 v-for 循环中图片加载路径问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDU - 1223 DP 分类
- 下一篇: Vue 2.x + Webpack 4.