Vue Router 详解 路由嵌套、路由模式、动态路由、路由守卫

路由

路由不仅前端有,源于服务器端,前端发送Http请求到服务器端,带地址(api/goods),后台通过接口该URL去匹配对应的类和函数处理 返回结果;
前端的路由: 当浏览器的URL变化时,vue就知道要切换内容了, 拿出对应的模版 vue渲染成真正的HTML页面;
           根据URL,动态的添加DMO和移除操作

Vue Router

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌。
包含的功能有:
1. 嵌套的路由/视图表
2. 模块化的、基于组件的路由配置
3. 路由参数
4. 基于 Vue.js 过渡系统的视图过渡效果
5. 细粒度的导航控制
6. 带有自动激活的 CSS class 的链接
7. HTML5 历史模式或 hash 模式

router.js 中 new Router 创建路由实例,并导出

import Vue from "vue";
import Router from "vue-router";
import Login from "./views/Login.vue";
import DashBoard from "./views/DashBoard.vue";

Vue.use(Router);
const router =  new Router({
  base: process.env.BASE_URL,
    routes: [
      {
        path: "/",
        redirect: "/dashboard"
      },
      {
        path: "/login",
        name: "login",
        component: Login
      },
      {
        path: "/dashboard",
        component: DashBoard,
      }
    ]
})
export default router;
main.js
  import Vue from "vue";
  import App from "./App.vue";
  import router from "./router";
  import store from "./store";

  Vue.config.productionTip = false;

  new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount("#app");
app.vue 使用 router-view 占位符
路由出口:

导航 使用 App.vue 中,使用 router-link 作为导航按钮
路由导航:
Home |
login |
DashBoard

模式

1、大家都知道vue是一种单页应用,单页应用就是仅在页面初始化的时候加载相应的html/css/js一单页面加载完成,不会因为用户的操作而进行页面的重新加载或者跳转,用javascript动态的变化html的内容

优点: 良好的交互体验,用户不需要刷新页面,页面显示流畅, 良好的前后端工作分离模式,减轻服务器压力,
缺点: 不利于SEO,初次加载耗时比较多

2、hash模式
vue-router默认是hash模式: 使用URL的hash来模拟一个完整的URL,于是当URL改变的时候,页面不会重新加载,也就是单页应用了,

当#后面的hash发生变化时:window.onhashchange
不会:浏览器不会向服务器发出请求、不会刷新页面,
 会:触发hashchange这个事件,通过监听hash值的变化来实现更新页面部分内容的操作;
     会创建hashHistory对象, 在访问不同的路由的时候,会发生两件事:
     HashHistory.push():将新的路由添加到浏览器访问的历史的栈顶
     HasHistory.replace():替换到当前栈顶的路由

      http://music.163.com/#red

     window.οnhashchange=function(event){
        console.log(event.oldURL,event.newURL);
        let hash=location.hash.slice(1);
        document.body.style.color=hash;
      }

3、history模式
随着history api的到来,前端路由开始进化了,前面的hashchange,你只能改变#后面的url片段,而history api则给了前端完全的自由
history api可以分为两大部分,切换和修改

默认是hash模式,url使用#后面定位路由,对seo不利,设置history,就可以使用普通的url模式
url就变成了 http://localhost:8080/login

核心API:
pushState()  改变url地址且不会发送请求; 
window.history.pushState(stateObject, title, URL)
replaceState()  读取历史记录栈、对浏览器记录进行修改; 
window.history.replaceState(stateObject, title, URL)

包括back,forward , go 三个方法
history.go(-2);//后退两次
history.go(2);//前进两次
history.back(); //后退
hsitory.forward(); //前进

window.history.pushState({color:'red'},'red','red'})
window.onpopstate=function(event){
  console.log(event.state)
  if(event.state&&event.state.color==='red'){
    document.body.style.color='red';
    }
  }
  history.back();
  history.forward();

通过pushstate把页面的状态保存在state对象中,
当页面的url再变回这个url时,可以通过event.state取到这个state对象,从而可以对页面状态进行还原,这里的页面状态就是页面字体颜色,其实滚动条的位置,阅读进度,组件的开关的这些页面状态都可以存储到state的里面。


区别:
前面的hashchange,你只能改变#后面的url片段。而pushState设置的新URL可以是与当前URL同源的任意URL。
history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误

history模式怕啥通过history api,我们丢掉了丑陋的#,但是它也有个毛病:不怕前进,不怕后退,就怕刷新,f5,(如果后端没有准备的话),因为刷新是实实在在地去请求服务器的,不玩虚的。
在hash模式下,前端路由修改的是#中的信息,而浏览器请求时是不带它玩的,所以没有问题.
但是在history下,你可以自由的修改path,当刷新时,如果服务器中没有相应的响应或者资源,会分分钟刷出一个404来。


// routes.js

const router =  new Router({
  mode: "history",
  ......
  })

动态路由

路由可以携带一些参数,使用 this.$router 获取
{
  path: "home1/:room/:bad", //参数prams 必传 : 占位符(可读性比较强)  需在route中配置; 还有一种是查询参数query
  name: "home1", // 以指令的形式传参数 当push的是一个对象时,  push的时候也可以把路径和参数组合到一起成一个String就可以不用name 如Home.vue
  component: Home1
}
app.vue 中
Home1-2

Home1.vue 中



路由 Props

[
        {
          path: "static",
          component: Home,
          props: {
            foo: "foo0"
          } //可直接传给组件的props 给组件传静态值  注意:要在组件中定义传入的prop
        },
        {
          path: "static/:foo1",
          component: Home,
          props: true //可直接传给组件的props 给组件传静态值foo1 注意:要在组件中定义传入的prop
        },
        {
          path: "home2/:id/:msg",
          component: Home2,
          name: "home2",
          props: func //函数形式 拓展性更强 注意:要在组件中定义传入的prop
        },
]


function func({ params, query }) {
  return {
    id: params.id,
    msg: params.msg,
    foo: query.foo
  };
}

在HOME2.vue中


export default {
  name: "home2",
  props: ["id", "msg", "foo"],
}

重定向

{
      path: "/",
      redirect: "/dashboard"
},

路由守卫

全局路由守卫 beforeEach 所有路由跳转前执行,next 同意跳转 比如 login 执行 1 秒后跳转
to:进入到哪个路由去,
from:从哪个路由离开,
next:函数,决定是否展示你要看到的路由页面。

router.beforeEach((to,from,next)=> {
  console.log(to);
  if (to.path !== "/login") {
    if(store.state.isLogin) {
      next();
    } else {
      next("/login?redirect="+to.path);
    }
  } else {
    next();
  }
});
独享守卫 beforeEnter 所有路由跳转前执行,next 同意跳转 比如 login 执行 1 秒后跳转
{
      path: "/dashboard",
      component: DashBoard,
      beforeEnter(to,from,next){
        if (store.state.isLogin) {
          next();
        } else {
          next('/login?redirect='+to.path);
        }
      },
}
组件级别的 beforeRouterEnter beforeRouteUpdate 在 Home2.vue 里面

    beforeRouteEnter(to, from, next) {
    console.log("Home2路由进入前");
    next();
  },
  beforeRouteUpdate(to, from, next) {
    console.log("Home2路由,但是参数变了");
    next();
  },
  beforeRouteLeave(to, from, next) {
    console.log("Home2路由离开前");
    next();
  }

完整的导航解析流程

导航被触发。
在失活的组件里调用离开守卫。
调用全局的 beforeEach 守卫。
在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
在路由配置里调用 beforeEnter。
解析异步路由组件。
在被激活的组件里调用 beforeRouteEnter。
调用全局的 beforeResolve 守卫 (2.5+)。
导航被确认。
调用全局的 afterEach 钩子。
触发 DOM 更新。
用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

最后 附上gitHub地址VueDemo,不妨下载试试吧,后续也将在该项目中持续更新vue相关内容。有疑问欢迎给我留言喔,对了,转载请注明出处喔,谢谢。

你可能感兴趣的:(web技术总结)