Skip to content

Commit

Permalink
global before/after hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Jun 10, 2015
1 parent e6f94d7 commit 0a146d0
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 12 deletions.
11 changes: 11 additions & 0 deletions example/example.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,4 +99,15 @@ router.redirect({
'/info': '/about'
})

router.beforeEach(function (from, to) {
if (to.path === '/forbidden') {
alert('this route is forbidden by a global before hook')
return false
}
})

router.afterEach(function (from, to) {
console.log('global after')
})

router.start(App, '#app')
1 change: 1 addition & 0 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ <h1>App Header</h1>
<a v-link="/inbox/message/123">inbox</a>
<a v-link="/about">about</a>
<a v-link="/user/1234">user</a>
<a v-link="/forbidden">forbidden</a>
<router-view class="test" v-transition="test" transition-mode="out-in"></router-view>
</div>

Expand Down
91 changes: 82 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
var Recognizer = require('route-recognizer')
var hasPushState = typeof history !== 'undefined' && history.pushState
var installed = false
var Vue

Expand All @@ -13,14 +12,28 @@ var Vue
*/

function Router (options) {
options = options || {}

// Vue instances
this.app = null
this._children = []

// route recognizer
this._recognizer = new Recognizer()

// state
this._started = false
this._currentPath = null
this._notFoundHandler = null
this._root = null
this._hasPushState = hasPushState
this._currentRoute = { path: '' }

// feature detection
this._hasPushState = typeof history !== 'undefined' && history.pushState

// global handler/hooks
this._notFoundHandler = options.notFound || null
this._beforeEachHook = options.beforeEach || null
this._afterEachHook = options.afterEach || null

// resolve root path
var root = options && options.root
if (root) {
// make sure there's the starting slash
Expand All @@ -29,9 +42,13 @@ function Router (options) {
}
// remove trailing slash
this._root = root.replace(/\/$/, '')
} else {
this._root = null
}
this._hashbang = !(options && options.hashbang === false)
this._pushstate = !!(hasPushState && options && options.pushstate)

// mode
this._hashbang = options.hashbang !== false
this._pushstate = !!(this._hasPushState && options.pushstate)
}

/**
Expand Down Expand Up @@ -109,6 +126,26 @@ p.redirect = function (map) {
// use another recognizer to recognize redirects
}

/**
* Set global before hook.
*
* @param {Function} fn
*/

p.beforeEach = function (fn) {
this._beforeEachHook = fn
}

/**
* Set global after hook.
*
* @param {Function} fn
*/

p.afterEach = function (fn) {
this._afterEachHook = fn
}

/**
* Navigate to a given path.
* The path is assumed to be already decoded, and will
Expand Down Expand Up @@ -140,6 +177,18 @@ p.go = function (path, options) {
}
}

/**
* Short hand for replacing current path
*
* @param {String} path
*/

p.replace = function (path) {
this.go(path, {
replace: true
})
}

/**
* Start the router.
*
Expand Down Expand Up @@ -273,10 +322,12 @@ p._addRoute = function (path, config, segments) {
*/

p._match = function (path) {
if (path === this._currentPath) {

var currentRoute = this._currentRoute
if (this.app && path === currentRoute.path) {
return
}
this._currentPath = path

// normalize against root
if (
this._pushstate &&
Expand All @@ -285,7 +336,9 @@ p._match = function (path) {
) {
path = path.slice(this._root.length)
}

var matched = this._recognizer.recognize(path)

// aggregate params
var params
if (matched) {
Expand All @@ -298,6 +351,7 @@ p._match = function (path) {
return prev
}, {})
}

// construct route context
var route = {
path: path,
Expand All @@ -307,19 +361,38 @@ p._match = function (path) {
_matchedCount: 0,
_router: this
}

// check gloal before hook
if (this._beforeEachHook) {
var res = this._beforeEachHook.call(null, currentRoute, route)
if (res === false) {
this.replace(currentRoute.path)
return
}
}

if (!this.app) {
// initial render
this.app = new this._appConstructor({
el: this._appContainer,
data: {
route: route
}
})
} else {
// route change
this.app.route = route
this._children.forEach(function (child) {
child.route = route
})
}

// check global after hook
if (this._afterEachHook) {
this._afterEachHook.call(null, currentRoute, route)
}

this._currentRoute = route
}

/**
Expand Down
4 changes: 1 addition & 3 deletions src/view.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,7 @@ module.exports = function (Vue) {
if (route._router._hasPushState) {
history.back()
} else if (previousRoute) {
route._router.go(previousRoute.path, {
replace: true
})
route._router.replace(previousRoute.path)
}
return
}
Expand Down

0 comments on commit 0a146d0

Please sign in to comment.