入口
package.json
{
...
module:'dist/vue-router.esm.js'
...
scripts:{
...
build:'node build/build.js'
}
}
build.js
const configs = require('./configs')
build(configs)
function build(builds){
let built = 0
const total = builds.length
const next = () => {
buildEntry(builds[built]).then(() => {
built ++
if(built < total){
next()
}
}).catch(logError)
}
next()
}
config.js
module.exports = [
...
{file: resolve('dist/vue-router.esm.js'), format: 'es'}
...
].map(getConfig)
function getConfig(opts){
const config = {
input:{
input: resolve('src/index.js')
...
}
...
}
}
VueRouter
export default class VueRouter{
static install
static version
static isNavigationFailure
static NavigationFailureType
static START_LOCATION
app,apps,ready,readyCbs,options,mode,history,matcher,fallback,beforeHooks,resolveHooks,afterHooks
constuctor(options = {}){
this.app = null
this.apps = []
this.options = options
this.beforeHooks = []
this.resolveHooks = []
this.afterHooks = []
this.matcher = createMatcher(options.routes || [],this)
let mode = options.mode || 'hash'
this.fallback = mode === 'history' && !supportsPushState && options.fallback !== false
if(this.fallback){
mode = 'hash'
}
if(!inBrowser){
mode = 'abstract'
}
this.mode = mode
switch(mode){
case 'history':
this.history = new HTML5History(this,options.base)
break
case 'hash':
this.history = new HashHistory(this,options.base)
break;
case 'abstract':
this.history = new AbstractHistory(this,options.base)
break
default:
if(process.env.NODE_ENV !== 'production'){
assert(false,`invalid mode ${mode}`)
}
}
}
match(raw,current,redirectedFrom){
return this.matcher.match(raw,current,redirectedFrom)
}
get currentRoute(){
return this.histroy && this.history.current
}
init(app){
process.env.NODE_ENV !== 'production' && assert(install.installed,`not installed. Make sure to call Vue.use(VueRouter) before creating root instance`)
this.apps.push(app)
app.$once('hook:destroyed',() => {
const index = this.apps.indexOf(app)
if(index > -1) this.apps.splice(index,1)
if(this.app === app) this.app = this.apps[0] || null
if(!this.app) this.history.teardown()
})
if(this.app){
return
}
this.app = app
const history = this.history
if(history instanceof HTML5History || history instanceof HashHistory){
const handleInitialScroll = routeOrError => {
const from = history.current
const expectScroll = this.options.scrollBehavior
const supportScroll = supportPushState && expectScroll
if(supportScroll && 'fullPath' in routeOrError){
handleScroll(this,routeOrError,from,false)
}
}
const setupListeners = routeOrError => {
history.setupListeners()
handleInitialScroll(routeOrError)
}
history.transitionTo(history.getCurrentLocation(),setupListeners,setupListeners)
}
history.listen(route => {
this.apps.forEach(app => {
app._route = route
})
})
}
beforeEach(fn){
return registerHook(this.beforeHooks,fn)
}
beforeResolve(fn){
return registerHook(this.resolveHooks,fn)
}
afterEach(fn){
return registerHook(this.afeterHooks,fn)
}
onReady(cb,errorCb){
this.history.onReady(cb,errorCb)
}
onError(errorCb){
this.history.onError(errorCb)
}
push(location,onComplete,onAbort){
if(!onComplete && !onAbort && typeof Promise !== 'undefied'){
return new Promise((resolve,reject) =>{
this.history.push(location,resolve,reject)
})
}else{
this.history.push(location,onComplete,onAbort)
}
}
replace(location,onComplete,onAbort){
if(!onComplete && !onAbort && typeof Promise !== 'undefied'){
return new Promise((resolve,reject) => {
this.history.replace(location,resolve,reject)
})
}else{
this.history.replace(location,onComplete,onAbort)
}
}
go(n){
this.history.go(n)
}
back(){
this.go(-1)
}
forward(){
this.go(1)
}
getMatchedComponent(to){
const route = to ? to.matched ? to : this.resolve(to).route : this.currentRoute
if(!route){
return []
}
return [].concat.apply([],route.matched.map(m => Object.keys(m.components).map(key => m.components[key])))
}
resolve(to,current,append){
current = current || this.history.current
const location = normalizeLocation(to,current,append,this)
const route = this.match(location,current)
const fullPath = route.redirectedFrom || route.fullPath
const base = this.history.base
const href = createHref(base,fullPath,this.mode)
return {
location,
route,
href,
normalizedTo:location,
resolved:route
}
}
getRoutes(){
return this.matcher.getRoutes()
}
addRoute(parentOrRoute,route){
this.matcher.addRoute(parentOrRoute,route)
if(this.histroy.current !== START){
this.history.transitonTo(this.history.getCurrentLocation())
}
}
addRoutes(parentOrRoute,route){
this.matcher.addRoutes(parentOrRoute,route)
if(this.history.current !== START){
this.history.transitionTo(this.history.getCurrentLocation())
}
}
}
...
if(inBrowser && window.Vue){
window.Vue.use(VueRouter)
}