There are plenty of articles about router, but so what? I’m going to write.

Vuejs actually has something called dynamic Components, which is similar to routing in that it displays different components on demand, but in practical use, it’s very cheap, it’s not very fun, it doesn’t programmatically navigate like routing (push.replace), there is no semantic guidance for the browser path, and dynamic components are more suitable for small local tabs to show you a wave of usage

<template>
    <div>
        ul>li>tab1+tab2     @click=""  <! --> >> Here change the TAB value of the following data to switch -->
        <! Router-link = router-link = router-link = router-link
        <component :is="tab"></component>  <! Router-view router-view router-view
    </div>
</template>

<script>
import tab1 from 'path/to/tab1.vue' // It introduces a lot of file trouble compared to vue-router
import tab2 from 'path/to/tab2.vue'
// The vue router also introduces files, but it is not easy to import so many files in the.vue file

export default {
    data(){
        tab:'tab1' // Tab1 is displayed by default
    },
    components:{
        tab1,
        tab2   // In es6 syntax objects, the same key value can be written like this}}</script>
Copy the code

Let’s forget about dynamic components and start router. Common API, the official website is very detailed. Check out the official tutorial and don’t forgetThe official API

Route Configuration

No matter what route configuration or vuex configuration, etc., there are corresponding specifications, in ordinary JS files, not according to the specification is not how, in TS files, will report an error. If you are interested in playing TS.

// router/index.js
// Omit a bunch of imports here
const router = new Router({
    base:'/'.mode:'history'.//default-->hash
    routes: [].scrollBehavior:() = >{
        return {x:0.y:0}}})Copy the code

The configuration is simple, that’s all.

base

Prefix of browser URL, default is ‘/’, if set to ‘/some/’ then run project, browser URL is all ‘/some/… ‘, will not affect the static file reference, generally write website will have a domain name, can point to a server directory, so the default ‘/’, if the company internal background management, then do not necessarily use a domain name, may be a directory under a CERTAIN IP, for example, the packaged file 111.22.33.44/admin, /admin/ is used as a prefix on the route path. Router-link and push methods should also be added with /admin. Cumbersome, but as long as base is set to ‘/admin/’, the internal configuration of the route and all related methods can ignore the directory name under the server IP. In this case, the publicPath of webPack should also be set to /admin/, which I won’t go into here.

mode

This is too easy. There are three modes,

Hash: The browser will have a ‘#’ symbol, reference the anchor point effect, the shortcoming is ugly, but good compatibility

History: Remove the ‘#’ symbol to make the URL look better. The server configuration will be covered below.

Abstract: This pattern is enforced in non-browser environments, such as WEEX

History mode Server configuration

My personal and company are in nginx, here speak nginx, configuration of the reason is that when you enter a routing, refresh the page again (or browser directly input a routing path), when the refresh the page, the browser will to DNS, TCP protocol, this time will be based on the browser’s url to the server to find corresponding resources, Vue router is a service for a single page, the corresponding URL must have no static resources on the server side, so 404 will appear. When configuring the following URL rewriting statement, note that it is rewriting, not redirection, without changing the URL, rewrite the browser content to index.html. Because of this index. HTML, the entry of our project, index. HTML, will read the packaged app.js at that time, so that we can read the routing configuration, so as to realize the routing page corresponding to the URL of our browser.

Hash mode does not need to be configured because browsers ignore # and? The following parameters

When the package is in the root directory,

location / { 
  try_files $uri $uri/ /index.html;
}
Copy the code

When the package is in a non-root directory,

location /admin {
  try_files $uri $uri/ /admin/index.html;
}
Copy the code

routes

Core routing configuration, the official website is very detailed, I will talk about a few points to note, all custom configuration, such as whether to need authentication or corresponding icon, etc., need to standardize the words are written in the meta object, non-standard words, and path at the same level, free to play, play bad I do not carry the fault.

Path must be specified, name must be unique, not mandatory.

Routes are configured to match sequentially. When a URL is successfully matched, no further matches are made, so pages like 403,404 should be written last.

The alias alias is used when you need to specify that a component is displayed in the router-view and that you want the browser URL to have the desired semantics

Redirect redirect: Indicates a path or object (redirect to a name)

scrollBehavior

This scrolling behavior, to be honest, feels awkward and I have hardly ever used it. It controls the body scrolling and many requirements are local scrolling. If you do need to control body scrolling, refer to the official documentation.

Use of routes

The router configuration starts with the root directory/and writes a layer of children to the router-view, otherwise the component will not display. Each nested children level corresponds to the router-view level.

// router/index.js
const router = new Router({
    routes:[
        {
            path:'/'.// Configure the first level of the array, which corresponds to the router-view in app.vue
            component:Home,// <<<----------------------------
            children: [// |
                {   // |
                    // The children level 1 appears at ------------
                    // Write a layer of router-view in the first Home component of the second level, and so on
                    path:'user'.component:User,
                }
            ]
        }
    ]
})
Copy the code

Route configuration generates the Menu menu

Menu is actually a route navigation, is router-link, many partners will build another file called menu.js, and then simulate the structure of the route configuration to write an array, and then generate dom according to this file traversal, is it redundant feeling, and when using the third-party MENU UI components, This static file is stateless (menu highlighting of the current access route, highlighting will be lost if you refresh the page or enter the URL of the route to enter the page).

Menu has a variety of situations,

  1. Fixed level, such as fixed 2 layer, or 3 layer, general background management system, fixed level more, because beautiful, clean. This is more convenient. The TEMPLATE DOM structure is also convenient.
  2. The product manager of “personality”, the menu menu of “customization”, the unknown level, here we need to use the render function to write dom.

Fixed level

<template>
    <div class="menu">
        <div class="first-menu" v-for="item,index in menus" :key="item.name">
            <router-link :to="item.name">{{ item.meta.zhName }}</router-link>
            <template v-if="item.children.length">
                <div class="sub-menu" v-for="subItem.subIndex in item.children"
                        :key="subItem.name">
                    <img :src="subItem.meta.icon" />
                    <router-link :to="subItem.name">
                    {{subItem.meta.zhName}}
                    </router-link>
                </div>
            </template>
        </div>
    </div>
</template>
<script>
export default {
    computed: {menus(){
            return this.$router.options.routes
            // Get the route configuration}}}</script>
<style>
.router-link-active{
    /* Activate style */
}
</style>
Copy the code

I’m only writing 2 layers here, and I’m not writing styles. If you use a menu component like element-UI, and it’s not rendered as a router-link underneath, then you have to programmatically navigate, click, push to item.name, The navigation style of the current route must be determined according to $route.name(current route configuration)

Unknown level

Because we do not know which layer of menu, so the HTML tag in the template cannot be freely traversed, so we need JS to operate the recursion of the route configuration, because the render function is js operation, so we need to use the render function to render.

<script>
export default {
    computed: {menus(){
            return this.$router.options.routes
            // Get the route configuration}},// With the render function you don't need to write the DOM of the template tag
    render(h){ 
        // The h parameter is createElement, which is a convenient and official recommendation
        / /... Here is the recursive code for manipulating menus, looping through the render function
        return h('div'.'This is a div.')
        // There must be a syntax for return}}</script>
Copy the code

See the render function documentation for the syntax.

$router.options.routes = $router.options.routes = $router.options.routes = $router.options.routes = $router.options.routes = $router.options.routes = $router.options.routes = $router. Permission control is not detailed, there are a lot of related articles, but do not recommend copy, suggest to add their own understanding, there is no absolute scheme.

Caching and transition animation of routes

Transition animations should be used for all of them, and most of them use opacity for transition.

<template>
    <transition mode="out-in" name="fade">
        <! $route.meta = $route. Meta = $route. Meta = $route.
        <keep-alive :include="aliveRoutes">
            <router-view :key="$route.fullPath" />
            <! -- Add the key to the complete path of the route, when the route is dynamic, trigger the route component to re-render -->
        </keep-alive>
    </transition>
    <! I won't go into the details of the official usage.
</template>
<script>
export default {
    computed: {aliveRoutes(){
            // this.$router.options.routes Gets the route configuration
            // You can configure whether meta is cached according to the meta field push into the array
            return [/ *... * /]}}}</script>
Copy the code

Routed hooks

The official website is super detailed. The trigger sequence is also clear. The official term is navigation Guard.

Note: Be clear about which hooks are global and which are internal to the component. All hooks need to be called next() to enter the route properly. When writing the internal logic of the hook function, it should be taken care not to form an infinite loop

For example,

router.beforeEach((to,from,next) = >{
    if (from.name === 'login'){
        next({
            name:'login'  / / death cycle
        })
        // See the official documentation for more next callback methods}})Copy the code

The usage of hooks in components depends on service requirements, for example, dynamic routing ↓↓↓.

Dynamic routing

Dynamic routing, use scenario is a fixed routing view component, with a dynamic browser URL, display different data in the view, and hope that the URL has the semantics of the current details, such as the details page, user information page.

Let’s look at how to configure dynamic routing. Here we use the detail page as an example

// router/index.js
const router = new Router({
    routes:[
        {
            path:'/list'.name:'list'.component:List
        },
        {
            path:'/detail/:id'.// Where id corresponds to params.id
            name:'detail'.component:Detail
        }
    ]
})
Copy the code
<! -- List.vue -->
<template>
    <div>
        <ul>
            <li @click="goDetail(item.id)" v-for="item in someData" :key="item.id">
            </li>
        </ul>
    </div>
</template>

<script>
export default{
    methods: {goDetail(_id){
            this.$router.push({
                name:'detail'.// Params takes effect only if the route is routed by name
                // Query is not affected
                params: {id:_id  // The value corresponds to the /:id of routes}})}}}</script>
Copy the code
<! -- Detail.vue -->

<script>
export default {
    beforeRouteEnter (to, from, next) {
        // This is a hook in the routing component. You can check whether to.params.id is undefined.
        // Do something because the route will match even if to.params.id is undefined
        // Because these ids may be used to fetch data, they will not be displayed on the page}}</script>
Copy the code

About route transmission parameters

  1. paramsAs mentioned above in dynamic routing, only configured through routingnameThis parameter takes effect only when a dynamic route is not usedparamsThe ginseng

Here are some caveats:

  • If dynamic routing is used, then the route is refreshed on the dynamic routing page, and the params parameter still exists,

  • If dynamic routing is not used, the params parameter is only valid when a route is jumped, and the params are lost when the page is refreshed

  1. queryParameter, can passpathornameJumps can be passed parameters, and the parameters will sumajaxthegetThe request is appended to the browser URL, and the refresh page remains

Lazy loading of routes

Route components package separate JS files. When accessing routes, load corresponding JS files, speed up the loading time of the home page, and increase the total volume of the project.

  1. npmoryarnThe installationbabel-plugin-syntax-dynamic-import
  2. .babelrcorbabel.config.jsconfiguration
module.exports = {
    plugins: ["syntax-dynamic-import"]}Copy the code
  1. Routing file usage
// router/index.js
const router = new Router({
    routes:[
        {
            path:'/list'.name:'list'.component:() = >import(/* webpackChunkName:"SOME_NAME" */'path/to/List.vue')
            // import is not the same as es6 import
            // Special comment syntax same chunkName packaged into a JS can be omitted}]})Copy the code

Named view of the route

I’ve never used a named view, so I don’t want to confuse you, but what I can explain is that a named view is a browser URL that matches multiple router-Views. Move to official documentation on demand.

Part of the API

  1. .vueIn the filethis.$routerIt is a mounted route instance and can be usedpushMethods.
  2. .vueIn the filethis.$routeCurrent routing information object, includingpath.queryEtc, read-only property.
  3. router.appRefers to therouterThe mountvueInstance, can passrouter.app.$options.storeaccessvuexAs long asmain.jsIn, we need to introducevuex, after the introduction ofrouterOtherwise, an error is reported.
  4. router.push()Common route redirect method, parameter is{path? :string,name? :string,params? :object,query? :object}, it should be noted that,pushIs the name of the method, not associated with the array.
  5. router.replace()Replace the current route, parameters andpushThe difference is that to replace the current route, click the browser return, does not return to the previously replaced route.
  6. router.go()androuter.back(), the argument is an integer, steps forward or backward.
  7. router.addRoutes()Parameters are required to conformroutesConfigure data, dynamically add route configuration to the original configuration.

The end of the

If you have any questions or are wrong, you can raise them

Tips: Sharing goes a long way.