ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Vue —— 精讲 VueRouter( 2 )

2020-06-14 09:02:46  阅读:314  来源: 互联网

标签:Vue title Route alive vue VueRouter path 精讲 路由


接着上一讲的内容

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

这里我们有这样的方式去传递路由参数
我们可以通过$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
  one rror(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文件夹的映射
    }
  },

标签:Vue,title,Route,alive,vue,VueRouter,path,精讲,路由
来源: https://www.cnblogs.com/BM-laoli/p/13123712.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有