vue 3 before create event in main.js - vue.js

I'm trying to use beforeCreate in main.js. What is the equivalence of this code in Vue 3?
new Vue({
el: '#app',
router,
components: { App },
store: store,
beforeCreate() { this.$store.commit('initialiseStore');},
template: '<App/>'
})

beforeCreate() still exists in Vue 3's Options API.
For that code snippet, the only differences in Vue 3 would be:
The creation of the app instance is now done via Vue.createApp().
Note: In the following example, we're using extends: App here so that we could add the beforeCreate() hook. Otherwise, we could simply do createApp(App) instead.
The Vue plugins are installed off of the app instance's use() method.
The mounting is done via the app instance's mount() method.
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
1️⃣
createApp({
extends: App,
beforeCreate() { this.$store.commit('initialiseStore') }
})
2️⃣
.use(router)
.use(store)
3️⃣
.mount('#app')
demo
Side note: Since you're migrating to Vue 3, Pinia is now the officially recommended state management library that replaces Vuex (now deprecated). See Pinia's migration guide.

Related

vue.reactive is not a function in vuejs2

when I create this error appear I'm not sure hot fix it.
I ready build a web app and then I just create a store.
enter image description here
/store/index.js
import Vuex from "vuex";
import Vue from "vue";
Vue.use(Vuex);
export default new Vuex.Store({
state: {
title: "My custom title"
},
mutations: {},
modules: {},
actions: {}
});
main.js
import Vue from "vue";
import App from "./App.vue";
import store from "./store";
import router from "./router/routes";
import Navbar from "./components/Navbar";
Vue.component("Navbar", Navbar);
Vue.config.productionTip = false;
new Vue({
router,
store,
render: (h) => h(App)
}).$mount("#app");
Check if your packages versions are compatible with each other. Don't want to be guessing but looks like you have too new Vuex for Vue 2.
Try installing Vuex in version 3.

Vue 3 - how to include components and mixins with the root component?

I try to convert the syntax from Vue 2 to Vue 3, but I'm not sure how to include the mixins and components, if you see this code from Vue 2:
import App from "./App.vue";
const app = new Vue({
mixins: [globalMixin],
router,
el: '#app',
store,
components: {
Thing,
Hello
},
render: h => h(App)
});
Here is the Vue 3 syntax, if I've understood it right:
const app = createApp(App)
app
.use(store)
.use(router)
app.mount('#app')
The vue 2 example has a mixin and two components, but how do I add that to the Vue 3 syntax?
You can add a component by doing : app.component('Thing', Thing) but that's only one component...should I add them one by one in that way? What about the mixins?
In Vue 3, it's possible to do local component registration and mixins in the root component (useful when trying to avoid polluting the global namespace). Use the extends option to extend the component definition of App.vue, and then add your own mixins and components options:
import { createApp } from 'vue'
import App from './App.vue'
import Hello from './components/Hello.vue'
import Thing from './components/Thing.vue'
import globalMixin from './globalMixin'
createApp({
extends: App,
mixins: [globalMixin],
components: {
Hello,
Thing,
}
}).mount('#app')
Registering the component one at a time seems like the way to go, especially if there are only a few components.
demo
In Vue 3, you can use the application API mixin method.
import { createApp } from 'vue'
import App from './App.vue'
import globalMixin from './globalMixin'
const app = createApp(App)
app.mixin(globalMixin)
app.mount('#app')
For components, you can add them one by one. I prefer it this way because it is cleaner.

Created Lifecycle Hook of global vue instance

I want to be able to use the AOS library globally on my vue project.
This is for Vue 2.
new Vue({
created () {
AOS.init()
},
render: h => h(App),
}).$mount('#app');
The Vue 3 sets up the app a little bit different.
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
I dont have that created option with the Vue 3 setup. I tried this, but it´s more of a guessing game...
createApp({App, AOS.init()})
But do I make this work in Vue 3?
You can still do that in Vue 3. Note h() is now imported as a global function from vue instead of being an argument of render().
Here's the equivalent Vue 3 code:
import { createApp, h } from 'vue'
import App from './App.vue'
createApp({
created() {
AOS.init()
},
render: () => h(App),
}).mount('#app')
You could use the created hook of the root component. To me that has always seemed like an appropriate place to initialize application-wide libraries.

Vue component opened in Ionic Vue Modal doesn't have $route and $router

I'm creating app by using Vue Ionic and trying to change page by modal controller provided by ionic like the following code.
const modal = await this.$ionic.modalController.create({
component: NewPageComponent
})
modal.present()
Then NewPageComponent is opened without problem in <ion-modal></ion-modal>.
But when I try to confirm $route and $router in NewPageComponent, NewPageComponent doesn't have these.
NewPageComponent
export default {
created () {
console.log(this.$route) // undefined
console.log(this.$router) // undefined
}
}
Vue Components opened in <ion-modal></ion-modal> don't seem to have $route and $router.
But others have these without problem.
For example I can see $route and $router in App.vue.
App.vue
<template>
<ion-app>
<v-app>
<span>App</span>
</v-app>
<ion-app>
</template>
<script>
export default {
created () {
console.log(this.$route) // this.$route exists
console.log(this.$router) // this.$router exists
}
}
</script>
Of course I have registered router in main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import Ionic from '#ionic/vue'
import './registerServiceWorker'
import './plugins/ionic.js'
Vue.use(Ionic)
Vue.config.productionTip = false
new Vue({
router, // I have set router like this
render: h => h(App)
}).$mount('#app')
Is there any way to make Vue Components opened in <ion-modal></ion-modal> like NewPageComponent have $route and $router?
Internally Ionic uses another Vue instance. When you creating new modal it is placed in this instance without router that is registered in main app. I recommend you to use event bus pattern to communicate between components. It's pretty simple:
EventBus.js
import Vue from 'vue'
export const EventBus = new Vue()
Then in main app you can listen to custom events:
App.vue
import {EventBus} from './EventBus.js'
//...
created() {
EventBus.$on('change-route', this.handleRouteChange)
EventBus.$on('change-params', this.handleParamsChange)
},
beforeDestroy() {
EventBus.$off('change-route', this.handleRouteChange)
EventBus.$off('change-params', this.handleParamsChange)
},
methods: {
handleRouteChange(page) {
// here you can normally access this.$router
this.$router.push(page)
},
handleParamsChange(params) {
this.$router.push({params:params})
}
},
NewPageComponent.vue
import {EventBus} from './EventBus.js'
//...
methods: {
changePage() {
EventBus.$emit('change-page', '/new-page')
// If you want to change page named route with params:
// EventBus.$emit('change-page', {name:'product', params: {id: 10}})
},
updateParams() {
EventBus.$emit('change-params', {id: 1010})
}
}

How do I do to make multi-pages switch smoothly in Vue.js with a navigation bar? How to router in MPA project?

I'm learning Vue.js 2.6.Here is my basic directory:
I need my home and blogs shares the same header and footer, so I imported my header and footer components separately in my home.vue and blogs.vue, but It didn't switch page smoothly when I click the link in the navigation bar. What can I do to make it smooth?
To make this project I turned to some case on the internet, after that I was confused when I saw its Router file structure:
It seems that I'm coding it as a MPA, but why is that index.js in Routers dir needed?
my home.js as below:
import Vue from 'vue'
import Home from './home.vue'
import router from '../../router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.config.productionTip = false
Vue.use(ElementUI)
new Vue({
el: '#homeDiv',
router,
components: { Home },
template: '<Home/>',
render:h => h(Home)
});
my index.js in Router dir as below:
import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from 'HelloWorld'
Vue.use(Router)
export default new Router({
mode: 'history',
routes: [
{
path: '/',
name: 'App',
component: HelloWorld
}
]
})
and there's another main.js in the root of src dir, the author of that sample code did nothing to the initial App.vue and main.js. I just added some element-ui related code into index.js and main.js.
main.js:
import Vue from 'vue';
import App from './App';
import router from './router';
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
//import './plugins/element.js'
Vue.config.productionTip = false;
Vue.use(ElementUI);
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
new Vue({
el: '#app',
render:h => h(App)
})
I felt its Router looks like spaghetti, I can't see which code is needed, which is not. What is a GOOD Router structure in a vue.js MPA project?
THX
You have multiple questions being asked here.
What is the best router structure for vue-router?
I don't think there is a standard anywhere. A lot of codes I have seen adopted the style you have already. Which is fine depending on the scale of what you are building.
How to make a smooth transition between pages?
In my projects, I wrap the router-view component in the official vue transition component. As advised here in the official vue router documentation
Please let me know if these answers suffice.