1

I've been using Vue.js single file components to build a website and really enjoying the modular system. I'm running into an issue however where the browser seems to be requesting multiple versions of resources instead of just one URL for each.

HeaderBar.vue

<template>
    <div id="header" :class="{sticky: isSticking }">
        <img id="header-logo" src="../assets/logo/logo_horiz.svg">
        <div id="header-menubox">
            <a class="social-link" href="[scrubbed]" target="_blank">
                <img src="../assets/social/facebook_blue.svg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img src="../assets/social/twitter_blue.svg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img src="../assets/social/insta_blue.svg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img src="../assets/social/yelp_blue.svg">
            </a>
            <button id="header-menu-button" @click="toggleMenu">
                <img src="../assets/button/menu.svg">
            </button>
        </div>
    </div>
</template>

<script>
    export default {
        name: 'HeaderBar'
    }
</script>

<style scoped>
#header {
    position: sticky;
    width: 100%;
    padding: 1em;
    background-color: rgba(255, 255, 255, 0.9);
    z-index: 100;
    display: grid;
    grid-template-areas: "logo . menu";
    grid-template-columns: 1fr 4fr 1fr;
    grid-template-rows: 1fr 1fr;
}

#header.sticky {
    background-color: #fff;
    box-shadow: 0 1em 2.5em rgba(0, 0, 0, 0.2);
}

#header-logo {
    grid-area: logo;
}

#header-menubox {
    grid-area: menu;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    justify-items: center;
}

#header-menu-button {
    background-color: unset;
    display: block;
    cursor: pointer;
    border: 0;
    grid-column: 3 / 4;
    grid-row: 2;
}
</style>

App.vue

<template>
  <div id="app">
    <HeaderBar></HeaderBar>
  </div>
</template>

<script>
import HeaderBar from './components/HeaderBar.vue'

export default {
  name: 'app',
  components: {
    HeaderBar
  }
}
</script>

<style>
#app {
  width: 100%;
}
</style>

vue.config.js

module.exports = {
  publicPath: '/'
}

Chrome Developer Console Chrome Console Error Output

What's causing this behavior?

[EDIT] I modified the HeaderBar.vue to import the images:

<template>
    <div id="header" :class="{sticky: isSticking }">
        <img id="header-logo" :src="logoImg">
        <div id="header-menubox">
            <a class="social-link" href="[scrubbed]" target="_blank">
                <img :src="fbImg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img :src="twitImg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img :src="instaImg">
            </a>
            <a class="img-link" href="[scrubbed]" target="_blank">
                <img :src="yelpImg">
            </a>
            <button id="header-menu-button" @click="toggleMenu">
                <img :src="menuImg">
            </button>
        </div>
    </div>
</template>

<script>
    import logoImg from "../assets/logo/logo_horiz.svg"
    import fbImg from "../assets/social/facebook_blue.svg"
    import twitImg from "../assets/social/twitter_blue.svg"
    import instaImg from "../assets/social/insta_blue.svg"
    import yelpImg from "../assets/social/yelp_blue.svg"
    import menuImg from "../assets/button/menu.svg"

    export default {
        name: 'HeaderBar',
        data: function() {
            return {
                logoImg: logoImg,
                fbImg: fbImg,
                twitImg: twitImg,
                instaImg: instaImg,
                yelpImg: yelpImg,
                menuImg: menuImg
            }
        }
    }
</script>

<style scoped>
#header {
    position: sticky;
    width: 100%;
    padding: 1em;
    background-color: rgba(255, 255, 255, 0.9);
    z-index: 100;
    display: grid;
    grid-template-areas: "logo . menu";
    grid-template-columns: 1fr 4fr 1fr;
    grid-template-rows: 1fr 1fr;
}

#header.sticky {
    background-color: #fff;
    box-shadow: 0 1em 2.5em rgba(0, 0, 0, 0.2);
}

#header-logo {
    grid-area: logo;
}

#header-menubox {
    grid-area: menu;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    justify-items: center;
}

#header-menu-button {
    background-color: unset;
    display: block;
    cursor: pointer;
    border: 0;
    grid-column: 3 / 4;
    grid-row: 2;
}
</style>

Now I have far fewer errors, but the URLs requested look even stranger: Chrome Console Error Output

735Tesla
  • 3,162
  • 4
  • 34
  • 57

2 Answers2

2

You should let webpack handle this.

Most probably the loader plugin you are using doesn't handle svgs.

Check config/webpack.config.js or build/webpack.base.conf.js and find the rule for images (it should have matches for png, jpeg, gif).

Add svg to that regular expression. You'll end up with something similar to this

test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
Radu Diță
  • 13,476
  • 2
  • 30
  • 34
1

You have to import them in the javascript portion of the component, then assign them to the element.

Or at least, that's how I got it to work.

<template>
    <div id = "imgcontainer"> 
      <img v-bind:src="image"/> 
    </div>
</template>

<script> 
  import img1 from "../assets/1.jpg" 
  export default { 
    data(){
      return{
        image: '', 
      };
    },
    beforeCreate(){
     this.image = img1
    },
  } 
</script>

that should solve your problem, in fact, it should solve all of your life problems

LJD
  • 498
  • 4
  • 11
  • Oh, I see, it looks like the way images are included in components is different than the main app instance. Related: https://stackoverflow.com/questions/45116796/how-to-import-and-use-image-in-a-vue-single-file-component I'll try it out – 735Tesla Mar 19 '19 at 17:38
  • Alright, I'm a lot closer (fewer errors) but it seems to be requesting `/[object Module]` which to me seems even stranger (see post edit). Any ideas? – 735Tesla Mar 19 '19 at 17:57
  • Try v-bind:src :D – LJD Mar 19 '19 at 18:06
  • `:attr` is shorthand for `v-bind:attr` https://vuejs.org/v2/guide/syntax.html#Shorthands is there a reason you think shorthands shouldn't be used here? – 735Tesla Mar 19 '19 at 18:07
  • I tested, `v-bind:src` produces the same result – 735Tesla Mar 19 '19 at 18:13
  • It may be your version of webpack, but I'm not sure. Google this: "[object%20Object] webpack" I'll see if I can help out later when I have free time, unless you say you've found a solution. – LJD Mar 19 '19 at 18:34
  • 1
    Thanks. I can't nail down a specific issue but there seem to be quite a few that occur when using relative paths with webpack. I tried using `@/assets/` instead of `../assets/` and that didn't work either – 735Tesla Mar 19 '19 at 18:45
  • You ever figure it out dude? – LJD Mar 20 '19 at 00:50
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/190332/discussion-between-735tesla-and-jude-desir). – 735Tesla Mar 20 '19 at 00:51