Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Cuál es el principio de Vue para implementar el salto de enrutamiento y cómo se llama el método js subyacente?

¿Cuál es el principio de Vue para implementar el salto de enrutamiento y cómo se llama el método js subyacente?

El enrutamiento front-end encuentra directamente el componente u objeto que coincide con la dirección y lo representa. Hay dos formas de cambiar la dirección del navegador sin realizar una solicitud al servidor:

1.

2. Utilice la función window.history de H5, utilizando el hash de la URL. El valor simula la URL completa.

Al empaquetar y crear una aplicación

Al crear una aplicación, el paquete de Javascript puede volverse muy grande y afectar la carga de la página. Sería más eficiente si pudiéramos dividir los componentes correspondientes a diferentes rutas en diferentes bloques de código y luego cargar solo los componentes correspondientes al acceder a la ruta.

Estructura de directorios

Echemos un vistazo a la estructura general de directorios

Las principales preocupaciones relacionadas con el proceso son los componentes y los directorios históricos, y create-matcher. js, crear-ruta-map.js, index.js, install.js, etc. Comenzaremos con application.js básico. A continuación, comenzaremos con el portal de aplicaciones básico y analizaremos todo el proceso de vue-router.

importar Vue desde 'vue'

importar VueRouter desde 'vue-router'

// 1. Complementos

// Instalación componentes lt;router-viewgt; y lt;router-linkgt;

// E inyectar objetos $router y $route en todos los componentes de la aplicación actual

Vue.use(VueRouter)

/ 2. Definición Los componentes utilizados en cada ruta se denominan componentes de enrutamiento

const Home = { template: 'lt.divgt;homelt;/divgt;'

const Foo = { template: 'lt;divgt ;foolt;/divgt;' }

const Bar = { template: 'lt;divgt;barlt;/divgt;' }

// 3. Crear enrutador de instancia VueRouter

enrutador constante = nuevo VueRouter({

modo: 'historial',

base: __dirname,

rutas: [

{ ruta: '/', componente: Inicio },

{ ruta: '/foo', componente: Foo },

{ ruta: ' /bar', componente: Bar }

]

})

// 4. Cree e inicie la aplicación

// Asegúrese de que el enrutador se inyecta

// El componente de enrutamiento estará en

new Vue({

router,

template; :`lt;div id="app"gt;

lt;h1gt;Basiclt;/h1gt;

lt;ulgt;

lt;ligt ; lt;router-link to="/"gt;/lt;/router-linkgt;lt;/ligt;

lt;ligt;lt;router-link to="/foo"gt; tonto;/router-linkgt;lt;/ligt;

lt;ligt;lt;router-link to="/bar"gt;/barlt;/router-linkgt;lt;/ligt; /p>

lt; etiqueta de enlace del enrutador="li" to="/bar"gt;/barlt;/router-linkgt;

lt;/ulgt;

lt; enrutador-vista class="view"gt;/router-viewgt;

lt;/divgt

`

}) . $mount('#app')123456789101112131415161718192021222324252627282930313233343536373839404142

Como complemento

El paso clave 1 en el código anterior utiliza el mecanismo de complemento proporcionado por Vue.js.use ( complemento) para instalar VueRouter, que llama al método de instalación del objeto del complemento (si el complemento en sí no tiene dicho método, se llama a la función propia del complemento, echemos un vistazo a la implementación específica de); vue-router como complemento.

El objeto VueRouter está expuesto en src/index.js y tiene un método de instalación estático:

/* @flow */

// Importa la instalación módulo

importar {instalar} desde './install'// ... .importar {inBrowser,supportHistory} desde './util/dom'// ... .exportar la clase predeterminada VueRouter {

p>

// ...}

// Asignar instalación

VueRouter.install = install

// Automáticamente use el complemento if (inBrowser amp ;amp; window.Vue) {

window.Vue.use(VueRouter )

}123456789101112131415161718

Puede Mira, esto está escrito Vue.js El enfoque clásico de los complementos. El método de escritura clásico del complemento js es agregar el método de instalación en el objeto del complemento para instalar la lógica específica del complemento. Al mismo tiempo, al final del juicio, si window.Vue. js existe en el entorno del navegador, instálelo en el complemento Vue.js. Vista.

install es un módulo separado aquí, así que continuaremos discutiendo la lógica principal de src/install.js en el mismo nivel:

//router-view router-link importar componente Ver desde './components/view' importar enlace desde './components/link'// exportar una referencia de Vue exportar let _Vue// instalar función exportar función instalar (Vue) {

if (instalar .installed ) return

install.installed = true

// Asignar referencia privada de Vue

_Vue = Vue // inyectar $router $route

Object.Object.defineProperty(Vue.prototype, '$router', {

get () { return this.$root._router }

}) Object.defineProperty (Vue .prototype, '$route', {

get () { return this.$root._route }

})// beforeCreate mixin

Vue. mixin({

beforeCreate () { // Determinar si hay un enrutador

if (this.$options.router) { // Asignar _router

this ._ router = this.$options.// Inicializar init

this._router.init(this) // Definir el objeto _route de respuesta

Vue.util.defineReactive (this, '_route'.this._router.history.current)

}

}

}

})// Registrar componente

Vue.component('router-view', Ver)

Vue.component('router-link', Enlace) // ...}. 12345678910111213141516171819202122232425262728293031323334353637383940414243

¿Algunas preguntas aquí?

- ¿Por qué exportar referencias de Vue?

El complemento definitivamente no quiere que Vue sea una dependencia al empaquetar, pero sí quiere usar algunos métodos del objeto Vue en sí. Esto se puede lograr de una manera similar a la anterior, es decir. , asignando variables en el momento de la instalación a Vue para que pueda usar ciertos métodos de Vue en otros lugares sin incorporar la dependencia de vue (siempre que prometa usarlo después de la instalación).

- ¿Puedo inyectar $router y $route en todos los componentes definiéndolos como propiedades $router y $route de Vue.prototype?

Todos los componentes de Vue.js son instancias extendidas de Vue, lo que significa que todos los componentes pueden acceder a las propiedades definidas en el prototipo de la instancia.

antes de crear mixin. Esto se discutirá en detalle más adelante al crear instancias de Vue.

Crear una instancia de VueRouter

En el archivo de entrada, primero crea una instancia de un VueRouter y lo pasa a las opciones de la instancia de Vue. Ahora vaya a la clase VueRouter expuesta en src/index.js:

// ... .import { createMatcher } from './create-matcher'// ... .export default class VueRouter {

// ...

constructor (opciones: RouterOptions = {}) {

this.app = null

this. opciones = opciones

this.beforeHooks = []

this.afterHooks = []

// Crear función de coincidencia

this. match = createMatcher(options.routes || [])

// Crear una instancia de un registro histórico específico según el modo

let mode = options.mode || 'hash'

this.fallback = modo === 'historia' amp; !supportsHistory if (this.fallback) {

modo = 'hash'

} if (! inBrowser) {

mode = 'abstracto'

}

this.mode = cambio de modo (modo) {

caso 'historial ':

this.history = new HTML5History(this, options.base) break

case 'hash':

this.history = new HashHistory(this , opciones.base, this.fallback) break

caso 'abstracto':

this.history = new AbstractHistory(this) break

predeterminado:

p>

assert(false, `modo no válido: ${mode}`)

}

}

// . ..}. 123456789101112131415161718192021222324252627282930313233343536373839

Internamente contiene un paso importante: crear una función de coincidencia.

función de coincidencia

La función de coincidencia es creada por createMatcher en src/create-matcher.js:

/* @flow */

importar Regexp desde 'path-to-regexp'// .import { createRouteMap } desde './.export function createMatcher (rutas: Arraylt; RouteConfiggt;): Matcher {

// Crear ruta map

const { pathMap, nameMap } = createRouteMap (rutas)

// Coincidencia de función de coincidencia (

raw: RawLocation,

currentRoute ?Ruta,

redirectedFrom?: Ubicación

): Ruta {

// ...

} función de redireccionamiento (

} p>

registro: RouteRecord,

ubicación: Ubicación

): Ruta {

// ...

} alias de función (

registro: RouteRecord,

ubicación: Ubicación,

matchAs: cadena

) : Ruta {

// ...

} función _createRoute (

registro: ?RouteRecord,

ubicación: Ubicación,

redirectedFrom ?) Ruta { if (record amp; record.redirect) { return redirección(record, redirigidoFrom || ubicación)

} if (record amp; record.matchAs) { return alias(registro, ubicación, record.matchAs)

} return createRoute(registro, ubicación, redirigidoFrom)

}

// return return match

}

// ....123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051

Se entiende que la ruta correspondiente se genera en base a la configuración de enrutamiento entrante y luego devolver directamente la función coincidente.

Continúe usando la función createRouteMap en src/create-route-map.js:

/* @flow */import { afirmar, advertir } desde './util/warn ' importar { cleanPath } desde './util/path'// Crear ruta mapexport función createRouteMap (rutas: Arraylt; RouteConfiggt;): {

pathMap: Dictionarylt;,

nombreMapa:Diccionariolt;RouteRecordgt;

}.

{ // mapa de ruta

const pathMap: Dictionarylt; = Object.create(null) // nombre mapa de ruta

const nameMap: Dictionarylt; (nulo) // Recorre el objeto de configuración de enrutamiento para agregar registros de enrutamiento

routes.forEach(route =gt; {

addRouteRecord(pathMap, nameMap, route)

}) devuelve {

pathMap,

nameMap

}

}

}

}

}//Agregar función de registro de ruta

parent?: RouteRecord,

matchAs?: string

){

//Obtener ruta y nombre

const { ruta, nombre }= ruta

assert(ruta! = nulo, se requiere `"ruta" en una configuración de ruta.`) // Objeto de registro de ruta

registro constante: RouteRecord = {

ruta: normalizePath(ruta, padre),

componentes: ruta.componentes || {predeterminado: ruta.components },

instancias: {},

nombre, padre,

matchAs,

redirección.ruta.redirect,

antes de ingresar: ruta.antes de ingresar,

meta: ruta.meta || p> if (ruta.niños) {// ... ...

ruta.niños.forEach(niño =gt; {

addRouteRecord(pathMap, nameMap, child, registro)

})

}})

}// Procesar la lógica del alias y agregar los registros correspondientes

if (route.children ) { // .../p>

if (ruta.alias ! == indefinido) { if (Array.isArray(ruta.alias)) {

ruta.alias .forEach (alias =gt; {

addRouteRecord(pathMap, nameMap, {path.alias}, parent, record.path)

})

} else {

addRouteRecord(pathMap, nameMap, { ruta: ruta.alias}, padre, re

cord.path)

}

}//Actualizar mapa de ruta

pathMap[record.path] = record //Actualizar mapa de nombres

if (nombre) { if (!nameMap[nombre]) {

nameMap[nombre] = registro

} else {

warn(false, `Definición de rutas con nombre duplicadas: { nombre: "${name}", ruta: "${record.path}" })

}

}

} Función normalizePath (ruta: cadena, padre?: RouteRecord): cadena {

ruta = ruta.replace(/\/$/, '') if (ruta[0] === ' / ') ruta de retorno if ( parent == null) ruta de retorno return cleanPath(`${parent.path}/${path}`)

}123456789101112131415161718192021222324252627282930313233343536373839404142434445 464 7484950515253545556575859606162636465666768697071727374757677787980818283

Puede ser Como se ve, el trabajo principal a realizar es generar un mapeo de registros de enrutamiento de acuerdo con el objeto de configuración de enrutamiento del usuario, que corresponde al registro de enrutamiento ordinario según la ruta y el nombre, para facilitar la coincidencia posterior.

Establecer registros históricos

Este también es un paso muy importante. Todas las clases de registros históricos están en el directorio src/history/. No necesitamos preocuparnos por la implementación de cada historial. clase de registro. Para diferencias específicas, solo sepa que ambos heredan de src/history/base.js.

Clase de historial:

/* @flow *//...import { inBrowser }.import { inBrowser } from './util/dom'import { runQueue } from './util/async' import { START, isSameRoute } de './util/route'// Aquí está el install.js analizado antes de exportar _Vueimport { _Vue } del historial de clases de exportación './install' {// ...

constructor (router: VueRouter, base: ?string) { this.router = router this.base = normalizeBase(base) // Comience con un objeto de enrutamiento que represente "ninguna parte"

this.current = INICIAR esto. pendiente = null

}// ...}// Obtener la función de valor base normalizeBase (base: ?string): string { if (!base) { if (inBrowser) { // respect lt; basegt; etiqueta

const baseEl = document. querySelector('base') base = baseEl.getAttribute('href'): '/'

} else { base = ' /'

}

}

}// Asegúrate de que haya una barra diagonal inicial

if (base.charAt( 0) ! == '/') { base = '/' base