From 49419605fd96e686ee1b76cd01c55e8f129a902d Mon Sep 17 00:00:00 2001 From: Eduardo San Martin Morote Date: Wed, 5 Jun 2019 18:08:09 +0200 Subject: [PATCH] wip --- explorations/html5.ts | 76 +++++++++++++++++++++++------------------- src/components/View.ts | 32 ++++++++++++++++++ src/index.ts | 45 ++++++++++++++++++++++++- 3 files changed, 117 insertions(+), 36 deletions(-) create mode 100644 src/components/View.ts diff --git a/explorations/html5.ts b/explorations/html5.ts index f10bd5fd..05f1770e 100644 --- a/explorations/html5.ts +++ b/explorations/html5.ts @@ -1,4 +1,4 @@ -import { Router, HTML5History } from '../src' +import { Router, HTML5History, plugin } from '../src' import { RouteComponent } from '../src/types' import Vue from 'vue' @@ -25,7 +25,7 @@ const GuardedWithLeave: RouteComponent = { }, } -const r = new Router({ +const router = new Router({ history: new HTML5History(), routes: [ { path: '/', component }, @@ -55,6 +55,8 @@ const r = new Router({ ], }) +const r = router + r.beforeEach((to, from, next) => { console.log(`Guard from ${from.fullPath} to ${to.fullPath}`) if (to.params.id === 'no-name') return next(false) @@ -105,43 +107,47 @@ async function run() { path: '/', }) - await r.push({ - name: 'user', - params: { - id: '6', - }, - }) - - await r.push({ - name: 'user', - params: { - id: '5', - }, - }) - - try { - await r.push({ - params: { - id: 'no-name', - }, - }) - } catch (err) { - console.log('Navigation aborted', err) - } - - await r.push({ - hash: '#hey', - }) - - await r.push('/children') - await r.push('/children/a') - await r.push('/children/b') - await r.push({ name: 'a-child' }) + // await r.push({ + // name: 'user', + // params: { + // id: '6', + // }, + // }) + + // await r.push({ + // name: 'user', + // params: { + // id: '5', + // }, + // }) + + // try { + // await r.push({ + // params: { + // id: 'no-name', + // }, + // }) + // } catch (err) { + // console.log('Navigation aborted', err) + // } + + // await r.push({ + // hash: '#hey', + // }) + + // await r.push('/children') + // await r.push('/children/a') + // await r.push('/children/b') + // await r.push({ name: 'a-child' }) } +// use the router +Vue.use(plugin) + window.vm = new Vue({ el: '#app', - // router, + // @ts-ignore + router, data: { message: 'hello', }, diff --git a/src/components/View.ts b/src/components/View.ts new file mode 100644 index 00000000..0837e195 --- /dev/null +++ b/src/components/View.ts @@ -0,0 +1,32 @@ +// @ts-nocheck + +import { FunctionalComponentOptions } from 'vue' + +const View: FunctionalComponentOptions = { + name: 'RouterView', + functional: true, + + render(_, { children, parent, data }) { + // used by devtools to display a router-view badge + // @ts-ignore + data.routerView = true + + // directly use parent context's createElement() function + // so that components rendered by router-view can resolve named slots + const h = parent.$createElement + // @ts-ignore + const route = parent.$route + + // TODO: support nested router-views + const matched = route.matched[0] + + // render empty node if no matched route + if (!matched) return h() + + const component = matched.component + + return h(component, data, children) + }, +} + +export default View diff --git a/src/index.ts b/src/index.ts index 61e7511b..c11583cf 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,47 @@ import { Router } from './router' import { HTML5History } from './history/html5' +import { PluginFunction } from 'vue' +import View from './components/View' -export { Router, HTML5History } +const plugin: PluginFunction = Vue => { + Vue.mixin({ + beforeCreate() { + // @ts-ignore + if (this.$options.router) { + // @ts-ignore + this._routerRoot = this + // @ts-ignore + this._router = this.$options.router + // this._router.init(this) + // @ts-ignore + Vue.util.defineReactive(this, '_route', this._router.currentRoute) + } else { + // @ts-ignore + this._routerRoot = (this.$parent && this.$parent._routerRoot) || this + } + }, + }) + + Object.defineProperty(Vue.prototype, '$router', { + get() { + return this._routerRoot._router + }, + }) + + Object.defineProperty(Vue.prototype, '$route', { + get() { + return this._routerRoot._route + }, + }) + + // @ts-ignore + Vue.component('RouterView', View) + // Vue.component('RouterLink', Link) + + const strats = Vue.config.optionMergeStrategies + // use the same hook merging strategy for route hooks + strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = + strats.created +} + +export { Router, HTML5History, plugin } -- 2.39.5