手动封装—Vue路由

src/router/index.js

// 使用插件的流程
// 1.引入vue
import Vue from 'vue'
// 2.引入插件
import lyRouter from '../ly-router'
import Home from '../components/Home.vue'
import List from '../components/List.vue'
// 3.Vue.use使用当前插件
// 找install方法  
// 如果这个插件是一个函数  就会被当做install方法  如果是对象 就必须要有install方法
Vue.use(lyRouter)
// 4.使用 export default 来导出当前路由配置项
export default new lyRouter({
    routes:[
        {
            path:"/",
            component:Home,
        },
        {
            path:"/list",
            component:List,
        }
    ]
})

src/ly-router/index.js

let Vue

class lyRouter{
    static install(_Vue){
        // 将Vue.use传递的Vue构造函数赋值给全局对象
        // _Vue是构造函数
        Vue = _Vue
        // 在这里调用init方法  原因:在这里路由会被挂载到Vue身上
        // console.log(_Vue);
        // console.log(this.$options);
        //混入
        Vue.mixin({
            //在组件初始化的时候在进行路由的实例化
            beforeCreate() {
               if(this.$options.router){
                    this.$options.router.init();
               }
            },
        })
    }
    constructor(options){
        //接受路由的配置项参数
        this.$options = options
        //创建路由表对象
        this.routesMap = {}
        // 默认的根路径
        this.app = new Vue({
            data:{
                //data中的数据是响应式的  因此只要curr发生改变那么组件默认也会发生改变
                curr: this.getHash() || "/"
            }
        })
        // this.init()
    }
    // 路由初始化
    init(){
        // 1.路由监听事件
        this.bindEvent()
        // 2.创建路由表对象
        this.createRoutesMap()
        // 3.创建组件
        this.renderComponent()
    }
    bindEvent(){
        //页面初次加载的时候也要监听路由的变换
        window.addEventListener("load",this.handleBindEventChange.bind(this))
        //hash值发生改变的时候监听路由的变换
        window.addEventListener("hashchange",this.handleBindEventChange.bind(this))
    }
    handleBindEventChange(){
        //当hash中发生改变的时候获取到hash值 赋值给this.app.curr这个响应式对象保证组件的更新
       var hash = this.getHash() || "/"
       this.app.curr = hash
       // console.log(this.app.curr);
    }
    getHash(){
        //获取hash值
        var hash = window.location.hash.slice(1)
        return hash
    }
    createRoutesMap(){
        //创建路由表对象,根据path的路径来决定渲染的组件
        this.$options.routes.forEach((item) => {
            this.routesMap[item.path] = item
        })
        console.log(this.routesMap);
    }
    renderComponent(){
        //注册 router-view组件  
        Vue.component("router-view",{
            render:h=>{
                // 这句话不能放在外面 render在创建虚拟dom的时候  创建的不是最新的
                //注意:这句话一定要写在内部  因为组件注册只会注册一次  当this.app.curr发生改变的时候讲h函数重新执行
                var component = this.routesMap[this.app.curr].component
                return h(component)
            }
        })
        //注册router-link组件
        Vue.component("router-link",{
            render(h){
                return h("a",{
                    attrs:{
                        href:"#"+this.to
                    }
                },this.$slots.default)
            },
            props:{
                to:{
                    type:String
                }
            }
        })
    }
}

export default lyRouter

App.vue

<template>
<!-- 程序入口vue组件 -->
  <div id="app">
      <router-link to="/">首页</router-link>
      <router-link to="/list">列表</router-link>
      <router-view></router-view>
  </div>
</template>

<script>
export default {
  name: 'App'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

main.js

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
// 程序入口文件
import Vue from 'vue'
import App from './App'
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render:h => h(App),
}).$mount('#app')

components/home.vue

<template>
  <div>
      <h2>home</h2>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>

components/list.vue

<template>
  <div>
      <h2>list</h2>
  </div>
</template>

<script>
export default {

}
</script>

<style>

</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值