vue動(dòng)態(tài)定義圖片路徑

最近在使用vue動(dòng)態(tài)設(shè)置圖片路徑的時(shí)候遇到了一些問(wèn)題,特此整理。

我想實(shí)現(xiàn)的效果:點(diǎn)擊圖片,彈出系統(tǒng)圖片選擇框乳蛾,選擇圖片后替換原圖片。

App.vue中:

<input type="file" id="avatar" @change="chooseFile($event)" accept="image/*" style="display: none" >
<label for="avatar">
    <img :src="../assets/user_1.png" alt="圖片">
</label>

結(jié)果:

默認(rèn)圖片加載成功峦萎,點(diǎn)擊該圖片可以彈出圖片選擇框屡久。

本著組件抽象的原則,我想把上述代碼抽象成組件爱榔,并且希望默認(rèn)的圖片url可以在父組件指定被环,于是,我這樣寫:
App.vue:

<template>
    <ItemShow-imageChoose id="userPicture" imageSrc="../assets/user.png"></ItemShow-imageChoose>
</template>
<script>
    import ItemShow_imageChoose from "./components/ItemShow-imageChoose"
    export default {
      name:'App',
      components: {
          "ItemShow-imageChoose":ItemShow_imageChoose
      }
    }

./components/ItemShow-imageChoose.vue:

<template>
    <div>
      <input type="file" :id="id" @change="chooseFile($event)" accept="image/*" style="display: none" >
        <label :for="id">
          <img :src="imageSrc" alt="圖片">
        </label>
    </div>
  </template>
  <script>
      export default{
          name:'ItemShow_imageChoose',
          props:{
              "id":[String],
              "imageSrc":[String]
          },
          methods:{
              chooseFile(e){
//                  this.$emit('choose',e.target.files)
              }
          }
      }
</script>

結(jié)果:

默認(rèn)圖片沒有加載出來(lái)详幽。

開始一步步找錯(cuò)....

首先筛欢,把圖片的src移至子組件的data中浸锨,看圖片是否能加載出來(lái):

./components/ItemShow-imageChoose.vue:

<template>
    <div>
        <input type="file" :id="id" @change="chooseFile($event)" accept="image/*" style="display: none" >
        <label :for="id">
            <img :src="src" alt="圖片" />
        </label>
    </div>
</template>
<script>
    export default{
        name:'ItemShow_imageChoose',
        props:{
            "id":[String],
            "imageSrc":[String]
        },
        data(){
          return {
              src:'../assets/user.png'    //重點(diǎn)看這里
          }
        },
        methods:{
            chooseFile(e){
//                this.$emit('choose',e.target.files)
            }
        }
    }
</script>

結(jié)果:

本來(lái)以為這樣寫肯定是對(duì)的,結(jié)果竟然不對(duì)版姑,但是這個(gè)結(jié)果也說(shuō)明:?jiǎn)栴}不是出在父子組件的參數(shù)傳遞上柱搜。

于是開始查資料....

看了一些文章和問(wèn)答,也大致理解了出錯(cuò)的原因(參考文章見附錄)剥险,是圖片路徑的問(wèn)題聪蘸。

如果圖片地址是直接寫死在html或者css里的,webpack會(huì)幫你處理這個(gè)圖片最終的地址(要用到url-loader)表制,例如:
初始:

<template>
    <img src="./相對(duì)地址.jpg" />
</template>

webpack編譯后會(huì)變成:

    <img src="/絕對(duì)地址.jpg" />
    <!-- 或者 -->
    <img src="data:image/jpg;base64......." />

實(shí)測(cè):

<template>
    <img src="../assets/user.png" />
</template>

打包成絕對(duì)路徑:

打包成base64字符串:

項(xiàng)目目錄:

以上就是webpack打包的兩種方式健爬,我們重點(diǎn)看第一種。第一種方式么介,圖片是以絕對(duì)路徑(以/開頭的路徑就是絕對(duì)路徑娜遵,/指根目錄,根目錄在本地就是指磁盤壤短,在github上就是指?jìng)}庫(kù)的根目錄设拟,在網(wǎng)站上就是指服務(wù)器的根目錄)進(jìn)行查找,圖片的目錄為/static/img久脯,但是我們查看上圖項(xiàng)目目錄纳胧,發(fā)現(xiàn)static目錄下并沒有img目錄,也沒有圖片帘撰,那么這里的路徑是怎么來(lái)的呢躲雅?

運(yùn)行npm run build,再看一下項(xiàng)目目錄:

我們?cè)赿ist目錄下面找到了該圖片骡和。由此知道,webpack打包后相寇,會(huì)將靜態(tài)資源文件放在dist/static/img下慰于,我們的網(wǎng)站實(shí)際上以dist目錄作為根目錄,并由此加載該目錄下的index.html所需的css唤衫、js婆赠、img等

現(xiàn)在我們使用Vue.js來(lái)動(dòng)態(tài)定義圖片路徑:

<template>
    <div>
        <img :src="src" alt="圖片" />
    </div>
</template>
<script>
    export default{
        data(){
          return {
              src:`../assets/user.png`
          }
        }
    }
</script>

結(jié)果:

dist目錄為根目錄,index.html的路徑為“./index.html”佳励,那“../assets/user.png”即為與dist目錄平級(jí)的assets目錄下面的user.png休里,我們發(fā)現(xiàn)該目錄不存在,圖片自然加載失敗赃承。

當(dāng)Vue.js來(lái)動(dòng)態(tài)定義圖片路徑的時(shí)候妙黍,url-loader是無(wú)法探測(cè)到圖片路徑的。我們build后發(fā)現(xiàn)瞧剖,圖片根本不會(huì)打包輸出到dist目錄(webpack是按需打包的):

由上圖可知拭嫁,dist目錄下無(wú)圖片文件或文件夾可免。

如何解決?

我整理并測(cè)試了以下三種解決辦法:

1做粤、絕對(duì)路徑訪問(wèn)

把圖片放到靜態(tài)資源目錄static目錄下(build 會(huì)將static目錄中的文件或者文件夾按照原本的結(jié)構(gòu)放在dist目錄下)浇借,并用/static絕對(duì)路徑訪問(wèn):

<template>
    <div>
        <img :src="src" alt="圖片" />
    </div>
</template>
<script>
    export default{
        data(){
          return {
              src:`/static/img/user.png`
          }
        }
    }
</script>

結(jié)果:
2、使用require

如果想在不調(diào)整目錄結(jié)構(gòu)的情況下讀取圖片怕品,還可以使用require:

data(){
     return {
         src:require('../assets/user.png')    //重點(diǎn)看這里
    }
}

該結(jié)果與上面說(shuō)的webpack打包的第一種方式結(jié)果相同妇垢。

缺點(diǎn):由于CommonJS只允許使用字符串字面量,所以不利于組件化肉康,靈活性較差闯估。

3、使用import

也可以用import引入圖片路徑:

<template>
    <div>
        <img :src="src" alt="圖片" />
    </div>
</template>
<script>
    import userPath from '../assets/user.png'
    export default{
        data(){
          return {
              src:userPath 
          }
        }
    }
</script>

結(jié)果:

該結(jié)果與上面說(shuō)的webpack打包的第一種方式結(jié)果相同迎罗。

這篇博客就先整理到這里睬愤。多花些時(shí)間踩踩坑也是很好的,學(xué)到了就是賺到了纹安。由于個(gè)人水平有限尤辱,博客錯(cuò)誤之處,煩請(qǐng)指正厢岂!

附完整代碼

./components/ItemShow-imageChoose.vue:

<template>
    <div>
        <input type="file" :id="id" @change="chooseFile($event)" accept="image/*" style="display: none" >
        <label :for="id">
            <img :src="'/static/img/'+imageSrc" alt="圖片" />
        </label>
    </div>
</template>
<script>
   export default{
        name:'ItemShow_imageChoose',
        props:{
            "id":[String],
            "imageSrc":[String]
        },
        methods:{
            chooseFile(e){
                var currentImg=e.target.nextElementSibling.childNodes[0]
                currentImg.setAttribute('src',window.URL.createObjectURL(e.target.files[0]))
                currentImg.onload=function () {
                    window.URL.revokeObjectURL(this.src)
                }
            }
        }
    }

</script>

參考:
1光督、Vue中img的src屬性綁定與static文件夾
2、問(wèn):vue+webpack動(dòng)態(tài)設(shè)置圖片src導(dǎo)致404錯(cuò)誤

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末塔粒,一起剝皮案震驚了整個(gè)濱河市结借,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌卒茬,老刑警劉巖船老,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異圃酵,居然都是意外死亡柳畔,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門郭赐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)薪韩,“玉大人,你說(shuō)我怎么就攤上這事捌锭》荩” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵观谦,是天一觀的道長(zhǎng)拉盾。 經(jīng)常有香客問(wèn)我,道長(zhǎng)坎匿,這世上最難降的妖魔是什么盾剩? 我笑而不...
    開封第一講書人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任雷激,我火速辦了婚禮,結(jié)果婚禮上告私,老公的妹妹穿的比我還像新娘屎暇。我一直安慰自己,他們只是感情好驻粟,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開白布根悼。 她就那樣靜靜地躺著,像睡著了一般蜀撑。 火紅的嫁衣襯著肌膚如雪挤巡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,144評(píng)論 1 285
  • 那天酷麦,我揣著相機(jī)與錄音矿卑,去河邊找鬼。 笑死沃饶,一個(gè)胖子當(dāng)著我的面吹牛母廷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播糊肤,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼琴昆,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了馆揉?” 一聲冷哼從身側(cè)響起业舍,我...
    開封第一講書人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎升酣,沒想到半個(gè)月后舷暮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡噩茄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年脚牍,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巢墅。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖券膀,靈堂內(nèi)的尸體忽然破棺而出君纫,到底是詐尸還是另有隱情,我是刑警寧澤芹彬,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布蓄髓,位于F島的核電站,受9級(jí)特大地震影響舒帮,放射性物質(zhì)發(fā)生泄漏会喝。R本人自食惡果不足惜陡叠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望肢执。 院中可真熱鬧枉阵,春花似錦、人聲如沸预茄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)耻陕。三九已至拙徽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間诗宣,已是汗流浹背膘怕。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留召庞,地道東北人岛心。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像裁眯,于是被迫代替她去往敵國(guó)和親鹉梨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容