skip to Main Content

I’m trying to use the ButtonCounter component as an example (https://vuejs.org/guide/essentials/component-basics.html#defining-a-component), but I just can’t make it work. I use vue js 3 from a CDN.

I have the ButtonCounter.js file:

export default {
  data() {
    return {
      count: 0
    }
  },
  template: `
    <button @click="count++">
      You clicked me {{ count }} times.
    </button>`
}

Then I have the main js file with vue:

import ButtonCounter from './ButtonCounter.js'


const app = Vue.createApp({
  components: {
    ButtonCounter
  },

  data() {
    return {
      aaa: []
    }
  },
  methods: {
    ...
  }
}
})

app.mount('#app')

And finally I have the html where I link vue js from a cdn, and I specify the following inside the body:

<ButtonCounter />

But I can’t see the button. What am I doing wrong?

2

Answers


  1. Chosen as BEST ANSWER

    Eventually I managed to solve it by using the vue-loader project, see https://github.com/FranckFreiburger/vue3-sfc-loader. It's a great tool!

    index.html:

      <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
      <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue3-sfc-loader.js"></script>
    
    <div id="app">
      ....
      <ButtonCounter />
    </div>
    
    <script src="/main.js"></script>
    

    main.js:

    const { loadModule } = window['vue3-sfc-loader'];
    
    const VueLoaderOpts = {
      moduleCache: { vue: Vue },
      async getFile(url) {
        const res = await fetch(url)
        if(!res.ok)
           throw Object.assign(new Error(url+' '+res.statusText), { res });
        return await res.text();
      },
      addStyle: () => {},
    }
    
    const app = Vue.createApp({
      components: {
        'ButtonCounter': Vue.defineAsyncComponent(() => loadModule('./ButtonCounter.vue', VueLoaderOpts))
      },
    
      data() {
        ...
      }
    }
    

    ButtonCounter.vue:

    <script>
    export default {
      data() {
        return {
          count: 0
        }
      }
    }
    </script>
    
    <template>
      <button @click="count++">
        You clicked me {{ count }} times yet.
      </button>
    </template>
    

  2. What you put inside the <div id=app></div> in the index.html is over-written when you have mounted your vue application.

    It should work if you put it in the template of your main.js file:

    import ButtonCounter from './ButtonCounter.js'
    const app = Vue.createApp({
        components: {
            ButtonCounter
        },
        template: `<ButtonCounter />`
    })
    
    app.mount('#app')
    

    Note that if you have not said type=module on the script tag for your main.js then it will blow up when you try to import

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search