zoukankan      html  css  js  c++  java
  • Vue —— 精讲 VueRouter( 2 )

    接着上一讲的内容

    八、编程导航中的路由传参

    这里我们有这样的方式去传递路由参数
    我们可以通过$touter.query的方式获取传递过来的参数,
    我们不需要,在路由里面加:id,什么的去获取这个东西,我们可以特殊的方式传递数据,就好了

    1. 传递
      /App.vue
    <router-linnk :to="{path:'/profuke',query:{name:'why','age':18}}"></router-linnk>
    
    
    1. 获取
      /Profile.vue
    //通过这样的方式就能把传递过来的query全部搞到手
    <h2> {{ $route.query }} </h2>
    
    1. 注意这里如何通过方法传递?非常的简单
    profileClick(){
        this.$router.push({
            path:'/profile',
            query:{
                name:'kebo',
                age:19,
                heigth:1.87
            }
        })
    }
    

    九、 $router 和 $route的区别

    (router是值的是new Router()的对象,)route 是当前处于活跃状态的 路由对象,比如你当前的在home下那么$route就是当前的具体状态的路由对象

    源码解析,我们看看vue.use()这个方法到底做了什么

    // 实际上,我们的按照插件的时候,不管是什么插件,实际上user的时候是去执行它对应的install方法
    
    export declare class VueRouter {
      constructor(options?: RouterOptions)
    
      app: Vue
      mode: RouterMode
      currentRoute: Route
    
      beforeEach(guard: NavigationGuard): Function
      beforeResolve(guard: NavigationGuard): Function
      afterEach(hook: (to: Route, from: Route) => any): Function
      push(location: RawLocation): Promise<Route>
      replace(location: RawLocation): Promise<Route>
      push(
        location: RawLocation,
        onComplete?: Function,
        onAbort?: ErrorHandler
      ): void
      replace(
        location: RawLocation,
        onComplete?: Function,
        onAbort?: ErrorHandler
      ): void
      go(n: number): void
      back(): void
      forward(): void
      getMatchedComponents(to?: RawLocation | Route): Component[]
      onReady(cb: Function, errorCb?: ErrorHandler): void
      onError(cb: ErrorHandler): void
      addRoutes(routes: RouteConfig[]): void
      resolve(
        to: RawLocation,
        current?: Route,
        append?: boolean
      ): {
        location: Location
        route: Route
        href: string
        // backwards compat
        normalizedTo: Location
        resolved: Route
      }
    
      static install: PluginFunction<never>
    }
    // 我们在vue-router源码中,看到了一个install方法,这个就是use中执行的方法,
    // 源码中最重要的还有一个方法,现在,我们先看看就好,后面会说到
    export interface RouterOptions {
      routes?: RouteConfig[]
      mode?: RouterMode
      fallback?: boolean
      base?: string
      linkActiveClass?: string
      linkExactActiveClass?: string
      parseQuery?: (query: string) => Object
      stringifyQuery?: (query: Object) => string
      scrollBehavior?: (
        to: Route,
        from: Route,
        savedPosition: Position | void
      ) => PositionResult | Promise<PositionResult> | undefined | null
    }
    
    
    

    实际上,在vue的设计中,很多地方都用到了一些高级的JS知识,比如get() set()方法等... 这些知识点都在<<js高级程序设计>>中可以获取,所以高程吃透80%什么框架都是soeasy

    十、导航守卫

    阅读源码非常的重要,我们有很多的东西实际上都可以不用详细的去记,只需要看源码理解就好了。

    需求1实现页面的title

    我们有这样的一个需求,我们希望我们页面的title会跟着我们的组件发生变化,是home就显示首页,是about就显示关于

    1. 解决方案1

    我们都知道,我们的组件有生命周期函数,其中最重要的生命周期函数是如下的四个

    • created()
    • mounted()
    • updated()

    那么我们可以在组件创建的时候,在页面还没有挂载上dom上之前,creatd生命周期里改它的title,就能实现我们的需求
    /Home.vue

    created(){
        doucument.title='首页'
    }
    
    1. 优化解决方案

    我们确实实现了这样的一个需求,但是有问题,如果有100k组件,我们不太可能写100k同样的代码,我们选择使用路由导航

    在Router源码中,有这样的一个东西

    export type NavigationGuard < V extends Vue = Vue > = (
      to: Route,//通过源码,我们知道这个to实际上就是当前页面的那个route对象
      from: Route,//这个from就是指的是父级路由 route 对象
      next: (to?: RawLocation | false | ((vm: V) => any) | void) => void
    ) => any
    
    export declare class VueRouter {
      constructor(options?: RouterOptions)
    
      app: Vue
      mode: RouterMode
      currentRoute: Route
    
      beforeEach(guard: NavigationGuard): Function
      beforeResolve(guard: NavigationGuard): Function
      afterEach(hook: (to: Route, from: Route) => any): F
    

    于是我们就能在beforeEach的时候拦截一下做一些特殊的处理
    需要注意的是:如果是多个嵌套路由,就需要 to.matched[0].meta.title,同样的,这个也适用于非嵌套路由,为了统一代码规范,我们都加上这个meta比较好
    /router/idnex.js

    
       path: '/home',
            component: Home,
            meta: {
                title: '首页'
            },
            children: [{
                    path: '',
                    redirect: 'news'
                },
                {
                    path: 'news',
                    component: HomeNews,
                    meta: {
                        title: '新闻'
                    }
    
                },
                {
                    path: 'message',
                    component: HomeMessage,
                    meta: {
                        title: '消息'
                    }
                },
    
            ]
        },
        {
            path: '/about',
            component: About
        },
        {
            path: "/user/:usermsg",
            component: User
        }
    ]
    
    const router = new Router({
        routes,
        mode: "history"
    })
    
    router.beforeEach((to, from, next) => {
        document.title = to.matched[0].meta.title
        next()
    })
    
    
    

    我们的路由hook还有很多

    我们的路由还有很多的hook钩子,请去翻阅官方的文档

    十一、keep-alive

    我们现在有这样的一个需求,我们希望我们跳转的时候把状态保持下来(换句话说就是缓存起来),要实现这样的一个功能,我们就需要使用到keep-alive

    知识点补充

    1. 在vue的官网实际上有这个解释和说明,只需要在router-view的地方包一个东西就好了,
    <keep-alive>
        <router-view/>
    </keep-alive>
    

    这样就可以把原来的东西组件的一些状态 缓存起来。缓存起来之后,下一次切换的时候就不会重新去创建路由

    keep-alive是vue内置的一个组件,可以使被包含的组件保存状态,避免重新的渲染,提高性能

    1. 几个常见的生命周期

    注意啊,这个东西一定要配合几个生命钩子函数一起使用,要不然就显得蛋疼
    下面的几个生命周期是我们经常使用的东西

    // 组件销毁调用的几个方法
    destroy(){}
    destroyed(){}
    
    // > 下面的 活跃 状态的方法 仅仅在有keep-alive包裹的router-view下才有用
    activated(){}
    deactivated(){}
    
    

    案例实现具体代码

    这里我们需要面临的是这样的一个需求,实际上 单纯的看keep-alive的东西,还是非常简单的,但是由于是嵌套路由以及重定向就需要考虑,它的路由地址会影响整个keep-alive。所以会出现一定的问题

    如下是解决方案,这里面使用的路由的一些hook函数,还是使用了keep-alive的hook函数

    • 去除路由的默认跳转行为,要不然它会干扰我们的keep-alive的状态保持
      /route/index.js
    const routes = [{
            path: '/',
            redirect: '/home'
        },
        {
            path: '/home',
            component: Home,
            meta: {
                title: '首页'
            },
            children: [{
                // 这里去除了 路由的重定向,避免造成干扰
                    path: 'news',
                    component: HomeNews,
                },
                {
                    path: 'message',
                    component: HomeMessage,
                },
            ]
        },
        {
            path: '/about',
            component: About,
            meta: {
                title: '关于'
            }
        },
        {
            path: "/user/:usermsg",
            component: User,
            meta: {
                title: '用户'
            }
        }
    ]
    
    
    • keep-alive管理路由
      /App.vue
    <keep-alive>
      <router-view/>
    </keep-alive>
    
    
    • 去我们的需要保持的子路由页面中动一下手脚
      /home.vue
    
    <template>
        <div>
            <h2>我是首页</h2>
            <p>我是首页内容哈哈哈</p>
         <router-link to="/home/news">news</router-link>
         <router-link to="/home/message">message</router-link>
    
                 <router-view/>
        
        </div>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    path: '/home/news'
                }
            },
            created () {
                console.log('created');;
            },
            // kepp-alive当前管理状态活跃时就去跳转到指定路由地址
            activated(){
                this.$router.push(this.path)
            },
            // 离开的时候保存这个路由地址,下一次活跃的时候重新赋值上就好了
            beforeRouteLeave(to, from, next) {
                console.log(this.$route.path);
                this.path = this.$route.path
                next();
            },
            
        }
    </script>
    
    <style scoped>
    
    </style>
    
    

    新的需求

    我们现在又有新的需求了,要知道一点,我们目前的所有的组件都是被保持状态的,现在我们有这样的一个需求,我们希望User组件还有About组件可以不被keep-alive管理,那么怎么做呢?

    1. 要实现这样的功能要调用keep-alive的属性,但是这个属性依赖于组件的名字,所以你的组件要有name属性,现在我们就去给user还有profile组件加上这个name属性
    
        export default {    
        computed: {
          name:'User',
            username() {
                    return this.$route.params.usermsg
                }
            },
        }
        
        =======
    
        export default {    
        computed: {
          name:'About',
            username() {
                    return this.$route.params.usermsg
                }
            },
        }
    
    1. 使用keep-alive特有的属性来实现这样的功能
      /App.vue
    <keep-alive exclude="User,About">
      <router-view/>
    </keep-alive>
    
    <!-- 实际上,我们还有include,不必多说,这个是包含的意思 -->
    

    给路径起别名

    实际上的别名都是在weboack配置好的

    1. 我们先来看看vue中的@是搞什么的

    实际上非常的简单 这个@符号就是代表当前的这个src文件夹根目录

    1. 我们来搞搞吧在vue2.0的版本中,我们是可以配置的,
      /build/webpack.base.config.js
    
     resolve: {
        extensions: ['.js', '.vue', '.json'],
        alias: {
          '@': resolve('src'), // 这里的@就是一个队src文件夹的映射
        }
      },
    
    
  • 相关阅读:
    制衡技术的新蓝海
    制衡技术,从Adblock所想到的
    centos6中安装新版 Elasticsearch 7.x
    nrm 安装与npm镜像切换
    james2.3 配置收件 之 MariaDB数据库配置
    手动搭建apache james邮件服务器,实现邮件功能
    James 如何作为服务在后台启动
    安装最新版RabbitMQ v3.7.13 以及基本配置
    mac 下 通过 brew 安装 MariaDB
    Mac 上安装maven
  • 原文地址:https://www.cnblogs.com/BM-laoli/p/13123712.html
Copyright © 2011-2022 走看看