3, vue-router@4.x and vuex@4.x
vue-router@4.x and vuex@4.x
vue2.x uses vue-router@3.x and vuex@3.x ,vue3.x uses vue-router@4.x and vuex@4.x , avoid following vue3 The version numbers of X are mixed. In fact, vue3 Both router and vuex used by X are 4 x.
Vue2.0 is used here for convenience of understanding x router,vue3.x router instead of vue-router@3.x And vue-router@4.x , unified use of vue2 x vuex,vue3.x vuex instead vuex@3.x and vuex@4.x .
1,vue-router@4.x
Create instance
// vue2.x router import Vue from 'vue' import Router from 'vue-router' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] Vue.use(Router) const router = new Router({ base: process.env.BASE_URL, mode: 'history', scrollBehavior: () => ({ y: 0 }), routes }) export default router // vue3.x router import { createRouter, createWebHistory } from 'vue-router' import Home from '../views/Home.vue' const routes = [ { path: '/', name: 'Home', component: Home }, { path: '/about', name: 'About', // route level code-splitting // this generates a separate chunk (about.[hash].js) for this route // which is lazy-loaded when the route is visited. component: () => import(/* webpackChunkName: "about" */ '../views/About.vue') } ] const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes }) export default router
scrollBehavior scrollbehavior
vue3. Vue2 is discarded by X router The {selector, x, y, offset} in X router is replaced by {el, left, top, behavior}. The new api semantics are closer to the original DOM
// vue2.x router const router = new Router({ base: process.env.BASE_URL, mode: 'history', scrollBehavior: () => ({ x: 0, y: 0 }), routes }) // vue3.x router const router = createRouter({ history: createWebHistory(process.env.BASE_URL), routes, scrollBehavior(to, from, savedPosition) { // scroll to id `#app` + 200px, and scroll smoothly (when supported by the browser) return { el: '#app', top: 0, left: 0, behavior: 'smooth' } } })
Routing component jump
vue2.x use the route option redirect to set automatic route adjustment, vue3 If this option is removed from X, an empty path origin matching jump will be added to the sub route
// vue2.x router [ { path: '/', component: Layout, name: 'WebHome', meta: { title: 'Platform home page' }, redirect: '/dashboard', // Write jump here children: [ { path: 'dashboard', name: 'Dashboard', meta: { title: 'workbench' }, component: () => import('../views/dashboard/index.vue') } ] } ]
// vue3.x router [ { path: '/', component: Layout, name: 'WebHome', meta: { title: 'Platform home page' }, children: [ { path: '', redirect: 'dashboard' }, // Write jump here { path: 'dashboard', name: 'Dashboard', meta: { title: 'workbench' }, component: () => import('../views/dashboard/index.vue') } ] } ]
Capture all routes: /: catchAll(. *)
When capturing all routes (/ *), you must now define them using parameters with custom regular expressions: /: catchAll(. *)
// vue2.x router const router = new VueRouter({ mode: 'history', routes: [ { path: '/user/:a*' }, ] }) // vue3.x router const router = createRouter({ history: createWebHistory(), routes: [ { path: '/user/:a:catchAll(.*)', component: component }, ] })
When the route is / user/a/b, the captured params are {"a": "a", "catchAll": "/ b"}
router.resolve
router.match Resolve is merged into router Resolve, but the signature is slightly different
// vue2.x router ... resolve ( to: RawLocation, current?: Route, append?: boolean) { ... return { location, route, href, normalizedTo: location, resolved: route } } // vue3.x router function resolve( rawLocation: Readonly<RouteLocationRaw>, currentLocation?: Readonly<RouteLocationNormalizedLoaded> ): RouteLocation & { href: string } { ... let matchedRoute = matcher.resolve(matcherLocation, currentLocation) ... return { fullPath, hash, query: normalizeQuery(rawLocation.query), ...matchedRoute, redirectedFrom: undefined, href: routerHistory.base + fullPath, } }
Get current route
Delete router Getmatchedcomponents, which can be obtained from router currentRoute. value. Get router from matched Getmatchedcomponents returns the target location or the component array matched by the current route (it is the definition / construction class of the array, not the instance). It is usually used when the data rendered by the server is preloaded.
[{ aliasOf: undefined beforeEnter: undefined children: [] components: {default: {...}, other: {...}} instances: {default: null, other: Proxy} leaveGuards: [] meta: {} name: undefined path: "/" props: ƒ (to) updateGuards: [] }]
use
If used, you may need to wait until the router is ready to mount the application
app.use(router)
// Note: on Server Side, you need to manually push the initial location router.isReady().then(() => app.mount('#app'))
In general, normal mounting can also be used, but now navigation is asynchronous. If there is a route guard during route initialization, there will be a transition of initial rendering before resolve, just like providing an appear ance for
In server-side rendering (SSR), you need to pass the appropriate history mode
const history = isServer ? createMemoryHistory() : createWebHistory() const router = createRouter({ routes, history }) // on server only router.push(req.url) // request url router.isReady().then(() => { // resolve the request })
When push ing or resolving a named route that does not exist, an error will be raised instead of navigating to the root route "/" and displaying nothing
In vue2 In X router, when push ing a named route that does not exist, the route will navigate to the root route "/", and nothing will be rendered. The browser console will only print warnings, and the url will jump to the root route.
const router = new VueRouter({ mode: 'history', routes: [{ path: '/', name: 'foo', component: Foo }] } this.$router.push({ name: 'baz' })
In vue3 In X router, the same method will cause errors.
const router = createRouter({ history: routerHistory(), routes: [{ path: '/', name: 'foo', component: Foo }] }) ... import { useRouter } from 'vue-next-router' ... const router = userRouter() router.push({ name: 'baz' })) // This line of code will report an error
Get route
Some online tutorials will tell you to access router and store objects through ctx, but in fact, this method can only be effective in the development mode. After compiling in the production environment, the properties seen by ctx under development cannot be accessed, which is easy to mislead you.
Examples of errors:
import { getCurrentInstance } from 'vue' export default { setup () { const { ctx } = getCurrentInstance() console.log(ctx) console.log(ctx.$router.currentRoute.value) const userId = computed(() => ctx.$store.state.app.userId) return { userId } } }
Correct use:
import { getCurrentInstance } from 'vue' import { useRouter, useRoute } from 'vue-router' import { useStore } from 'vuex' export default { setup () { const { ctx } = getCurrentInstance() console.log(ctx) const router = useRouter() const route = useRoute() const store = userStore() console.log(router, route, store) console.log(router.currentRoute.value) const userId = computed(() => store.state.app.userId) return { userId } } }
2,vuex@4.x
vuex4. There are few breaking change s in X, and there are few overall changes
Create instance
// vue2.x vuex import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex) export default new Vuex.Store({ state: {}, mutations: {}, actions: {}, getters: {}, modules: {} }
// vue3.x vuex import Vuex from 'vuex' export default Vuex.createStore({ state: {}, mutations: {}, actions: {}, getters: {}, modules: {} })
Get store
// vue3.x vuex import { getCurrentInstance } from 'vue' import { useRouter, useRoute } from 'vue-router' import { useStore } from 'vuex' export default { setup () { const { ctx } = getCurrentInstance() console.log(ctx) const router = useRouter() const route = useRoute() const store = userStore() console.log(router, route, store) console.log(router.currentRoute.value) const userId = computed(() => store.state.app.userId) return { userId } } }