Código fuente y avances del marco Vue.js (1) --- Implementación del principio de Vue-Router

1. Revisión básica de Vue-Router

(1) Uso básico

  1. Registrar complemento de enrutamiento
  2. Crear instancia de enrutamiento
    router/index.ts
// 1. 注册路由插件
Vue.use(VueRouter)

const routes: Array<RouteConfig> = [
  {
    
    
    path: '/',
    name: 'home',
    component: HomeView
  },
  {
    
    
    path: '/about',
    name: 'about',
    // 使用import动态懒加载组件,提升首页渲染效率
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
  }
]

// 2. 创建路由实例
const router = new VueRouter({
    
    
  routes
})
  1. Al crear Vueuna instancia, cuélguela en
    main.ts de la instancia de enrutamiento.
// 3. 创建 Vue 实例并挂载路由实例
new Vue({
    
    
  router,
  render: h => h(App)
}).$mount('#app')

routerEl acto de pasarlo al Vueconstructor de una instancia hará que la Vueinstancia conserve los dos objetos.
Insertar descripción de la imagen aquí

  • $route: Reglas de coincidencia de rutas
  • $router: Objeto de instancia de enrutamiento, puede llamar pushy gootros métodos para cambiar la ruta actual. $router.currentRouteEl atributo apunta a la regla de coincidencia de ruta actual:
console.log(myVue.$route===myVue.$router.currentRoute) // true
  1. Crear un marcador de ruta
  2. Crear enlace de salto de enrutamiento
    APP.vue
<nav>
  <!--5.创建路由跳转链接-->
  <router-link to="/">Home</router-link> |
  <router-link to="/about">About</router-link>
</nav>
<!--4.创建路由占位符-->
<router-view/>

(2) Enrutamiento dinámico

VueEl enrutamiento dinámico se refiere al hecho de que la transferencia dinámica de parámetros se puede utilizar para implementar saltos en la ruta de enrutamiento url. En este momento, la urlruta de enrutamiento no está codificada sino variable. Definición y transferencia de valor del enrutamiento dinámico:
router/index.ts

{
    
    
	 path: '/about/:id', // :id起占位符的作用
	 name: 'about',
	 component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}

Vista de aplicación

<router-link to="/about/89">About</router-link>

Hay dos formas de recibir parámetros dinámicos dentro de una ruta:

  1. Utilice $router.params
    ver/Acerca de.vue
<h2>id: {
   
   { $route.params.id }}</h2>

Insertar descripción de la imagen aquí
Una desventaja de este enfoque es que puede conducir a una dependencia excesiva $route.
2. Utilice el enrutador propsreceptor
/index.ts

{
    
    
  path: '/about/:id',
  name: 'about',
  props: true,
  component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}

vistas/Acerca de.vue

<h2>id: {
   
   { id }}</h2>
<script>
export default {
      
      
  name: 'AboutView',
  props: {
      
      
    id: String,
  },
};
</script>

Insertar descripción de la imagen aquí
Si no se pasan parámetros dinámicos en este momento, la página quedará en blanco. Agregarlo más tarde
indica que este atributo es opcional. Si no se pasa este parámetro, otras partes del componente de enrutamiento también pueden representar router/index.ts normalmente.:id?

path: '/about/:id?',

(3) Enrutamiento anidado

El enrutamiento anidado se utiliza en escenarios donde los componentes están anidados en varios niveles. Como se muestra en la siguiente figura, /user/johnnycorrespondiente a un componente, también contiene dos componentes que se pueden cambiar y mostrar. Las rutas correspondientes a estos dos componentes se pueden definir como /user/johnnysubrutas .
Insertar descripción de la imagen aquí
Las subrutas se definen utilizando childrenlos atributos del ruta. childrenLos atributos apuntan a una matriz. La matriz Los objetos en tienen atributos como y , pathque representan la ruta de la subrutina. Hay dos formas de escribir:componentpath

  • Una es la ruta absoluta, que se define a partir del directorio raíz y debe agregarse al principio /;
  • Una es la ruta relativa, que define la ruta relativa a la ruta principal. La ruta de la ruta principal y la ruta relativa eventualmente se unirán como la ruta del subcomponente actual y no se pueden agregar al principio /.
    enrutador/index.ts
{
    
    
    path: '/about',
    name: 'about',
    component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue'),
    children: [
        {
    
    
            path: '/about/company', // 绝对路径
            // path: 'company' // 相对路径
            name: 'company',
            component: () => import(/* webpackChunkName: "about" */ '../views/CompanyView.vue')
        }
    ]
}

Defina enlaces de salto de enrutamiento y marcadores de posición en la plantilla de componente de las vistas del componente principal
/AboutView.vue

<router-link to="/about/company">company</router-link>
<router-view></router-view>

Insertar descripción de la imagen aquí

(4) Navegación programática

Además de utilizar aenlaces para implementar saltos de ruta, también puede utilizar $routermétodos en objetos para implementar saltos de ruta. Se utilizan tres métodos principales:

  • push(). Acepta dos parámetros. El parámetro uno se puede escribir de dos maneras. La primera es una ruta y la segunda es un objeto. El objeto contiene los atributos pathde la ruta o namelos atributos de la ruta nombrada. El parámetro dos se utiliza para pasar parámetros para la ruta.
  • replace(). El uso es similar al push()método, pero este historial no se registrará y el historial de enrutamiento después del salto reemplazará el historial de enrutamiento actual, es decir, después del salto, no puede volver a la ruta actual a través del navegador. botón de retroceso.
  • go(). Este método toma un número entero como parámetro, que indica cuántos pasos avanzan o retroceden en la pila del historial, similar a window.history.go(n).
    aplicación.vue
<template>
  <div id="app">
    <router-view/>
    <button @click="goHome()">go HomeView</button>
    <button @click="goAbout()">go AboutView</button>
    <button @click="back()">回退</button>
  </div>
</template>
<script>
export default {
      
      
  name: 'App',
  methods: {
      
      
    goHome() {
      
      
      this.$router.push('/');
    },
    goAbout() {
      
      
      this.$router.replace({
      
       name: 'about' });
    },
    back() {
      
      
      this.$router.go(-1);
    },
  },
};
</script>

2. Modo Historia

(1) La diferencia entre el modo Hash y el modo Historia

Ambas son rutas de front-end, que cambian el contenido de representación de la página mediante cambios de ruta.

  • HashEl patrón se basa en anclajes y onhashchangeeventos, y los anclajes frontales se pueden implementar a través de atributos HTMLde elementos y enlaces href. Cuando la ruta cambia, el contenido de representación de la página se determina en función de la ruta. Los siguientes datos Hashen el patrón representan la configuración de enrutamiento.#
  • HistoryEl patrón se basa en HTML5el medio History APIy utiliza principalmente pushState()métodos y replaceState()métodos. pushState()El método no envía una solicitud al servidor, solo cambia urlla dirección y registra la dirección en el historial.
<template>
  <div id="app">
    <router-view/>
    <button @click="goHome()">go HomeView</button>
    <button @click="goAbout()">go AboutView</button>
    <button @click="back()">回退</button>
  </div>
</template>
<script>
export default {
      
      
  name: 'App',
  methods: {
      
      
    goHome() {
      
      
      this.$router.push('/');
    },
    goAbout() {
      
      
      this.$router.replace({
      
       name: 'about' });
    },
    back() {
      
      
      this.$router.go(-1);
    },
  },
};
</script>

(2) Modo de trabajo histórico

HistoryEn modo, urlla ruta es una dirección normal: https://www.teambition.com/project. Para aplicaciones de una sola página, el servidor solo guarda htmllos recursos de la página de inicio. Si el servidor no tiene la configuración correspondiente, acceder al servidor con dicha dirección no encontrará el recurso, por lo tanto, el servidor debe configurarse en consecuencia para admitir el Historymodo Cuando el servidor encuentra Cuando el recurso solicitado no está disponible, el archivo estático de la página de inicio se devuelve al cliente y el cliente analiza la página en función de la dirección de enrutamiento actual para implementar el salto de página.

  • Para nodeel servidor, es necesario configurar historyel middleware .
  • Para nginxel servidor, debe modificar nginx.confel archivo de configuración location /y agregar una línea de código en: try_files $uri $uri/ /index.html; Significa intentar cargar el recurso correspondiente a la ruta solicitada en el servidor. Si no se puede encontrar, use la dirección como carpeta y busque hacia abajo index.html; si aún así no se encuentra, regresa al archivo raíz en el sitio web index.html.

3. Implementación del enrutador Vue

(1) Principio de funcionamiento de Vue Router

  1. HashCómo funciona el patrón
  • #La última cadena en la barra de direcciones representa la dirección de enrutamiento. Cuando solo #cambia la última dirección, no se enviará ninguna solicitud al servidor y la nueva dirección se guardará en el historial.
  • onhashchangeEl método monitoreará los cambios en las direcciones de enrutamiento.
  • Dentro onhashchangedel método, se encontrará el componente correspondiente según la dirección de enrutamiento y se representará la página.
  1. Historyprincipio de funcionamiento
  • Al hacer clic en un enlace de salto de ruta, History APIel pushState()método agrega un nuevo registro a la pila del historial del navegador y cambia el actual sin cambiar la página URL.
  • Cuando el usuario hace clic en el botón Atrás del navegador o llama a un go()método, popStateel método se activará, se modificará la dirección actual y Vue-Routerse monitoreará la ejecución del método popStatepara obtener la información de enrutamiento actual.
  • Encuentre el componente correspondiente de acuerdo con la información de enrutamiento actual para la representación de la página.

(2) Análisis del enrutador Vue

  1. Primero echemos un vistazo Vue Routeral uso y analicemos Vue Routerlos tipos de
// 1. 注册路由插件
Vue.use(VueRouter)
// 2. 创建路由实例
const router = new VueRouter({
    
    
    routes
})
  • Registre el método Vue Routede uso de r Vue.use(). Este método se utiliza para registrar complementos. Hay dos tipos de parámetros que se pueden recibir. Uno es una función, que se ejecutará directamente; el otro es una clase, que ejecutará el método estático install()del clase.
  • Vue RouterPuede utilizar newla palabra clave para crear un objeto de instancia, aceptando un objeto como parámetro.
  • Entonces Vue Routeres una clase, el constructor recibe un objeto como parámetro, el objeto tiene una propiedad routesy Vue Routerla clase tiene un método estático install.
  1. Vue RouterEl objeto debe tener tres propiedades:
  • optionsGuardar reglas de enrutamiento entrantes
  • routeMapGuarde la relación correspondiente entre rutas y componentes como una relación de mapeo
  • dataPara Vue.observableimplementar la actualización de datos bidireccional, debe haber un objeto responsivo definido
  1. Según Vue Routerla función del objeto, se puede dividir en cuatro métodos:
  • initEvent()Registre popStateun detector de eventos para su procesamiento posterior cuando cambie el enrutamiento
  • createRouteMap()inicializaciónrouteMap
  • initComponents()Inicialización router-linky router-viewcomponentes.
  • init()Ejecute los tres métodos anteriores.
    Insertar descripción de la imagen aquí

(3) Implementación del método Install ()

Crea un nuevo src/vuerouter/index.jsarchivo y exporta Vue Routeruna clase.
Insertar descripción de la imagen aquí

export default class VueRouter {
    
    
	static install(){
    
    }
}

install()Funciones que el método debe implementar:

  1. Para determinar si el complemento actual se ha instalado, debe darle install()al método un atributo para identificarlo. Cuando install()se ejecute el método, este atributo cambiará true.
if(VueRouter.install.installed) return;
VueRouter.install.installed = true;
  1. Reciba Vueel constructor como parámetro y Vueregistre el constructor como una variable global porque necesitará usar Vuelos métodos en la clase más adelante, comoVue.component()
let _Vue = null;
export default class VueRouter {
    
    
    //接受Vue的构造函数作为参数
    static install(Vue) {
    
    
        // 1. 判断当前插件是否已经被安装,如果已经安装则不需要重复安装
        if(VueRouter.install.installed) return;
        VueRouter.install.installed = true;
        // 2. 把Vue构造函数记录到全局变量
        _Vue = Vue;
    }
}

¿ Por qué aceptar Vueun constructor como parámetro? Puedes echar un vistazo a install()la definición del código fuente del método:

// router.d.ts
static install: PluginFunction<never>
// plugin.d.ts
export type PluginFunction<T> = (Vue: typeof _Vue, options?: T) => void
// vue.d.ts
export const Vue: VueConstructor

Poder saber cómo se ve una función tan fácilmente es TypeScriptun lugar muy poderoso.

  1. Repasemos Vueel código que crea la instancia:
const myVue = new Vue({
    
    
  router,
  render: h => h(App)
}).$mount('#app')

En este momento, Vuese pasa un objeto al constructor routery install()el método necesita routerinyectar el objeto en Vuela instancia. Lo que se pasa actualmente es Vueel constructor. Para Vueagregar atributos a la instancia, debe montar los atributos en la cadena del prototipo, y Vueel objeto de la instancia puede heredar Vuelos atributos del constructor en una cadena. VueLos parámetros pasados ​​durante la construcción de la instancia se guardan en Vuelas $optionspropiedades de la instancia. Pero en install()el momento de la ejecución, aún no sabemos Vuequién es la instancia, por lo que debemos retrasar esta operación y realizarla durante el ciclo de vida Vuede la instancia beforeCreate(). Entonces necesitas usar mixin aquí para beforeCreate()mezclar el método en cada Vueobjeto de instancia. VueAdemás, este método solo debe ejecutarse una vez y se puede acceder a él en todos los objetos de instancia, por lo que solo debe ejecutarse una vez en la myAppaplicación y no es necesario ejecutarlo repetidamente en el ciclo de vida del componente beforeCreate()posterior . VueLa función de enlace mixto se ejecutará antes que la función de enlace de la propia instancia.

_Vue.mixin({
    
    
    beforeCreate() {
    
    
    	// 实例创建过程即new Vue()的时候有传递router参数,证明当前Vue实例是应用
        if(this.$options.router) {
    
    
        	// this指向当前Vue实例对象
            _Vue.prototype.$router = this.$options.router;
        }
    }
})

(4) constructor constructor

constructorEl constructor necesita inicializar tres propiedades options: , routeMapy . Código revisado :data
new VueRouter()

const router = new VueRouter({
    
    
    routes
})

constructorEl constructor aceptará un objeto como parámetro, que debe guardarse en el atributo options; routeMapes un objeto de par clave-valor que se utiliza para guardar la correspondencia entre la ruta y el componente. En la fase de inicialización, solo necesita inicializarlo. a un objeto vacío. El valor se asigna más tarde; datael atributo es un objeto responsivo, con un currentatributo que apunta a la dirección de enrutamiento actual. La fase de inicialización se establece en '/'. Debe utilizar el método Vueproporcionado por el constructor observablepara crear el objeto responsivo. . Cuando el objeto responsivo cambie, se activará automáticamente. Confíe en las funciones del componente de este objeto responsivo renderpara actualizar automáticamente la vista.

constructor(options) {
    
    
    this.options = options;
    this.routeMap = {
    
    };
    this.data = _Vue.observable({
    
    
        current: '/'
    });
}

(5) método createRouteMap()

createRouteMap()El método se utiliza para crear routeMapesta variable, que almacena la relación entre la ruta de enrutamiento y el componente en forma de un par clave-valor, con la ruta como clave y el componente como valor.

createRouteMap() {
    
    
    // 遍历所有路由规则,把路由规则解析成键值对的形式,存储到routeMap中
    this.options.routes.forEach(route => {
    
    
        this.routeMap[route.path] = route.component;
    })
}

(6) método initComponent()

initComponent()Los métodos se utilizan para crear router-linkcomponentes y router-viewcomponentes. Cómo utilizar el registro de componentes Vue.component().

1.enlace de enrutador

Primero repasemos router-linkel uso de: <router-link to="/">Home</router-link>. routerLinkEl componente recibe un parámetro toy eventualmente se representará en aforma de etiqueta, por lo que la plantilla es una aetiqueta; ael contenido de la etiqueta es el contenido pasado por el componente principal cuando se usa el componente, por lo que al definirlo, necesita Utilice la ranura para modificar primero la etiqueta ay coloque el contenido en su lugar. Del análisis anterior se puede definir routerLink:

Vue.component('router-link', {
    
    
    props: {
    
    
        to: String
    },
    template: '<a :href="to"><slot></slot></a>'
})

Pero todavía hay algunos problemas con esta forma de definición, el problema radica en Vuela versión de compilación. VueLas versiones de compilación se dividen en versión de ejecución y versión completa.

  • La versión completa incluye un compilador que compila plantillas en tiempo de ejecución. Por tanto, admite Vueel uso de atributos en componentes templatey es adecuado para entornos de desarrollo.
  • La versión en tiempo de ejecución no contiene un compilador y no puede utilizar templateatributos. Sin embargo, es más liviano y puede HTMLfuncionar principalmente colocando la plantilla y utilizándola en un entorno de producción.

Vue-cliEl valor predeterminado es tiempo de ejecución Vue, por lo que templateno se admiten atributos. Hay dos soluciones

  1. Utilice la versión completa Vue. Agregar a vue.config.jslas opciones de configuración del archivo.runtimeCompiler: true,
  2. templateEn lugar de utilizar una renderfunción. renderLa función recibe una hfunción como parámetro y devuelve hel resultado del procesamiento de la función. hLa función es crear un virtual DOMy aceptar tres parámetros.
    • DOMParámetro 1: Selector virtual (selector de etiquetas a)
    • Parámetro dos: DOMatributos virtuales ( hrefatributos, punteros this.to)
    • Parámetro tres: DOMuna matriz compuesta por subelementos virtuales (solo hay un subelemento: una ranura anónima, utilizando la adquisición vuede la instancia . La función es un método montado en la instancia y apunta internamente a la instancia; si Se utiliza la función de flecha, el punto de al mismo, es decir, instancia). Las funciones de flecha no se pueden utilizar aquí para señalar el componente creado.$slot.defaultrenderVuethisVuethisinitComponent()thisVueRouterthisrouterLink
Vue.component('router-link', {
    
    
    props: {
    
    
        to: String
    },
    render(h) {
    
    
        return h('a', {
    
    
            attrs: {
    
    
                href: this.to
            }
        }, [this.$slots.default])
    }
})
2.vista del enrutador

routerViewEl componente necesita encontrar el componente correspondiente a la ruta actual y luego renderizar este componente. routerMapLa relación correspondiente entre enrutamiento y componentes se almacena en el atributo. El dataatributo almacena la ruta actual, por lo que debe this.routeMap[this.data.current]obtener el componente que actualmente se debe representar y pasar el componente a la función h.

Vue.component('router-view', {
    
    
	// 注意使用箭头函数
    render:(h) =>{
    
    
        const component = this.routeMap[this.data.current];
        // h函数会帮我们把组件转化为虚拟DOM
        return h(component);
    }
})

En router-link, también necesitamos mejorar la función de procesamiento de eventos de clic.

  • Cuando se hace clic en un enlace a, se enviará una solicitud al servidor de forma predeterminada para solicitar ael recurso al que apunta el enlace, por lo que en la función de controlador del evento de clic se debe evitar el comportamiento predeterminado;
  • Repasemos this.datael atributo. Es un objeto responsivo, en el cual currentel atributo apunta a la dirección de enrutamiento. Cuando data.currentse modifica el atributo, hará que router-viewla renderfunción se vuelva a ejecutar. Debido a que routerViewel componente depende de él , activa la actualización de la vista. , por lo que los atributos this.data.currentde la ruta actual deben modificarse para permitir que la vista se actualice automáticamente.data.currentthis.to
  • No solo necesita modificar la vista, sino que también necesita modificar la dirección de la barra de direcciones, por lo que debe llamar a window.historyun pushState()método para modificar la dirección de la barra de direcciones.
Vue.component('router-link', {
    
    
    props: {
    
    
        to: String
    },
    render(h) {
    
    
        return h('a', {
    
    
            attrs: {
    
    
                href: this.to
            },
            on: {
    
    
                click: this.handleClick
            }
        }, [this.$slots.default])
    },
    methods: {
    
    
        handleClick(e) {
    
    
            // 改变current的值,触发组件的重新渲染
            // current是一个响应式的数据,所以会触发render函数的重新执行
            // render函数将会重新生成href指向this.to的a标签
            this.$router.data.current = this.to;
            // 通过pushState改变地址栏的地址,但是不会向后端发送请求
            // 参数一:state对象,可以在触发popstate事件时获取到
            // 参数二:title
            // 参数三:url
            history.pushState({
    
    }, '', this.to);
            // 点击a链接默认会向服务端发送请求去请求a链接对应的数据
            // 具体表现为页面会刷新,
            // 这里要阻止向服务端发送请求
            e.preventDefault();
        }
    }
})

De esta manera, la función de hacer clic en el enlace de enrutamiento para realizar el salto de enrutamiento se ha implementado generalmente, pero todavía hay un problema: al hacer clic en los botones de avance y retroceso del navegador, solo cambia la ruta de la barra de direcciones y la vista es no actualizado.

3.initEvent()

Cuando se hace clic en los botones de avance y retroceso del navegador, popState()se activará la función de escucha de eventos, por lo que la actualización de la página debe manejarse con este método. En popState(), la barra de direcciones se ha actualizado, por lo que la dirección de enrutamiento se puede obtener directamente de la dirección en la barra de direcciones. El valor asignado es this.data.current
window.locationun objeto que contiene la información de la URL actual, que es Locationuna instancia del objeto. Este objeto tiene muchas propiedades y métodos, los siguientes son algunos de los más utilizados:

  • location.href: Devuelve la URL completa.
  • location.protocol: Devuelve el protocolo utilizado por la página actual (como: http, https).
  • location.host: Devuelve el nombre de host (nombre de dominio) y el número de puerto de la página actual.
  • location.pathname: Devuelve la parte de la ruta de la página actual.
  • location.search: Devuelve la parte de la cadena de consulta de la página actual.
  • location.hash: Devuelve la parte ancla de la página actual.
initEvent() {
    
    
    // 监听浏览器地址栏地址的变化
    window.addEventListener('popstate', () => {
    
    
        this.data.current = window.location.pathname;
    })
}

No olvides init()llamar initEvent()funciones dentro de funciones.

init() {
    
    
    this.createRouteMap();
    this.initComponents(_Vue);
    this.initEvent();
}

VueRouterIntroduzca su propio enrutador/index.js donde se introdujoVueRouter

import VueRouter from '../vuerouter'

4. Código completo

vuerouter/index.js

let _Vue = null;
export default class VueRouter {
    
    
    //接受Vue的构造函数作为参数
    static install(Vue) {
    
    
        // 1. 判断当前插件是否已经被安装,如果已经安装则不需要重复安装
        if (VueRouter.install.installed) return;
        VueRouter.install.installed = true;
        // 2. 把Vue构造函数记录到全局变量
        _Vue = Vue;
        // 3. 把创建Vue实例时候传入的router对象注入到Vue实例上
        _Vue.mixin({
    
    
            beforeCreate() {
    
    
                // this是Vue实例
                if (this.$options.router) {
    
    
                    _Vue.prototype.$router = this.$options.router;
                    this.$options.router.init();
                }
            }
        })
    }

    // 构造函数
    constructor(options) {
    
    
        this.options = options;
        this.routeMap = {
    
    };
        this.data = _Vue.observable({
    
    
            current: '/'
        });
    }

    init() {
    
    
        this.createRouteMap();
        this.initComponents(_Vue);
        this.initEvent();
    }

    createRouteMap() {
    
    
        // 遍历所有路由规则,把路由规则解析成键值对的形式,存储到routeMap中
        this.options.routes.forEach(route => {
    
    
            this.routeMap[route.path] = route.component;
        })
    }

    initComponents(Vue) {
    
    
        // 将Vue实例传过来是为了减少方法与外部的依赖
        Vue.component('router-link', {
    
    
            props: {
    
    
                to: String
            },
            render(h) {
    
    
                return h('a', {
    
    
                    attrs: {
    
    
                        href: this.to
                    },
                    on: {
    
    
                        click: this.handleClick
                    }
                }, [this.$slots.default])
            },
            methods: {
    
    
                handleClick(e) {
    
    
                    // 改变current的值,触发组件的重新渲染
                    // current是一个响应式的数据,所以会触发render函数的重新执行
                    // render函数将会重新生成href指向this.to的a标签
                    this.$router.data.current = this.to;
                    // 通过pushState改变地址栏的地址,但是不会向后端发送请求
                    // 参数一:state对象,可以在触发popstate事件时获取到
                    // 参数二:title
                    // 参数三:url
                    history.pushState({
    
    }, '', this.to);
                    // 点击a链接默认会向服务端发送请求去请求a链接对应的数据
                    // 具体表现为页面会刷新,
                    // 这里要阻止向服务端发送请求
                    e.preventDefault();
                }
            }
        })
        // router-view起一个占位符的作用
        // 首先要在routeMap找到目标组件
        // 然后渲染组件
        Vue.component('router-view', {
    
    
            render:(h) =>{
    
    
                const component = this.routeMap[this.data.current];
                // h函数会帮我们把组件转化为虚拟DOM
                return h(component);
            }
        })

    }

    initEvent() {
    
    
        // 监听浏览器地址栏地址的变化
        window.addEventListener('popstate', () => {
    
    
            this.data.current = window.location.pathname;
        })
    }
}

Supongo que te gusta

Origin blog.csdn.net/weixin_45855469/article/details/131292709
Recomendado
Clasificación