Introdução ao princípio do Vue-Router, escrevendo seu próprio Vue-Router

Pré-conhecimento

Dois modos de roteamento front-end


  1. O conteúdo por trás de # no URL do modo Hash é usado como o endereço do caminho.
    Ouça o evento HashChange.
    Encontre o componente correspondente com base no endereço de roteamento atual e renderize novamente
  2. Modo de histórico
    Altere a barra de endereço através do método history.pushState (),
    ouça os eventos popstate,
    encontre o componente correspondente com base no endereço de roteamento atual e renderize novamente

Preparação de roteamento manuscrito

Crie um novo projeto vue sem vue-router

Crie um novo arquivo relacionado ao roteador no projeto

  1. Crie uma nova pasta de rota e crie um novo index.js na pasta para armazenar regras de roteamento
import Vue from 'vue'
import VueRouter from '../vuerouter'
//从我们自己的router中导入VueRouter
import Index from '../components/Index.vue'
Vue.use(VueRouter)

const routes = [
    {
    
    
        path:'/',
        name:'Index',
        component : Index
    },
    {
    
    
        path:'/about',
        name:'about',
        component: ()=> import('@/views/about.vue')
    },
    {
    
    
        path:'/home',
        name:'home',
        component: ()=> import('@/views/home.vue')
    },
]
const router = new VueRouter({
    
    
    mode:'history',
    base: process.env.BASE_URL,
    routes
})

export default router
  1. Crie uma nova pasta vuerouter e crie um novo index.js na pasta para armazenar o código do roteador escrito à mão
    Insira a descrição da imagem aqui

  2. Não se esqueça de citar o roteador que escrevemos em main.js

import Vue from 'vue'
import App from './App.vue'
import router from './route'


Vue.config.productionTip = false

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

Comece a escrever à mão Vue-Router

Em primeiro lugar, é necessário esclarecer o que fazer manuscrito Vue-roteador. A figura a seguir é um diagrama de classes do Vue-roteador, que registra em detalhes quais atributos e métodos VueRouter precisa
Insira a descrição da imagem aqui

opções: registrar o objeto passado no construtor (existem regras de roteamento neste objeto)
routeMap: é um objeto usado para registrar a correspondência entre o endereço de roteamento e o componente, as regras de roteamento serão analisadas no routeMap nos
dados futuros : é um objeto, há um atributo current, que é usado para registrar o endereço de roteamento atual.Aqui, os dados são usados ​​para implementar um objeto responsivo.

implementação do método de instalação

Por meio de _ no diagrama de classe, você pode descobrir que instalar é um método estático

let _Vue = null

export default class VueRouter {
    
    

    static install (Vue) {
    
    
        //判断当前插件是否被安装
        if(VueRouter.install.installed){
    
    
            return;
        }
        VueRouter.install.installed = true

        // 把vue构造函数记录到全局变量
        _Vue = Vue
        // 把创建vue实例的时候传入的router对象注入到Vue实例上
        //混入 mixed
        _Vue.mixin({
    
    
            beforeCreate() {
    
    
            if(this.$options.router)
                _Vue.prototype.$router = this.$options.router
            },
        })
    }

}

Implementação do construtor

    constructor(options){
    
    
        this.options = options

        this.routerMap = {
    
    } // 用于存储解析的router对象
        this.data = _Vue.observable({
    
    
            current:'/'
        })
        // this.init()
    }

Desta forma, os atributos relevantes no diagrama de classes são realizados

Implementação do método CreateRouterMap

A função deste método é converter as regras de roteamento passadas no construtor na forma de pares chave-valor e armazená-las no routeMap mencionado acima

//遍历所有的路由规则,解析路由规则变为键值对的形式,存储到routermap里
    createRouterMap(){
    
    
        this.options.routes.forEach(route =>{
    
    
            this.routerMap[route.path] = route.component
        })
    }

Implementação do método initComponents

    initComponents (Vue) {
    
    
        Vue.component('router-link',{
    
    
            props:{
    
    
                to:String
                //接收外部传入的to
            },
            // template:'<a :href="to"><slot></slot></a>'
            render (h) {
    
    
                return h('a',{
    
    
                    attrs:{
    
    
                        href:this.to
                    },
                    on:{
    
    
                        click:this.clickHandler
                    }
                },[this.$slots.default])
            },
            methods: {
    
    
                clickHandler(e){
    
    
                    history.pushState({
    
    },'',this.to)
                    this.$router.data.current = this.to
                    e.preventDefault();
                }
            },
        })
        const  _this = this
        Vue.component('router-view', {
    
    
            render(h) {
    
    
                const component = _this.routerMap[_this.data.current]
                return h(component)
            },
        })
    }

Implementação do método initEvent

initEvent(){
    
    
        window.addEventListener('popstate',()=>{
    
    
            this.data.current = window.location.pathname
        })
    }

Este método é para carregar e renderizar componentes ao voltar e avançar no navegador

Código de roteamento escrito à mão completo

let _Vue = null

export default class VueRouter {
    
    

    static install (Vue) {
    
    
        //判断当前插件是否被安装
        if(VueRouter.install.installed){
    
    
            return;
        }
        VueRouter.install.installed = true

        // 把vue构造函数记录到全局变量
        _Vue = Vue
        // 把创建vue实例的时候传入的router对象注入到Vue实例上
        //混入 mixed
        _Vue.mixin({
    
    
            beforeCreate() {
    
    
            if(this.$options.router)
                _Vue.prototype.$router = this.$options.router
                // this.$options.router.init()
            },
        })
    }

    constructor(options){
    
    
        this.options = options

        this.routerMap = {
    
    } // 用于存储解析的router对象
        this.data = _Vue.observable({
    
    
            current:'/'
        })
         this.init()
    }
    init(){
    
    
        this.createRouterMap()
        this.initComponents(_Vue)
        this.initEvent()
    }
    //遍历所有的路由规则,解析路由规则变为键值对的形式,存储到routermap里
    createRouterMap(){
    
    
        this.options.routes.forEach(route =>{
    
    
            this.routerMap[route.path] = route.component
        })
    }
    initComponents (Vue) {
    
    
        Vue.component('router-link',{
    
    
            props:{
    
    
                to:String
            },
            // template:'<a :href="to"><slot></slot></a>'
            render (h) {
    
    
                return h('a',{
    
    
                    attrs:{
    
    
                        href:this.to
                    },
                    on:{
    
    
                        click:this.clickHandler
                    }
                },[this.$slots.default])
            },
            methods: {
    
    
                clickHandler(e){
    
    
                    history.pushState({
    
    },'',this.to)
                    this.$router.data.current = this.to
                    e.preventDefault();
                }
            },
        })
        const  _this = this
        Vue.component('router-view', {
    
    
            render(h) {
    
    
                const component = _this.routerMap[_this.data.current]
                return h(component)
            },
        })
    }
    initEvent(){
    
    
        window.addEventListener('popstate',()=>{
    
    
            this.data.current = window.location.pathname
        })
    }
}

Referência:
Lagou Education

Acho que você gosta

Origin blog.csdn.net/qq_43377853/article/details/113841827
Recomendado
Clasificación