I'd like to use a separate Vue instance to handle events. This approach works in a standard Vue app but throws an error in the Nuxt environment.
Do I need to simply reference it differently?
Code
const Vue = require('vue');
const Hub = new Vue();
export default Hub;
// Usage
import Hub from '~/events/hub';
Hub.$emit(EVENT_TOGGLE_NAVIGATION, true);
Error
Uncaught TypeError: Vue is not a constructor
Environment
nuxt 1.0.0
vue 2.5.17
You need to use import
import Vue from 'vue'
Related
I've been trying to get storybook working with a Vue 2 + composition API project for a while now and I keep running into the error:
Unexpected error while loading ./ProductCard.stories.js: [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function.
So I assume I need to include it before any file/story gets called.
When I try and import it into my storybook's main.js file like this:
import Vue from "vue";
import VueCompositionApi from "#vue/composition-api";
Vue.use(VueCompositionApi);
module.exports = {
//... storybook config
}
I get the console error:
import Vue from "vue";
^^^^^^
SyntaxError: Cannot use import statement outside a module
I've also tried:
const Vue = require("vue");
const VueCompositionApi = require('#vue/composition-api');
Vue.use(VueCompositionApi);
Which appears to work but I still get the top error [vue-composition-api] must call Vue.use(VueCompositionAPI) before using any function.
Does anybody know where I'm meant to import the composition API so it's loaded before it's called?
I've tried putting it in the preview.js file as well with the same error.
Whats causing it is the component ProductCard loads a composable called useUiStatewhich uses vue-composition-api.
I would have thought it's called vue.use already.
Is it possible to initialize Pinia store inside Vue 2 single file component? Right now I'm trying do this:
import { createPinia, PiniaVuePlugin } from 'pinia';
import Vue from 'vue';
Vue.use(PiniaVuePlugin);
const pinia = createPinia();
Vue.prototype.$pinia = pinia;
and it works in app but when I import this component to another App I'm having this error:
getActivePinia was called with no active Pinia. Did you forget to install pinia?
Is it even possible to initialize the pinia after main instance of app is created?
I am creating a frontend and a backend application inside one Vue 3 project. Everything works fine except that app.js is throwing following error, depending on which component is visited in the browser.
I you visit the app.vue:
[Vue warn]: Failed to mount app: mount target selector "#cms" returned null.
and if you visit the cms.vue:
[Vue warn]: Failed to mount app: mount target selector "#app" returned null.
The mounting file app.js looks like this:
require('./bootstrap');
import {createApp} from 'vue';
import app from "../vue/app";
import cms from "../vue/cms";
import router from "./router";
createApp(app)
.use(router)
.mount("#app");
createApp(cms)
.use(router)
.mount("#cms");
Is there any way I can prevent the browser warning?
You could query the document for those elements, and only mount the ones that exist:
const appEl = document.querySelector('#app');
if (appEl) {
createApp(app).use(router).mount(appEl);
}
const cmsEl = document.querySelector('#cms');
if (cmsEl) {
createApp(cms).use(router).mount(cmsEl);
}
I'm looking at migrating a Vue 2 app to Vue 3 and ran into a problem. The Vue 2 app used to start with importing a whole lot of components and directives:
// these components register to the global Vue instance
import {ComponentA} from './componenta';
import {directiveA} from './directivea';
// create app (after the components are registered)
new Vue({...})
This worked fine, but when changing this code to Vue3, the app instance is now created instead. This instance isn't actually available when the global directives and components are imported.
What's the recommended way for dealing with this? I can't reorder the imports to the bottom of the file as webpack bundles them always at the top...
The order of imports does not matter in your case - what matters is the order of the JavaScript statements that follow the import section.
You should first create the app instance and only then register your global components to this instance - as explained in https://learnvue.co/2020/08/how-to-register-a-vue3-global-component/
import { createApp } from 'vue'
import PopupWindow from './components/PopupWindow'
import App from "./App.vue"
const app = createApp(App)
app.component('PopupWindow', PopupWindow) // global registration - can be used anywhere
app.mount('#app')
I settled with a solution that imports the app instance before component registration/definition (which occur within the component file) in an attempt to keep the current structure.
import {app} from './instance';
import './components/popupwindow';
import App from './app.vue';
const app = createApp(App)
app.mount('#app')
// instance.js
import {createApp} from 'vue';
const app = createApp();
export {app};
// popupwindow.vue
import {app} from '../instance';
// component registration+definition here (for global components only)
app.component('popup', {
...
}
I am using a library (vue-airbnb-style-datepicker) which is trying to access the document object to attach some event listeners. Wrapping the vue app as a web component results into following error:
Cannot read property 'addEventListener' of null
My main.js:
import Vue from "vue";
import App from "./App.vue";
import wrap from "#vue/web-component-wrapper";
import AirbnbStyleDatepicker from "vue-airbnb-style-datepicker";
Vue.use(AirbnbStyleDatepicker, {});
Vue.config.productionTip = false;
const WrappedElement = wrap(Vue, App);
window.customElements.define("gpc-components", WrappedElement);
How can i use the document object in a web component?
Is it even possible?
If not, does a workaround exist?