Having trouble adding global method using Plugin in Vue 3?

I have been working on creating a method that can generate local image URLs to be used in any template automatically.

However, I encountered an issue while trying to develop a plugin that adds a global property.

Plugin Implementation:

// src/plugins/urlbuilder.js
export default {
    install: (app) => {
        app.config.globalProperties.buildImageUrl = imageName => require('@/assets/images/' + imageName);
    }
}

Main.js Configuration:

// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import urlbuilder from './plugins/urlbuilder.js'

createApp(App).use(router).use(urlbuilder).mount('#app')

Home View – Image Rendering:

// src/views/Home.vue
<template>
    <img :src="buildImageUrl('myimage.jpg')">
</template>

Unfortunately, when attempting to render the image, I encountered the following error in the console:

Uncaught (in promise) TypeError: _ctx.buildImageUrl is not a function
    at Proxy.render (cjs.js?!./node_modules/babel-loader/lib/index.js!./node_modules/vue-loader-v16/dist/templateLoader.js?!./node_modules/cache-loader/dist/cjs.js?!./node_modules/vue-loader-v16/dist/index.js?!./src/views/Home.vue?vue&type=template&id=fae5bece&scoped=true:57)
    at renderComponentRoot (runtime-core.esm-bundler.js:922)
    ...

Note: While it works by directly adding a global property without using a plugin, I have read that the recommended approach is to use a plugin.

In conclusion, the manual setup below works successfully:

app = createApp(App)

app.config.globalProperties.buildImageUrl = imageName => require('@/assets/images/' + imageName)

app.use(router).mount('#app')

What could potentially be going wrong with my current implementation?

Answer №1

If you want to access global properties, you can do so using the following method:

  const instance = getCurrentInstance()
  const globalProperties = instance.appContext.config.globalProperties
  console.log(globalProperties)

It is recommended to use provide and inject.

Alternatively, you can create a hook file:

useGlobalProps.ts

import { getCurrentInstance } from 'vue'
import type { ComponentInternalInstance } from 'vue'

function useGlobalProps() {
  const { appContext } = getCurrentInstance() as ComponentInternalInstance
  const globalProps = appContext.config.globalProperties
  return { ...globalProps }
}

export default useGlobalProps

Then, you can use this hook in your component:

import useGlobalProps  from '@/hooks/useGlobalProps'
const { testFn, globalFn } = useGlobalProps()
testFn()
globalFn('global function in main.js')

Don't forget to register globalFn in your main.js file:

app.config.globalProperties.globalFn = function testGlobal(name: string) {
  console.log(name)
}

You can also register testFn through a plugin:

myPlugin.js

export default function (app: App<HTMLElement>) {
  app.config.globalProperties.testFn = () => {
    console.log('install global properties')
  }
  return app
}

Lastly, make sure to use this plugin in your main.js file:

import myPlugin from './myPlugin.js'
// ...
app.use(myPlugin)

Answer №2

An improved method involves utilizing provide and inject in Vue.js

import urlbuilder from './plugins/urlbuilder.js'

app.provide('$urlbuilder', urlbuilder);

For further information, refer to provide and inject documentation

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

Utilizing an object for Device Orientation Controls instead of a camera within Three.js

As I embark on my journey with Three.js, I am taking my first steps into the world of device orientation controls. While exploring demos on the Three.js website, I noticed that most examples only involve manipulating the camera. I am eager to find an examp ...

Is it possible to run my NPM CLI package on CMD without needing to install it globally beforehand?

I've created a new NPM package, complete with its own set of CLI commands. Let's call this package xyz, and let's imagine it's now live on npmjs.com Now, picture a user who installs this package in their project by executing npm insta ...

Retrieving the chosen date from a calendar using a jQuery function

Hey there, I need help with showing tasks created on a specific date by selecting that date from a full month calendar. There are multiple tasks created on the selected date, and I want to trigger a jQuery event to fetch data for that date. However, my i ...

Issues with clicking in JS eventListener

I'm in need of some assistance with a small header issue in my project. I've included all the necessary header files so that you can run it in a snippet and see what's going on. The problem lies within my JS file. When running the file, you ...

What is the best way to toggle a d3 svg overlay using a leaflet layer control?

I am looking for a solution to place 3 d3 svgs on a leaflet map and control them as easily as leaflet layers. Check out this code example, which works but is not ideal. The key part is from line 75 onwards, where I create a custom layer control linked to ...

Setting the "status" of a queue: A step-by-step guide

I created a function to add a job to the queue with the following code: async addJob(someParameters: SomeParameters): Promise<void> { await this.saveToDb(someParameters); try { await this.jobQueue.add('job', ...

Struggling to track user handler events of success or failure in Amazon Cognito

Seeking guidance as a newcomer to VueJS and Amazon-cognito, I am attempting to sign in through my straightforward VueJS application. Utilizing NPM and webpack, I have diligently followed the instructions detailed in amazon-cognito-auth-js Displayed below ...

What is the process for removing a document attribute in Sanity iO?

I have a collection of objects within my Sanity Document named Images which includes Comments An example comment object in the comments array looks like: { "_key": "6510dc79cf8b", "comment": "Hello world" ...

Astro Project experiencing issues with loading SRC folder and style tags

After setting up a brand new astro repository with the following commands: npm create astro@latest npm run dev I encountered an issue where the default project template failed to display correctly on my computer. Here is how the page appeared: https://i. ...

Error occurring when attempting to pass messages within an iframe on a sandboxed page in a Chrome extension

Whenever I try to utilize my popup page for a chromium extension as a conduit for communication between the background page and a page shown within an iframe on the popup, I encounter the following error. I required a sandboxed environment to execute Vue.j ...

Retrieve the updated text content from a textarea using JavaScript/jQuery

For a beginner in javascript and jquery like me, I encountered an issue with a textarea element that has preset content. When I change the value on the site to "new" and click the "showme" button, the alert box displays the preset value instead of the new ...

What would be more efficient for designing a webpage - static HTML or static DOM Javascript?

My burning question of the day is: which loads faster, a web page designed from static html like this: <html> <head> <title>Web page</title> </head> <body> <p>Hi community</p> </bo ...

HTML anchor tag failing to redirect to specified link

I need to populate the URI property from an API result into an HTML format. I attempted to achieve this by calling a function and running a loop 3 times in order to display 3 links with the URI property of each object. However, the code is not functioning ...

Ensure that immutability is strictly enforced, or allow for partial immutability without the risk of silently failing

Is there a method to implement partial immutability on an object in a way that triggers an error if any attempt at mutation is made? For instance, consider let obj = {a: 1, b: 2}. I am interested in making obj.a and obj.b immutable while still allowing ad ...

Nuxt.js encountered an unexpected keyword 'export' causing a parsing error

Within my index.js file in the 'store' section, I am encountering the following code: import Vuex from 'vuex' // import axios from 'axios' const createStore = () => { return new Vuex.Store({ state: { loadedPost ...

Using jQuery to retrieve the domain extension from a URL

Seeking assistance with extracting domain extensions from various URLs using jQuery. Uncertain how to account for all possible scenarios. Here are the parts of the URL that need to be extracted: https://www.amazon.**com**/dp/067144901X https://www.amazon. ...

When using React, it's important to verify if the page has been refreshed before updating the local storage based on the GraphQL query. If the page

Currently, I am working on implementing a hit counter feature that increments each time a user clicks a button. The setup involves GatsbyJS with React and utilizes a lambda function to store the count in FaunaDB. Additionally, the client-side functionality ...

Can I utilize p5.Vector.fromAngle() in Vue JS?

Incorporating P5 into a Vue application can be achieved using the following code snippet: let script = p5 => { p5.setup = _ => { this.setup(p5) } p5.draw = _ => { this.draw(p5) } } this.ps = new P5(script) While functions like ba ...

"The variables in the .env file are not reflecting the latest updates. What is the best way

Currently, I am in the process of developing an application using Quasar (Vue) where I have stored my database keys in a .env file. Recently, I encountered an issue when attempting to switch to another instance and updating the keys in the env file. Despit ...

Sending cookies via POST/GET request with Credentials is not functioning

Greetings, despite the numerous duplicates of this inquiry, my attempt to solve it has been unsuccessful. Therefore, I am initiating a fresh discussion. Aside from utilizing axios, I also experimented with fetch but encountered similar outcomes. On the b ...