We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我们先来看下vue-router的基本用法
vue-router
// route/index.js import VueRouter from 'vue-router' import Vue from 'vue' import Home from './../views/Home.vue' import About from './../views/About.vue' Vue.use(VueRouter) export default new VueRouter({ mode: 'hash', routes: [ { path: '/home', component: Home }, { path: '/about', component: About }, ] })
然后我们需要在App.vue里面添加几个组件
App.vue
<template> <div id="app"> <router-link to="/home">首页</router-link> <router-link to="/about">关于</router-link> <router-view></router-view> </div> </template> <script> export default { name: 'app', mounted() { console.log(this.$router, this.$route) } } </script>
我们还可以发现vue-ruter帮我们提供了2个属性$router和$route
vue-ruter
$router
$route
因为vue-router和react-router的原理基本一样,是基于hash或者H5 api来实现,这里就直接上代码了
react-router
class HistoryRoute { constructor() { this.current = null //存放当前的路径 } } class VueRouter { constructor(options) { this.mode = options.mode || 'hash' this.routes = options.routes || [] this.routesMap = this.createMap(this.routes) this.history = new HistoryRoute() this.init() //初始化路由 } init() { // 判断当前是什么模式 if (this.mode === 'hash') { // 先判断用户打开时候有没hash 没有的话就跳转到 #/ location.hash ? '' : location.hash = '/' window.addEventListener('load', () => { this.history.current = location.hash.slice(1) }) window.addEventListener('hashchange', () => { this.history.current = location.hash.slice(1) }) } else { //history location.pathname ? '' : location.pathname = '/' window.addEventListener('load', () => { this.history.current = location.pathname }) window.addEventListener('popstate', () => { //监听浏览器前进后退 this.history.current = location.pathname }) } } createMap(routes) { // 将传递的路由表进行改造成{'/home':Home, '/about':About} return routes.reduce((prev, next) => { prev[next.path] = next.component return prev }, {}) } } VueRouter.install = (Vue) => { Vue.mixin({ beforeCreate() { if (this.$options && this.$options.router) { // 根组件 this._root = this this._router = this.$options.router //如果history中的current变化,也会刷新视图 Vue.util.defineReactive(this, 'xx', this._router.history) } else { // 因为组件的渲染顺序是 父子孙 所以子和孙都是可以拿到对应的父组件 this._root = this.$parent._root this._router = this.$parent._router } Object.defineProperty(this, '$router', { get() { return this._root._router } }) Object.defineProperty(this, '$route', { get() { return { current: this._root._router.history.current } } }) } }) Vue.component('router-link', { props: { to: String }, render(h) { const mode = this._self._root._router.mode return <a href={mode === 'hash' ? `#${this.to}` : this.to}> {this.$slots.default} </a> } }) Vue.component('router-view', { render(h) { const current = this._self._router.history.current const routesMap = this._self._router.routesMap return h(routesMap[current]) } }) } export default VueRouter
那我们接下来总结几个难点吧
我们使用vue-router的时候用的是插件的用法,即Vue.use(xxx), 所以我们需要提供一个install方法
Vue.use(xxx)
install
如果做到多个组件共享一个路由实例呢,可以根据我们组件的渲染顺序父子孙,先给根组件定义属性,然后子孙通过$parent 来取
$parent
vue中通过this.$slots.defaule来拿到插槽的默认内容,react中是this.props.children
this.$slots.defaule
this.props.children
Vue.component()里面通过this._self拿到当前组件
Vue.component()
this._self
实现history中的current变化,也会刷新视图,源码中是通过 Vue.util.defineReactive(this, 'xx', this._router.history)这个方法实现的
history
current
Vue.util.defineReactive(this, 'xx', this._router.history)
The text was updated successfully, but these errors were encountered:
No branches or pull requests
实现一个vue-router
vue-router基本用法
我们先来看下
vue-router
的基本用法然后我们需要在
App.vue
里面添加几个组件我们还可以发现
vue-ruter
帮我们提供了2个属性$router
和$route
实现mini的vue-router
因为
vue-router
和react-router
的原理基本一样,是基于hash或者H5 api来实现,这里就直接上代码了那我们接下来总结几个难点吧
我们使用
vue-router
的时候用的是插件的用法,即Vue.use(xxx)
, 所以我们需要提供一个install
方法如果做到多个组件共享一个路由实例呢,可以根据我们组件的渲染顺序父子孙,先给根组件定义属性,然后子孙通过
$parent
来取
vue中通过
this.$slots.defaule
来拿到插槽的默认内容,react中是this.props.children
Vue.component()
里面通过this._self
拿到当前组件实现
history
中的current
变化,也会刷新视图,源码中是通过Vue.util.defineReactive(this, 'xx', this._router.history)
这个方法实现的The text was updated successfully, but these errors were encountered: