emit eventHub inside vuex - vue.js

im wondering how can i use this.$eventHub.$emit('something');
But inside of vuex
the reason why i need this is because im using a plugin (vuex-persist-indexeddb), and there is a method called rehydrated (which fires when the db is loaded) so i want to emit an event on eventHub for warn the db is loaded...
i made the eventHub like this in the main.js file:
Vue.prototype.$eventHub = new Vue(); // Global event bus
In my store/index.js file ive loaded Vue but it doesnt recognize the $eventHub called from Vue.$eventHub...
imported with:
import Vue from "vue";
Hope anyone can help me, thanks in advice

i've already solved it :)
the solution was create a new folder/file like this:
folder: eventHub/index.js
file contents:
import Vue from "vue";
const eventBus = new Vue()
export default eventBus
and then in the router file simple import and use
import eventHub from '#/eventHub'
eventHub.$emit('something');
pulled from the official docs:
vue docs events

Related

Transition from gobal Vue instance to app breaks import dependency

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', {
...
}

Whats wrong with my eventBus implementation?

I want to trigger a function from another component which is not parents and child relationship. i try to use eventbus, but i am not sure am i implemented it correctly, since the function is not working. i have created a boot file eventBus.js and added it into the quasar config, but its still not working. Anyone can help me to check which part did i implemented wrongly?
eventBus.js
import Vue from 'vue'
const eventBus = new Vue();
export default eventBus
Vue.prototype.$eventBus = eventBus;
below is the function that i want to get from this page, (this.getSchedule(), it is working perfectly on current page).
mounted(){
this.$eventBus.$on("refreshListSchedule", ()=>{
scheduleDate = this.scheduleDate
console.log(scheduleDate)
console.log("Testing successed")
this.getSchedule()
})
},
The page that i want to trigger it
this.$eventBus.$emit('refreshListSchedule')
It is better if you manually import from eventBus.js in each component where you want to emit or subscribe for events - don't rely on Vue.prototype.
And don't forget to unsubscribe in the beforeDestroy hook.

How to access document/window from shadow dom in vue?

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?

Vue is not defined in components

I have file: components.js:
import Vue from 'vue'
import SelectCategory from './components/SelectCategoryComponent'
import CommentsManager from './components/CommentsManagerComponent'
Vue.component('select-category', SelectCategory);
Vue.component('comments-manager', CommentsManager);
In app.js I imported this file:
window.Vue = require('vue');
import './components'
But when page is loading I get error: Vue is not defined. When I add import Vue from 'vue' in every component then all working good. But how I can add Vue globally, without add import Vue from 'vue' in every component?
But how I can add Vue globally, without add import Vue from 'vue' in every component
You should not use global variables. Put import Vue from 'vue' in every file.
Now, if you still want to, use global instead of window. And make sure that file is loaded first. Or, you might want to set window= in your html file, and leave it out of every file.
As I can see within your components.js you have imported Vue and you have imported another Vue and you have put it to window object. so you have imported 2 different Vue within your application, as well there is no need to use components.js and app.js that can be confused later. so I suggest you put all your requirement within app.js file.
so app.js file will be like this :
import Vue from 'vue'; // es6 syntax
window.Vue = Vue;
import SelectCategory from './components/SelectCategoryComponent'
import CommentsManager from './components/CommentsManagerComponent'
Vue.component('select-category', SelectCategory);
Vue.component('comments-manager', CommentsManager);

Nuxt: Vue Instance for Global Events

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'