路由实例
router/index.js
import Vue from 'vue'
import Router from '../demoTools/kVue-router/router'
// import Router from 'vue-router'
Vue.use(Router)
/* 初始路由-静态路由 */
const routes = [
{
path: '/',
component: () => import('@/views/index.vue')
},
{
path: '/goods',
component: () => import('@/views/goods.vue'),
redirect: '/info',
children: [
{
path: '/shopCar',
component: () => import('@/views/shopCar.vue')
},
{
path: '/orders',
component: () => import('@/views/orders.vue')
}
]
}
]
const router = new Router({
mode: 'hash',
routes
})
export default router
// vue-router
// 保存vue的构造函数 插件中需要用到
import krouterView from './krouter-view'
import krouterLink from './krouter-link'
let Vue
class VueRouter {
constructor(options) {
// 将new传入的属性存储
this.$options = options
// 定义一个存储当前路由变量
// currentRouter需要是响应式数据 可以实时变化 以方便router-view的函数再次执行
// vue提供响应式的api
this.currentRouter = window.location.hash.slice(1) || '/'
// match匹配
Vue.util.defineReactive(this, 'matched', [])
this.match()
// 监听hash的变化
window.addEventListener('hashchange', this.onchange.bind(this))
}
onchange() {
// window.location.hash 获取的值 #/home
this.currentRouter = window.location.hash.slice(1)
// 清空路由数组
this.matched = []
this.match()
}
match(routes) {
routes = routes || this.$options.routes
// 递归遍历
for (const route of routes) {
// 处理路由完全匹配
if (
route.path === '/' &&
this.currentRouter.indexOf(route.path) !== -1
) {
this.matched.push(route)
}
// about/info
if (
route.path !== '/' &&
this.currentRouter.indexOf(route.path) !== -1
) {
this.matched.push(route)
if (route.children) {
this.match(route.children)
}
return
}
}
}
}
// Vue.use(VueRouter)其实就是调用的install的方法
// Vue.use调用会传入_vue参数
VueRouter.install = function(_vue) {
Vue = _vue
// 挂载$router属性
// this.$router.push()
// 全局混入方式实现
// 全局混入目的:延迟下面逻辑到router创建完毕并且附加到选项上时才执行
Vue.mixin({
beforeCreate() {
// 每个组件调用都会执行
/* 判断
new Vue({
router,
render: h => h(App)
}).$mount('#app');
是否有router属性 存在的话挂载在Vue
*/
if (this.$options.router) {
Vue.prototype.$router = this.$options.router
}
}
})
// 注册并且实现组件router-view
Vue.component('router-link', krouterLink)
// 注册并且实现组件router-link
Vue.component('router-view', krouterView)
}
export default VueRouter
krouter-view.js
/* 路由嵌套实现思路
1、标记路由嵌套层数
2、路由匹配获取代表深度层级的matched数组
*/
export default {
// 获取当前路由对应组件
render(h) {
// 标记当前router-view深度
this.$vnode.data.routerView = true
// 路由嵌套层数计算
let depath = 0
let parent = this.$parent
while (parent) {
const vnodeData = parent.$vnode && parent.$vnode.data
if (vnodeData) {
if (vnodeData.routerView) {
depath++
}
}
parent = parent.$parent
}
// 定义存储组件变量
let components = null
// 查找到对应组件赋值
console.log(depath, '基层')
const route = this.$router.matched[depath]
console.log(route, '哈哈')
if (route) {
components = route.component
}
// 渲染对应组件
return h(components)
}
}
krouter-link.js
export default {
props: {
to: {
type: String,
required: true
}
},
render(h) {
// <a href='to'>xxx</a>
// this.$slots.default 获取默认插槽内容 获取home about
// hash模式需要 '#'
// 虚拟dom设置a标签属性和值
return h('a', { attrs: { href: '#' + this.to } }, this.$slots.default)
}
}
871

被折叠的 条评论
为什么被折叠?



