根据vue-router实现简易版router路由

快深夜了,简单写点东西,不然还真睡不着觉哒 ~ ~

写什么好呢?前些天看了下vue-router的源码结构,理解了下 router-view 和 router-link 的基本实现;所以简单写一个vue-router的小功能版本,实现基本的路由切换,就可以了;好吧,接下来我们开始吧 ~~

一、最终路由切换展示

二、使用方式

其使用方式与原生的使用方式几乎一致,也有部分不同,由于并非使用install()方法实现,所以引入的方法并不需要Vue.use()

1. 在main.js中引入

import router from '@/custom-router/router.js'

2. 在router.js中定义路由配置

import Vue from 'vue';
import Router from './router-script.js';

const Home = { template: '<div>首页的内容</div>' };
const Music = { template: '<div>音乐详情页</div>' };
const Movie = { template: '<div>电影详情页</div>' };

const routes = [
    { path: '/', component: Home },
    { path: '/music', component: Music },
    { path: '/movie', component: Movie }
];

const router = new Router(Vue,{
  routes
})

export default router

三、核心代码实现

1. 定义一个 Router 类

export default class Router {
  
  constructor (Vue, options) {
     //...
  }

  //...

}

2. 初始化绑定onhashchange、onload事件

  // 绑定事件
  init () {
    window.addEventListener('load', this.onHashChange.bind(this), false);
    window.addEventListener('hashchange', this.onHashChange.bind(this), false);
  }

  // 获取当前 hash 串
  getHash () {
    return window.location.hash.slice(1) || '/';
  }

  // 设置当前路径
  onHashChange () {
    this.app.current = this.getHash();
  }

3. 路由组件映射

  // 路由映射表
  createRouteMap (options) {
    options.routes.forEach(item => {
      this.routeMap[item.path] = item.component;
    });
  }

4. 全局注册 router-link 组件、router-view组件

// 注册组件
initComponent (Vue) {

  Vue.component('router-link', {
    props: {
      to: String
    },
    template: `<a :href="'#'+to"><slot></slot></a>`
  });

  const self = this;
  
  Vue.component('router-view', {
    render (h) {
      var component = self.routeMap[self.app.current];
      return h(component);
    }
  });
  
}

5. 获取当前router-view要渲染对应的组件结构

  // 设置当前路径
  onHashChange () {
    this.app.current = this.getHash();
  }

 

四、完整代码结构

 

export default class Router {
  
  constructor (Vue, options) {
    this.$options = options;
    this.routeMap = {};
    this.app = new Vue({
      data: {
        current: '/'
      }
    });

    this.init();
    this.createRouteMap(this.$options);
    this.initComponent(Vue);
  }

  // 绑定事件
  init () {
    window.addEventListener('load', this.onHashChange.bind(this), false);
    window.addEventListener('hashchange', this.onHashChange.bind(this), false);
  }

  // 路由映射表
  createRouteMap (options) {
    options.routes.forEach(item => {
      this.routeMap[item.path] = item.component;
    });
  }

  // 注册组件
  initComponent (Vue) {

    Vue.component('router-link', {
      props: {
        to: String
      },
      template: `<a :href="'#'+to"><slot></slot></a>`
    });

    const self = this;
    
    Vue.component('router-view', {
      render (h) {
        var component = self.routeMap[self.app.current];
        return h(component);
      }
    });
    
  }

  // 获取当前 hash 串
  getHash () {
    return window.location.hash.slice(1) || '/';
  }

  // 设置当前路径
  onHashChange () {
    this.app.current = this.getHash();
  }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的小英短

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值