前端路由和后端路由
- 后端路由-mvc:输入url》请求发送到服务器》服务器解析请求的路径》获取对应页面》返回出去
- 前端路由-spa:输入url》js解析地址》找到对应地址的页面》执行页面生成的js》看到页面
vue-router工作流程
- url改变》触发监听事件》改变vue-router里面的current变量》监视current变量的监视者》获取新的组件》render新组件
路由模式
hash
- #号后面的内容
- 可以通过location.hash拿到
- 通过onhashchange监听改变
- 只会把路由给到服务器,并不会发生跳转
history
- 通过location.pathname来获取路径
- 通过onpopstate监听history的改变
Vue.use
- 如果传进去的是一个函数的话,就执行这个函数
- 如果函数/对象的install是一个方法的话,就会优先执行这个方法,而不去执行本身这个函数
function a() { console.log('函数本身的方法'); } a.install = function () { console.log('install的方法'); } Vue.use(a)//install的方法复制代码
- Vue.use()会向install这个方法传入一个vue的类(都是相等的都是Vue的类)
- 这个类下面有个mixin的方法(可以向vue实例混入各种data,methods或者各种,相当于全局引入)
a.install = function (Vue) { Vue.mixin({ data(){ return{ //都可以在任何组件调用这个name name:"zxx" } } }) }复制代码
- 最重要的还是可以混入生命周期函数,可以拿到各个组件的this
//可以拿到各个组件实例的this created(){ console.log(this); }复制代码
- vue有一系列util,下面有一些方法
- 而且这些方法都是暴露出来的可以直接使用
- 其中defineReactive就是数据响应原理的方法
//vue外面的对象 var test={ testa:1 } //进行数据绑定 Vue.util.defineReactive(test,'testa') //2秒之后改变 setTimeout(function(){ test.testa=333 },2000) a.install = function (Vue) { Vue.mixin({ //混入下面的组件 beforeCreate(){ this.test=test }, created(){ } }) }复制代码
- 放在beforeCreate是因为这时候this还没有创建,放到created的话,this已经创建了
- 单其实测试发现,放在2个里面都一样的,都可以正常运行
代码
class History { constructor() { this.current = null } } class VueRouter { constructor(options) { this.mode = options.mode || 'hash'; this.routes = options.routes || []; this.history = new History; this.routesMap = this.createMap(this.routes) this.init() } init() { if (this.mode === 'hash') { //如果为false的话,那么执行后面的语句,改成/ //如果为true的话,执行'',不改变任何东西 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 { location.pathname ? '' : location.pathname = '/'; window.addEventListener('load', () => { this.history.current = location.pathname }) window.addEventListener('popstate', () => { this.history.current = location.pathname }) } } createMap(routes) { return routes.reduce((prev, item) => { prev[item.path] = item.component return prev }, {}) } } VueRouter.install=function(Vue){ Vue.mixin({ //全局混入了router实例,并且做了响应式绑定 beforeCreate() { if (this.$options && this.$options.router) { this._root = this; this._router = this.$options.router Vue.util.defineReactive(this, 'current', this._router.history) } else { this._root = this.$parent._root } } }) Vue.component('router-view', { render(h) { let current = this._self._root._router.history.current; console.log(current); let routesMap = this._self._root._router.routesMap console.log(routesMap); return h(routesMap[current]) } } ) } export default VueRouter复制代码