Vue Router 入门

Vue Router 学习

前言

随着ajax兴起,页面请求越来越多,是用来处理单页应用 SPA(single page web application)的不二之选

SPA应用特点体现在如下:

  • 页面交互是无刷新
  • 页面的跳转也是无刷新的

原理是 匹配不同的 url 路径,进行解析,然后动态的渲染出区域 html 内容

每当切换路由的时候,在DOM中删除上一个路由节点(from),渲染一个新的节点(to)-- 可使用缓存路由

keep-alive,从而不使用这种销毁再创建的模式

可是url 每次变化的时候,都会造成页面的刷新,

那么解决办法就是在改变 url 的情况下,保证页面的不刷新


2014年以前前端路由是通过hash模式进行

通过类似这样 http://www.xxx.com/#login

这种 #的后面部分 ,后面的 hash 值会发生变化

并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。

另外每次 hash 值的变化,还会触发 hashchange 事件, 从而我们可知hash 发生了哪些变化

*** window.onhashchange***

然后我们可以监听 hashchange 来实现页面的更新

14年后HTML5 标准发布多了两个API `pushState· `replaceState`

至此url路径变得美观。(如果你愿意使用 vue-router 的同时开启 history模式的话)

mode:'history'

Vue Router 在模块化编程中的用法

现在来配置一个简单路由

\color{#ff0000}{注意:}加入路由跳转页面的组件都创建在 src 目录下的 view下比较好

view 下为页面级组件,一般不复用,一般引用 components下面的小组件

components 下为小组件,常用组件,一般会复用

router 名词,路由器(发出动作者)

route 名词,路由(所走的路径)

routes名词(复数)(代表一组路由路径)

  1. src 目录下创建一个文件夹为router

  2. 在router 文件夹下 创建 index.js 文件

  3. main.js 中导入 且声明使用

    import router from './router' // 省略了 /index.js 这是因为webpack默认 index true
    
    new Vue({
      router, //实例中使用
      store,
      render: h => h(App)
    }).$mount('#app')
    
  1. 编写index.js 文件

    import VueRouter from 'vue-router' //导入前 记得导入前置 vue
    
    Vue.use(VueRouter) // 使用
    
  2. 产生一个对象并向外暴露

    export default new VueRouter({
        
    })
    
  1. routes中配置 n个路由

    export default new VueRouter({
        mode:'history',
        routes: [    //多条对象,理因是一个数组
            {
                // 第1条路由
                path: '/',
                component: xxx // 对应映射的组件名 请在使用之前先导入组件
            },
            {
                // 第2条路由
                path: '/xxx',
    
            }
        ]
    })
    
  2. App组件中的模板中 在需要点击跳转路由的地方指定 router-link

<router-link to="/xxx">这里配置要显示的文本,相当于 a 连接</router-link>

to 里面的参数一定要写 routers 中的 path 对应一致

  1. 在指定变化的部分中加入router-view
<templete>
    <div id='app'>
        <nav>
            <router-link to="">Home</router-link>
            <router-link to="">About</router-link>
        </nav>
        <div class="main-body">
            <router-view></router-view>  <!--这里是需要变化的部分-->
        </div>
    </div>
</templete>

现在来配置一个嵌套路由

\color{#ff0000}{注意:}配置嵌套路由的时候,会出现如下情况:

下面这些问题,好像是我当初router-link 里面的 toindex.js 里面的路由映射对应>不上所以才产生的问题, 请仔细检查自己有没有配错!

指定的 层级嵌套路由路径不正确 (时刻注意 path 中最左边的 / 代表根路径,请写全,/father/child,或者 直接省略为 xxx

  • 在加入子路由嵌套的时候使用简写path会发生问题,点击子组件后不显示,(这个问题发生在 父组件的path/的时候),将/更改为具体的名称(或者老老实实写全路径)
const routes = [
  {
    path: '/',
    name: 'home',
    component: Home,
    children: [
      {
        path: '/home/news',  // 靠近path 最左侧的那个 /  代表根路径
        name: 'news',
        component: News
      },
      {
        path: 'message', // 这个时候简写会出现问题,点击会渲染不出,必须写全/home/message
        name: 'message',
        component: Message
      }
    ]
  },
  {
    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')
  }
]

/修改为具体路径可解决

{
path: '/home', //修改在这里
name: 'home',
component: Home,
children: [
  {
    path: '/home/news',  
    name: 'news',
    component: News
  },
  {
    path: 'message', // 简写没问题了
    name: 'message',
    component: Message
  }
]
},

在写path的时候,如果在 router-link 中用到了该 path,请一定对照写一致,

在写name的时候,必须写引入的组件中 组件的名字,如:

  export default {
      name: 'Login', //假设这是 登陆组件
  }

在路由中配置:

{
    path:'/login', //随意指定
    name:'Login', //不能随意指定,必须大小写一致,写成login就不行,vue默认按照组件名称渲染路由
    component:Login
}

缓存路由组件

用来保持组件的状态,在tab选项卡中跳转有时候需要查看下上一个tab的信息,但是之前的数据是从后台

获取来的,这个时候不需要再次请求数据(实时性要求比较低的),减小服务器压力,来使用 keep-alive保持,缓存这个组件对象

<keep-alive>
    <router-view></router-view>
</keep-alive>

使用编程式路由

意思就是不使用 <router-link> xxx </router-link>,这样的点击跳转,在代码执行的时候决定跳转路由

this.$router.push('/toPath')

使用 watch来监视路由的最新变化

vue中,获取实时最新的状态的方法就是 watch

如果有以下需求:

左边的树结构是 发起ajax 请求成功后渲染出来的,

左边的每一个树节点node 都有唯一的一个 Key标识

当点击某一个node的时候,进行路由跳转,需要传递对应的 Key标识改变路由跳转

结构和需求看起来像下面这样:

在这里插入图片描述

路由跳转时携带参数 params (此处没用 query来携带参数)

paramsquery的区别请点击

this.$router.push({name:'ModuleConfig',params:{index:n}})

// 得到 n 的值不在这里提出

右边的router-view区域中 使用watch

data(){
    return{
        index: this.$route.params.index
    }
}

好像有说法:

router只负责写(传)

route 只负责读(取)

'$route'(to,from){
    this.index = to.params.index  //获取实时最新的 后缀 index,然后index 变化时,整个表单变化
}
// 左值 index 定义在 data 中(普通属性)
// 右值 在路由跳转的携带参数中取出

router 中的 index.js 修改配置

const routes = [
    {
        path:'/ModuleConfig/:index',  //要对应
        name:'ModuleConfig',
        component:ModuleConfig,
    }
]

这里还可以将 index定义成 computed 属性

computed:{
    index(){
        return this.$route.params.index
    }
}

如果你需要分别拿到 oldvaluenewvalue,那显然 watch更合适

watch更像是为属性改变的前后定义的一个钩子函数,可以点击此处 参考查看我的另一篇文章中写到的区别

以后再慢慢更新,最后说下:

任何时候都参照下 Vue 风格指南都是好的。比如 staticassets文件夹的区别,又比如viewcomponents文件夹的区别,说不定每次 vue-cli 的更新都会带来 vue ui 构建项目后的文件夹不一致呢? GO to Vue 风格指南

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。