Leveraging Vue js components while utilizing it from a content delivery network (CDN

I'm attempting to utilize the ButtonCounter component as a demonstration (source: https://vuejs.org/guide/essentials/component-basics.html#defining-a-component), but I am facing difficulties in getting it to function properly. I am utilizing Vue.js 3 from a CDN.

Here is the content of my ButtonCounter.js file:

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

Next, I have the main JavaScript file with Vue:

import ButtonCounter from './ButtonCounter.js'


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

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

app.mount('#app')

Lastly, within the HTML document where I link Vue.js from the CDN, and specify the following inside the body:

<ButtonCounter />

Despite following these steps, I am unable to see the button. Could someone please advise me on what I might be doing wrong?

Answer №1

After struggling for a bit, I finally cracked the code with the help of the vue-loader project. If you're interested, check out https://github.com/FranckFreiburger/vue3-sfc-loader. It's an amazing resource!

index.html:

  <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="9ee8ebfbadb3edf8fdb3f2f1fffafbecdeaeb0a6b0aa">[email protected]</a>/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>

Answer №2

When you mount your Vue application, anything inside the <div id=app></div> in the index.html gets overwritten.

To ensure it works properly, place your code inside the template of your main.js file:

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

app.mount('#app')

Remember, if you forget to add type=module on the script tag for your main.js, it will cause issues when you try to import.

Answer №3

For those working with Vue 3, here's a helpful tip - you can utilize SFC with the assistance of a handy tool provided in this particular package

When setting up Vue in your script, consider using it in the following manner:

app.js

 // Setting up vue-sfc-loader
const options = {
    moduleCache: {
        vue: Vue,
    },
    async getFile(url) {
        const res = await fetch(url);
        if (!res.ok)
            throw Object.assign(new Error(res.statusText + " " + url), { res });
        return {
            getContentData: (asBinary) =>
                asBinary ? res.arrayBuffer() : res.text(),
        };
    },
    addStyle(textContent) {
        const style = Object.assign(document.createElement("style"), {
            textContent,
        });
        const ref = document.head.getElementsByTagName("style")[0] || null;
        document.head.insertBefore(style, ref);
    },
};

const { loadModule } = window["vue3-sfc-loader"];
// END Setup vue-sfc-loader

const base_component_url = '/static/assets/dashboard/js/vue/';

function load(path) {
    return Vue.defineAsyncComponent(() => loadModule(base_component_url + path, options))
}

const app = Vue.createApp({ 
    delimiters: ['[[', ']]'], 
    components: {
        'Greeting': load('components/test/Greeting.vue')
    }
});

app.mount('#__VUE');

To include the component in your HTML, do so like this:

<Greeting></Greeting>

or

<Greeting />

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unable to convert JavaScript object to C# through deserialization

In order to pass a model from the controller action to the view, I included a list of objects and converted it into a JavaScript object to facilitate displaying markers on Google Maps. My goal is to send the selected object (selected marker) back to the co ...

Restricting Checkbox Choices with JavaScript by Leveraging the forEach Function

I am developing a checklist application that limits the user to selecting a maximum of three checkboxes. I have implemented a function to prevent users from checking more than three boxes, but it is not working as expected. The function detects when an ite ...

Utilizing a backup system to store environment variables within a configuration file

Currently, I am utilizing my environment variables by directly referencing process.env.NODE_ENV throughout my application. While this method works, it is becoming challenging to manage and keep track of. Therefore, I would like to consolidate all these var ...

What methods can I use to stop the styles of a child component from impacting those of the parent component

Is there a way to create CSS rules that achieve the following conditions? The parent component's CSS does not impact the child component The child component's CSS does not affect the parent component The child component is sourced from an exte ...

Navigating through Next.js for slug URLs such as site.com/username

Can someone help me figure out how to create a profile page for each username, like site.com/jack or site.com/jill? I'll be pulling the username info from an API that also contains the user ID and email. I'm new to Next.js and would really appre ...

Exploring ElectronJs: The journey to sending messages from ipcMain to IpcRender and awaiting a response

I need help with sending a message to ask the renderer to parse an HTML string mainWindow.webContents.send('parse html', { resp}) The renderer processes the data and sends a reply ipc.on('parse html',function(e,p){ let b ...

The functionality to open the menu by clicking is experiencing issues

I'm attempting to replicate the Apple website layout. HTML structure: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" conte ...

In my current project, I am working with Knockout and TypeScript but I am encountering difficulties in firing the window-resize event

Instead of using jquery, I prefer working with a custom handler for the $(window).resize(function () { ... event. If there is a way to achieve this without relying on jquery, please feel free to share it in the comments below. The code snippet below show ...

How can one determine if a new document was created by Mongoose's upsert feature?

My code in node.js/express.js looks like this: var User = mongoose.model('User'); var usersRouter = express.Router(); usersRouter.put('/:id', function(req, res) { req.body._id = req.params.id; var usr = new User(req.body); ...

Enzyme's simulate() failing to produce expected results with onChange event

I am facing an issue with a component and its related tests: import React from 'react'; import PropTypes from 'prop-types'; function SubList (props) { var subways = ['', '1', '2', '3', & ...

Response Headers in Google Cloud Functions

When executing a GCF triggered by an Http Request, I encounter the issue of receiving unnecessary headers along with my custom message. Here is a list of headers that are included: HTTP/1.1 200 OK Server: nginx Content-Type: application/json; charset=utf- ...

Learn the process of extracting an array of objects by utilizing an interface

Working with an array of objects containing a large amount of data can be challenging. Here's an example dataset with multiple key-value pairs: [{ "id": 1, "name":"name1", age: 11, "skl": {"name": & ...

Creating a design utilizing HTML columns with a set height and the ability to scroll horizontally

For my android project, I have a requirement to display a view (WebView) that dynamically loads content. The content will consist of <div class="content-item"> tags that are added by JavaScript to <div class="content-holder"> after the page has ...

Angular is failing to retrieve data from FS.readFile using promises

My goal is to utilize an Angular service to decide whether to call fs.readFile or fs.writeFile based on the button pressed, in order to explore the interaction between node and angular promises. Although I have managed to read and write files, I am facing ...

Creating a form that can identify both letters and numbers using JavaScript

Is it possible to create an <input> field that can recognize both letters and numbers while disregarding spaces and capitalization? Here is my current progress, aiming for the feedback to display as "right" when 9 H 6 U 8 f is entered in the field, ...

Having trouble integrating a custom image upload adapter plugin into ckeditor 5 using vue js?

I have been working on developing a custom image upload plugin for ckrditor5 using Vue js, Inertia, Vite Js, and Laravel. Despite following the documentation closely and implementing the code as per the guidelines, I encountered an error in the console. ap ...

Ajax requests function properly only on one occasion

My select option works perfectly the first time, but then the request does not execute again. I suspect that the issue lies with the 'onchange' event. Here is my Ajax code : jQuery(document).ready(function($) { $('#referenceProduit') ...

Attempting to loop through a JSON data structure in a React component

Trying to add a toggle checkbox for each JSON value present. Here is an example of the json object pertaining to element { "sourceIP": { "Primary": ["237.100.100.3", "238.0.4.8"], "Secondary": ["237.0.1.178", "237.1.1.91"] }, " ...

Maintain HTML formatting when page is refreshed

I am new to HTML and JavaScript, and I'm trying to modify the JavaScript code below so that when I reload the page, it retains the most recent active tab instead of defaulting back to the first tab. Currently, if I click on the second tab for "Paris" ...

Create an unordered Vue component object

In the data retrieved from the backend, there is an object containing various properties, one of which is the 'average' value. This object is ordered based on that value and when accessed through Postman, it appears as follows: ranking: ...