一、简易demo
// routes注册
import Vue from "vue";
// import VueRouter from "vue-router";
import VueRouter from "./vueRouter"; // 自定义路由 js
import Home from "../views/Home.vue"; Vue.use(VueRouter); const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
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"),
},
]; const router = new VueRouter({
mode: "history",
routes,
}); export default router;
// vueRouter
var _Vue = null export default class VueRouter {
// 一、 install方法
static install(Vue) {
// 1、判断插件是否注册
if (VueRouter.install.installed) return
VueRouter.install.installed = true // 2、将Vue构造函数记录到全局变量
_Vue = Vue // 3、把创建Vue实例的时候传入的router对象注入到Vue实例上
// _Vue.prototype.$router = this.$options.router;
// 混入
_Vue.mixin({
beforeCreate() {
if (this.$options.router) {
_Vue.prototype.$router = this.$options.router
this.$options.router.init() // ?
}
}
})
} // 二、构造函数
constructor(options) {
this.options = options
this.routeMap = {}
this.data = _Vue.observable({
current: '/'
})
} init() {
this.createRouteMap()
this.initComponents(_Vue)
this.initEvent()
} // 三、createRouteMap
createRouteMap() {
// 遍历所有的路由规则,把路由规则解析成键值对,保存在routeMap中
this.options.routes.forEach(route => {
this.routeMap[route.path] = route.component
})
} // 四、initComponents
initComponents(Vue) {
Vue.component('router-link', {
props: {
to: String
},
// template: '<a :href="to"><slot></slot></a>'
render(h) {
return h(
'a',
{
attrs: {
href: this.to
},
on: {
click: this.clickHandler
}
},
[this.$slots.default]
)
},
methods: {
clickHandler(e) {
history.pushState({}, '', this.to) // 修改地址栏 - 不会发送请求
this.$router.data.current = this.to // 重新加载响应的组件
e.preventDefault() // 阻止发送请求
}
}
}) const self = this
Vue.component('router-view', {
render(h) {
let component = self.routeMap[self.data.current]
return h(component)
}
})
} // 五、返回按钮、前进按钮问题
initEvent() {
window.addEventListener('popstate', () => {
this.data.current = window.location.pathname
})
}
}
二、Vue-Router传参方式

一、普通、动态路由传参方式

// 路由代码传参
import About from 'about'
// routes 配置
{
path: '/about/:id', // 动态路由
component: About,
props: true // ①布尔模式
} {
path: '/about', // 普通路由
component: 'About',
props: { id: 19 } // ②对象模式
} // 接收方式 props
props;['id'] 或者
props: {
id: { type: Number, default: 12}
}
// ③函数模式
routes:[
{
path: '/about',
component: About,
// props: route => ({id:route.query.id}) // url='/about?id="89"' 或者
props: route => ({id: route.params.id}) // url='/about/:id' => '/about/89'
}
]

二、动态路由:将给定匹配模式的路由映射到同一个组件,复用一个组件,相对与销毁后重建更高效。

  • Keep-alive包括时,组件的声明周期钩子函数不会被重复调用。

  • 要对同一个组件中参数变化做出响应的话,可以通过watch 侦听$route对象上的任意属性

    watch: {
    $route: {
    immediate: true,
    handler(route) {
    // 处理事件 对路由变化做出响应
    }
    }
    }
  • 或者使用导航守卫,beforeRouteUpdate,也可以取消导航

三、捕获所有路由或404路由

四、路由的匹配语法

  • 自定义正则 像可以区分 /list/100 和/list/xsk 等路由

    • routes: [ { path: '/list/:id(\\d+)'}, {path: '/list/:name'} ]
  • 可以重复的参数 匹配多个部分的路由,可以用 * 号和 +号将参数标记为重复

  • 也可通过使用?号修饰符(0个或1个)将一个参数标记为可选

五、嵌套路由、命名路由

六、编程式导航

  • 声明式()\编程式路由 router.push(...)

  • Router.push(params):

    • Params: 字符串路径、路径对象、命名的路由并加上参数、带查询参数、带hash

    •   '/users/detail'
      { path: '/users/detail' }
      { name: 'detail', params: {id: '0'}}
      { path: '/users/detail', query: {id: '0'} }
  • 替换当前位置 router.replace({path: '/users'}) 或者router.push({path:'users', replace: true}); 导航时不会向history添加记录

  • history.go()横跨历史

七、命名视图:

八、重定向配置

// 通过routes配置来完成
const routes = [{ path: '/home', redirect: '/'}]
// 重定向的目标也可以是一个命名的路由 redirect: { name: 'Details'}
// 一个方法动态返回重定向目标
const routes = [
{
path: '/home/:id',
redirect: to => {
return {path:'Details', query: { q: to.params.searchText}}
}
}
]
// 别名
alias: '/home'

九、路由组件传参 props、$route.query$route.params

  • 布尔模式 routes配置时 props:true设置即可

  • 对象模式 props: { id: '0' } 当props为静态的时候很有用

  • 函数模式 创建一个返回props的函数,允许你将参数转换为其他类型,将静态值与基于路由的值相结合等操作

    props: route => ({ query: route.query.id })
    props: route => ({ params: route.params.id})
  • 对于命名视图的路由,必须为每个命名视图定义props配置

    const routes = [{
    path: '/home',
    components: { default: Home, sidebar: Sidebar},
    props: { default: true, sidebar: true}
    }]

十、不同的历史模式

  • Hash模式:history: createWebHashHistory() SEO受影响
  • HTML5模式:history:createWbeHistory() 如果没有适当的服务器配置,就会404,需要在服务器上添加一个简单的回退路由
三、进阶-路由导航

一、导航守卫:vue-router提供的主要是通过跳转或取消的方式守卫导航。

  • 方式:全局、单个路由独享、组件

  • 全局前置守卫:beforeEnter:

    • 每个守卫都接收两个__参数__:to\from\next(可选)
    • 返回值 ①false:取消当前导航、②一个路由地址:通过一个路由地址跳转到不同的地址,类似于router.push()可配置,当前的 导航被中断然后进行一个新的导航。
    • next可选参数
  • 全局后置守卫:afterEach 不接受next函数也不会改变导航本身

  • 全局解析守卫:beforeResolve

  • 路由独享守卫:在routes中配置

  • 组件内的守卫 可用配置API:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

    • beforeRouteEnter:唯一可传递next回调守卫;解决不可访问this;
    • next()里的内容执行时机在组件mounted周期之前;
    • beforeRouteUpdate: 该组件复用时被调用

手写vue路由的更多相关文章

  1. 剖析手写Vue,你也可以手写一个MVVM框架

    剖析手写Vue,你也可以手写一个MVVM框架# 邮箱:563995050@qq.com github: https://github.com/xiaoqiuxiong 作者:肖秋雄(eddy) 温馨提 ...

  2. 手写 Vue 系列 之 Vue1.x

    前言 前面我们用 12 篇文章详细讲解了 Vue2 的框架源码.接下来我们就开始手写 Vue 系列,写一个自己的 Vue 框架,用最简单的代码实现 Vue 的核心功能,进一步理解 Vue 核心原理. ...

  3. 手写 Vue 系列 之 从 Vue1 升级到 Vue2

    前言 上一篇文章 手写 Vue 系列 之 Vue1.x 带大家从零开始实现了 Vue1 的核心原理,包括如下功能: 数据响应式拦截 普通对象 数组 数据响应式更新 依赖收集 Dep Watcher 编 ...

  4. 手写vue中v-bind:style效果的自定义指令

    自定义指令 什么是自定义指令 以 v- 为前缀,然后加上自己定义好的名字组成的一个指令就是自定义指令.为什么要有自定义指令呢?在有些时候,你仍然需要对普通的DOM元素进行底层的操作,这个时候就可以用到 ...

  5. 手写vue双向绑定数据

    来一张原理图: 实现思路: (1)绑定data 种的数据,为每个数据添加指令.通过Object,defineProperty() 来通知属性是否更改 (2) 找到每个DOM节点的指令.绑定事件.并绑定 ...

  6. 学习手写vue,理解原理

    class Compiler{ constructor(el,vm){ // 判断el属性 是不是 一个元素, 如果不是就获取 this.el = this.isElementNode(el)?el: ...

  7. 手写vue observe数据劫持

    实现代码: class Vue { constructor(options) { //缓存参数 this.$options = options; //需要监听的数据 this.$data = opti ...

  8. 手写 Vue2 系列 之 编译器

    前言 接下来就要正式进入手写 Vue2 系列了.这里不会从零开始,会基于 lyn-vue 直接进行升级,所以如果你没有阅读过 手写 Vue 系列 之 Vue1.x,请先从这篇文章开始,按照顺序进行学习 ...

  9. 基于vue手写tree插件那点事

    目录 iview提供的控件 手写控件 手写控件扩展 手写控件总结 # 加入战队 微信公众号 主题 Tree树形控件在前端开发中必不可少,对于数据的展示现在网站大都采取树形展示.因为大数据全部展示出来对 ...

随机推荐

  1. 单例模式 | C++ | Singleton模式

    Singleton 模式 单例模式(Singleton Pattern)是 C++/Java等语言中最简单的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 这种模式实 ...

  2. 记离线缓存(manifest)一大坑,断定其只适用于静态网站或离线应用

    今天看了离线缓存(manifest)方面的资料,兴冲冲地就想给自己的网站用上.待我把代码都写好部署上服务器,并测试过OK的时候,在SegmentFault刷了一把manifest方面的问答,才发现这个 ...

  3. 编写大型项目web页面 从写web登陆页面开始

    web页面搭建需要准备什么工具 首先我们会和设计师沟通 我们需要一些检验设计的工具 ps 自动裁图 自动测量工具 (我这里安利一下一个工具 我用的cutterman) sketch 可以使用阿里的工具 ...

  4. 第二次课堂练习-连接hbase数据库-页面展示

    图片来源:中国知网 页面来源:中国科学院文献情报中心-科技查新平台 如有侵权,请评论留言

  5. 【Android开发】URL[] 转成 bitmap[]

    public static Bitmap[] getBitmapFromURL(String[] path) throws MalformedURLException { Bitmap[] b = n ...

  6. js 图片上传给后台的3种格式

    1. file格式 (创建formData来完成file上传) 我们的接口需求: 代码: <input type="file" id="imgfile" ...

  7. vux+vue-cli3.0坑

    最近开发了项目使用了vue-cli3.0+vux搭建的项目,现在总结遇到的问题: 环境:github vux有关于vue-cli3.0以及vux已经搭建好的脚手架vux-cli3链接 一:如下报错 解 ...

  8. Windows中Nginx配置nginx.conf不生效解决方法

    转:https://lucifer.blog.csdn.net/article/details/83860644?utm_medium=distribute.pc_relevant.none-task ...

  9. nfs客户端的一次处理

    为什么要说这个呢,由于节点环境不一致,导致在重建pod时,我们暂且叫该pod为 cxpod,cxpod所在宿主机出现了问题现象如下:一.cxpod始终处于创建中 ContainerCreating [ ...

  10. 异步任务-springboot

    异步任务-springboot 异步:异步与同步相对,当一个异步过程调用发出后,调用者在没有得到结果之前,就可以继续执行后续操作.也就是说无论异步方法执行代码需要多长时间,跟主线程没有任何影响,主线程 ...