Vue—09—路由vue-router;


动态路由:

多个路由指向同一个组件;比如/user/:id,id传的不一样,但是会都匹配这个路由记录,然后指向同一个组件;

注意两点(1)这个时候组件是会被复用的,组件实例并不会销毁重建,而是直接使用;(2)组建内部可以通过this.$route.params来获取后面跟的参数

嵌套路由

一个组件内部还有route-view,即嵌套了一个路由视图;如何访问,在路由表里定义children数组;

命名路由

在路由表里,除了用path属性表示匹配到的组件外,也可以用name属性;

编程式路由导航

除了在router-link组件中导航外,还可以使用this.$route.push(),这种方式是在js里写的,所以叫编程式;

const userId = '123'
// 1.参数可以是字符串
router.push('home')

// 2.参数也可以是对象
router.push({ path: 'home' })
// 2.1参数是一个对象,对象里面使用name表示命名路由,适用params表示动态参数
router.push({ name: 'user', params: { userId: '123' }})。  // -> /user/123
      //等同于这样写:router.push({ path: `/user/${userId}` }) // -> /user/123
// 2.2参数是一个对象,对象里面使用path表示路由跳转路径,使用query属性表示查询参数;
router.push({ path: 'user', query: { userId: '123' }})。// ->user?userId=123

//  3.注意:
//如果对象里提供了path属性,params 属性会被忽略,但是query属性不会忽略;
//这里的 params 不生效.  //如果想要params生效,请配合name使用;
 router.push({ path: '/user', params: { userId }}) // -> /user

参数解藕(路由组件穿参)

如果组件里一直通过this.$route.params或者this.$route.query的方式取值,那么这个组建会和路由耦合性太高,如果这个组件平时随便用用自然无所谓,可如果是想要它做一个高度可复用的组件,那最好是进行参数解藕,把this.$route.params当作props参数传递过来;

路由视图:

router-view就是路由视图;

路由记录:

routes路由表配置中的每个路由对象为 路由记录

一个路由匹配到的所有路由记录会暴露为 $route 对象的 $route.matched 数组;

路由守卫

全局守卫

  1. beforeEach,
  2. resolveEach
  3. afterEach

路由表守卫

  1. beforeEnter

组件守卫:

  1. beforeRouteEnter
  2. beforeRouteUpdate
  3. beforeRouteLeave

路由元信息

通过路由记录获取在路由表上定义的meta信息;

this.$route.matched.forEach( e => e.meta);

路由过度动画

给路由视图加上一个<transition></transition>组件即可;

路由懒加载

无webpack:
  routes: [{ path: '/foo', component: ()=>{Promise.Resolve({组件对象})} }]

有webpack:
  routes: [{ path: '/foo', component: ()=>{import( '路径名举例:./Foo.vue')}  }]

 

 

数据获取

导航完成后在creted钩子函数里;

滚动行为

当创建一个 Router 实例,你可以提供一个 scrollBehavior 方法:

const router = new VueRouter({
  routes: [...],
  scrollBehavior (to, from, savedPosition) {
    // return 期望滚动到哪个的位置
  }
})

 

导航故障

 

 

 

 

 

 

 


 

一、前后端渲染和前后端路由

 

后端渲染:后端已经把数据嵌套在html和css上了,然后后端给前端发送的是一个完整的html页面,浏览器显示出来就行了。

前端渲染:前端先去静态资源服务器下载html、css、js代码,并展示出来,但展示了htmlcss后,当遇到了js代码时,js代码会向后端发送请求并接受后端发送来的数据,然后进行处理(比如说js代码要循环生成x个input框,后端告诉前端x等于10,然后html就要继续多生成10个input标签),    最终得出一个完整的html,这就是前端渲染;

后端路由:

浏览器请求的每一个url,后端路由都根据路由表发送到专门的controller中进行处理(路由表应该是tomcat+spingMVC的DispacharServlet进行处理的)

前端路由:

前端路由首先是到了sqa阶段,由于我们只有一个index页面,我们想展示不同的页面,就需要调用不同的子组件模板去覆盖,哪如何根据不同的url去找不同的子组件模板?使用vue-router;

 

 

 

 二、前端发展的几个阶段

前端的几个阶段:

1.jsp阶段或者template阶段:

需要写html代码在jsp中,由于jsp还有java代码调用数据,所以整个页面非常不清晰;

或者template阶段,html代码虽然不和java代码在一起写了,但是仍然是后端渲染,将html页面渲染好之后发送给前端;

这个个时候没有前端路由只有后端路由去根据url找controller;并且是后端渲染;

2.前后端分离阶段:

浏览器根据不同的url去静态资源服务器(可能是node服务器)请求到不同的一套html、css、js代码,将jtml、css渲染好之后,当遇到了js代码时,js代码会向后端发送请求并接受后端发送来的数据,然后进行处理(比如说js代码要循环生成x个input框,后端告诉前端x等于10,然后html就要继续多生成10个input标签),    最终得出一个完整的html,这就是前端渲染。

虽然,前后端分离阶段没有用到前端路由,但是开始前端渲染;

3.spa阶段:

这个时候,整个静态资源服务器只有一套html、css、js代码,前端服务器需要根据不同的url代码去寻找不同的子组件模板来代替index.html页面,这个时候就是前端路由;

当然遇到了js代码,也需要从后端获取数据,然后前端渲染;

https://www.bilibili.com/video/BV15741177Eh?p=101&spm_id_from=pageDr

 

 

三、路由的几种模式

路由的几种模式:

1.hash模式

2.history模式

histroty.back() 相当于  history.go(-1)

histroty.forward() 相当于histroty(1)

 

 

四、路由vue-router的简单使用

1.使用

首先配置vuerouter:

1.npm install vue-router -S

2.配置router文件下的index.js文件

3.配置main.js

其次使用vue-router:

1.在app.vue里配置《router-link》和《router-view》

2.router-link的4个属性:

 

 

 3.组件如何通过vue-router切换?

《router-view》标签会展示我们替换的组件;

vue-router安装好之后,会往所有的组件里都有$router属性;

不用router-link,使用this.$router.push()进行组件的切换;

 

 

 

 

五、路由vue-router的高级使用

$router和$route的区别:
$router表示我们在index.js文件中new的router对象;

$route表示那个路由路径活跃,我们就去取哪个对象;$route的params属性就可以取到使用本路由的url的后缀;

1.动态路由(参考4传递参数,有异曲同工之妙)

即在index。js文件中设置一个动态的路由,格式为:

    {
      path:'/user/:suibian',
      component:User,
    },

我们在app.vue的tempalte模板的《router-link》标签的to属性中,给:suibain穿什么值,它就接受什么值,比如说suibian=aaa,

那么这个路由就会跳到User.vue组件,但是路由url变成了/usr/aaa;

然后我们在User.vue中可以通过$route.params.suibian获取到suibian的值的aaa;

 

 2.懒加载

用到时再加载

 懒加载的使用方式:

 

 3.嵌套路由

就是子路由;

在indexjs文件中设置子路由,然后在本vue中再设置《route-link》《router-view》标签,因为子路由所展示的vue页面是覆盖本vue的;

 

 

 

 4.传递参数

第一方式是使用动态路由的方式,在index.js文件中的router属性里写变量,

    {
      path:'/user/:suibian',
      component:User,
    }

 然后后面的vue文件通过$route.params.变量名取值;

第二种方式是传过去一个对象,对象里有Path,这个属性是跳转的url,query是要传递的参数;

 

 然后后面的vue文件通过$route.query.变量名取值;

这样看来还是用query的方式好一点。

注意:
所有的组件都继承自vue的原型;
vue的原型是绑定了¥router和¥route,所以¥router和¥route是所有组件都可以用的; 

 

 

 

5.全局导航守卫(路由守卫)

所有的组件都有生命周期函数:

created():组件一被创建时调用

mounted():组件被挂载时调用

updated():组件被更新时调用;

通过这三个生命周期函数,我们可以实现进入某.vue文件时、。vue文件加载完成时、。vue文件数据发生改变时我们可以监听到并根据自己需要改变;

但是如果每一个。vue文件都写着三个函数有点太复杂了,我们可以使用全局导航守卫。

这是所有的路由都可以用的守卫;除了全局导航守卫,还有

  • 路由独有导航守卫(具体去官网学习)
  • 组件内守卫(具体去官网学习)

如何使用呢?我们以修改页面的title为例,第一我们先给每个路由定义一个mete属性,并写上进入我这个路由后浏览器的title要修改成的值,然后在index。js问文件中使用router调用beforeEach()方法,并调用函数

import Vue from 'vue'
import VueRouter from 'vue-router'

//统一管理组件的懒加载
const HelloWorld = () => import('@/components/HelloWorld.vue');


//1.加载vuerouter
Vue.use(VueRouter)

//2.定义路由引射表
const route = [
  {
    path:'/helloworld',
    component:HelloWorld,
    meta:{
      title:'你好世界',
    },
    children:[
      {
        path:'/',
        redirect:'hw222',
      },
      {
        path:'hw111',
        component:HelloWorld111,
      },
      {
        path:'hw222',
        component:HelloWorld222,
      },
    ],
  },
  {
    path:'/test',
    component:Test,
  },

];

//3.初始化路由
const vueRouter =  new VueRouter({
  routes:route,
  mode:'history',
})
//3.1添加路由守卫 vueRouter.beforeEach((to,from,next)
=> { window.document.title = to.matched[0].meta.title; next() }) //4.导出路由 export default vueRouter;

 

meta:元数据:描述数据的数据

metacalss:元类,由元类创造类,再由类创造实例;

除了由路由守卫beforeEach还有路由钩子afterEach,这些都和路由独有守卫、组件守卫一样自己去官网看吧。

 

posted @ 2021-08-28 15:15  Eric-Shen  阅读(99)  评论(0编辑  收藏  举报