1. ¿Cuáles son los ciclos de vida y qué cosas se han hecho en estos ciclos de vida?
beforeCreate antes de la creación; no se pueden obtener datos de respuesta
Una vez creado, puede agregar un evento de carga aquí y realizar solicitudes de datos.
Antes de montar Mount, la carga finaliza aquí y se obtienen algunos datos iniciales para implementar la autoejecución de la función.
Después del montaje, inicie una solicitud de backend aquí, recupere los datos y haga algo con el enlace de enrutamiento.
beforeUpdate antes de que se actualicen los datos
Una vez actualizados los datos actualizados,
beforeDestroy, ¿estás seguro de eliminar XX? ¿O confirmar para salir?
destruido Después de la destrucción, el componente actual se eliminó y el contenido relacionado se borró. El DOM no se puede obtener aquí.
2. Comunicación de componentes
Padres: props, $attrs/$listeners, $children, $root, provide/inject, $refs
De hijo a padre: $emit, $parent,
Hermano: eventBus, vuex
3. Comunicación de página
Parámetros de empalme de URL: "/a?a1=a1", página de recepción: this.$route.query.a1
Parámetros de consulta: {ruta: 'a', consulta: {a2:'a2'}}, página de recepción: this.$route.query.a2
parámetros: {nombre: 'a', parámetros: {a3:'a3'}}, página de recepción: this.$route.params.a3
Parámetros de enrutamiento dinámico: /path/a4, página de recepción: this.$route.params.id, enrutamiento: ruta: "/a/:id"
4. ¿Qué hace $set?
Se utiliza cuando los datos cambian pero la vista no se actualiza, como atributos recién agregados de un objeto o miembros recién agregados de una matriz.
this.$set(obj,"clave","valor")
5. ¿Qué hace $nextTick?
Ejecute la devolución de llamada retrasada después del siguiente ciclo de actualización de DOM. Utilice este método inmediatamente después de modificar los datos para obtener el DOM actualizado.
Por ejemplo: puede usarlo si desea operar dom durante el ciclo de vida creado.
this.$nextTick(()=>{ ... }) puede operar dom en el ciclo de vida antes del montaje
6. ¿Qué hace el mixin?
Proporciona una forma muy flexible de distribuir funciones reutilizables en componentes de Vue. Un mixin puede contener opciones de componentes arbitrarios. Cuando un componente utiliza un mixin, todas las opciones del mixin se "mezclarán" con las opciones del propio componente.
var mixin = { datos: función () { retorno { mensaje: 'hola', foo: 'abc' } } } new Vue({ mixins: [mixin], datos: función () { retorno { mensaje: 'adiós' , bar: 'def' } }, creado: function () { console.log(this.$data) // => { mensaje: "adiós", foo: "abc", bar: "def" } } } )
7. Hable brevemente sobre la comprensión de MVVM.
MVVM es la abreviatura de Model-View-ViewModel. El modelo representa el modelo de datos y la lógica empresarial para la modificación y operación de los datos también se puede definir en el modelo. La vista representa el componente de la interfaz de usuario, que es responsable de convertir el modelo de datos en una interfaz de usuario para su visualización. ViewModel monitorea los cambios en los datos del modelo, controla el comportamiento de la vista y maneja las interacciones del usuario. Una comprensión simple es que es un objeto que sincroniza Vista y Modelo y conecta Modelo y Vista. Bajo la arquitectura MVVM, no existe una conexión directa entre Vista y Modelo. En cambio, interactúan a través de ViewModel. La interacción entre Modelo y ViewModel es bidireccional, por lo que los cambios en los datos de la Vista se sincronizarán con el Modelo y los cambios en los datos del Modelo. También se reflejará inmediatamente en la Vista. ViewModel conecta la capa de Vista y la capa de Modelo a través de un enlace de datos bidireccional, y la sincronización entre Vista y Modelo es completamente automática sin intervención humana, por lo que los desarrolladores solo necesitan centrarse en la lógica empresarial y no necesitan operar manualmente el DOM. Debe prestar atención a la sincronización del estado de los datos. MVVM gestiona completamente el mantenimiento del estado de los datos complejos.
8. La diferencia entre reloj y computado
Watch solo puede monitorear los cambios de datos en los datos. Computed no necesita hacerlo. Watch puede realizar operaciones asincrónicas. Computed no puede. Computed no modifica los datos originales. Los datos procesados se devuelven mediante retorno y pueden contener una gran cantidad de operaciones lógicas.
9. La diferencia entre v-if y v-show
9.1 v-show simplemente controla el atributo de visualización del elemento, mientras que v-if es una representación condicional (si la condición es verdadera, el elemento se representará, si la condición es falsa, el elemento será destruido);
9.2 v-show tiene una sobrecarga de primer renderizado más alta, mientras que v-if tiene una sobrecarga de primer renderizado mucho menor;
9.3 v-if tiene una sobrecarga de conmutación más alta, mientras que v-show tiene una sobrecarga de conmutación pequeña;
9.4 v-if tiene v-else-if y v-else coincidentes, pero v-show no.
9.5 v-if se puede utilizar con plantilla, pero v-show no.
10. ¿Por qué no se pueden usar v-for y v-if juntos?
v-for tiene una prioridad más alta que v-if
Nunca use v-if y v-for en un elemento al mismo tiempo, lo que provocará una pérdida de rendimiento (cada renderizado se repetirá primero y luego realizará un juicio condicional)
Para evitar esta situación, anide la plantilla en la capa exterior (la representación de la página no genera nodos dom), realice un juicio v-if en esta capa y luego realice un bucle v-for internamente.
<template v-if="isShow"> <p v-for="elemento en elementos"> </template>
Si la condición aparece dentro del bucle, puede filtrar los elementos que no necesitan mostrarse de antemano a través del atributo calculado.
calculado:{ elementos:función(){ devolver this.list.filter(función(elemento){ devolver elemento.isShow }) } }
11. ¿Cuál es la función de la clave?¿Cuál es mejor escribir índice o id como valor?
La clave especifica una ID única para cada vnode. Durante el proceso de diferenciación de vnodes en el mismo nivel, puede comparar rápidamente según la clave para determinar si son el mismo nodo. Utilice la unicidad de la clave para generar un objeto de mapa para obtener el nodo correspondiente, que es más rápido que atravesar El método es más rápido. Después de especificar la clave, se puede garantizar la precisión de la representación (reutilizando elementos DOM tanto como sea posible). La ID debe usarse primero al asignar valores.
12. Cómo utilizar el filtro
// Usa globalmente Vue.filter('globalFilter', function(){ // ... }) // Usa filtros localmente : { formatMoney(num) { // ... }, } <p>Filter{ { dinero | formatoDinero }}</p>
13. ¿Qué hacen los cinco núcleos de vuex?
estado: datos básicos en Vuex, función auxiliar mapState
Getters: el estado derivado del estado de la tienda, algo similar a las propiedades calculadas, función auxiliar mapGetters
Mutaciones: la única forma de cambiar el estado en la tienda en Vuex, es sincrónica, la función auxiliar mapMutations
acciones: La acción presenta una mutación en lugar de cambiar directamente el estado. La acción puede contener cualquier operación asincrónica. Mapa de funciones auxiliaresAcciones
Módulos: Vuex nos permite dividir la tienda en módulos. Cada módulo tiene su propio estado, mutaciones, acciones, captadores e incluso submódulos anidados: división similar de arriba a abajo.
14. Cómo llamar a métodos de mutaciones y acciones.
Llamar a mutaciones: $store.commit('método definido en mutaciones') Llamar a acciones: $store.dispatch('método definido en acciones') acciones llamar a métodos en mutaciones: fn (contexto){ contexto . commit('método definido en mutaciones) '); }
15. ¿Cuáles son los atributos comúnmente escritos de vue-router?
Atributos comunes del enlace de enrutador:
a representa el enlace de la ruta de destino
Si reemplazar establece el atributo de reemplazo, al hacer clic, se llamará a roter.replace() en lugar de router.push(), por lo que no quedará ningún registro histórico después de la navegación, es decir, no podrá volver a la página anterior.
Después de que append establece el atributo append, la ruta base se agrega antes de la ruta actual. Por ejemplo, navegamos desde /a a una ruta relativa b. Si append no está configurado, la ruta es /b. Si está configurado, es /a/b.
etiqueta A veces desea que <router-link> se represente en una determinada etiqueta, como <li>. Entonces usamos la clase de propiedad de etiqueta para especificar qué tipo de etiquetas, y aún escuchará los clics y activará la navegación.
active-class establece el nombre de la clase CSS utilizada cuando se activa el enlace. El valor predeterminado se puede configurar globalmente a través de la opción de construcción de ruta linkActiveClass. El valor predeterminado es 'router-link-active'
exacto "si activar", el valor predeterminado es falso.
Propiedades comunes de vue-router:
ruta de ruta
nombre nombre de la ruta
componente de enrutamiento de importación de componentes
redirigir ruta redirigir
modo de moderación
subruta infantil
metainformación de metaenrutamiento
16. ¿Qué son los guardias de enrutamiento y qué han hecho?¿Para qué sirven los tres parámetros?
Guardias globales: beforeEach (interceptación de inicio de sesión), afterEach
Guardia exclusiva de ruta: beforeEnter (interceptación de inicio de sesión para algunas rutas)
Guardias dentro del componente: beforeRouteEnter (gestión de permisos), beforeRouteUpdate, beforeRouteLeave
Protección de resolución global de enrutamiento: beforeResolve (aquí, dependiendo de la dirección del nombre de la página única, el nombre de dominio de la interfaz a la que se accede también es diferente)
Tres parámetros: a: adónde ir, desde: de dónde venir, siguiente: siguiente paso
El ciclo de vida se activa al salir de la página a y entrar en la página b 1. beforeRouteLeave: el componente del componente de enrutamiento abandona el gancho antes del enrutamiento, lo que puede cancelar la salida del enrutamiento. 2.beforeEach: protección de enrutamiento global, que se puede utilizar para verificación de inicio de sesión, carga de enrutamiento global, etc. 3.beforeEnter: la guardia exclusiva de la ruta 4.beforeRouteEnter: el gancho antes de que el componente enrutado ingrese a la ruta. 5.beforeResolve: protección de análisis global de enrutamiento 6.afterEach: gancho de publicación global de enrutamiento 7.beforeCreate: ciclo de vida del componente, no se puede acceder a él. 8.creado: ciclo de vida del componente, se puede acceder a él, pero no se puede acceder a dom. 9.beforeMount: ciclo de vida del componente 10.desactivado: deja el componente de caché a, o activa los ganchos de destrucción de componentes beforeDestroy y destruidos de a. 11.montado: acceso/operación dom. 12.activado: ingrese el componente de caché e ingrese el subcomponente anidado de a (si corresponde). 13. Ejecute la función de devolución de llamada beforeRouteEnter a continuación.
17. La diferencia entre el modo hash e histórico
El modo hash consiste en escribir el punto de anclaje # después de la URL, ya que el cambio del valor hash no hará que el navegador envíe una solicitud al servidor, y el cambio hash activará el evento hashchange (hashchange solo puede cambiar el fragmento de URL después #); el punto más crítico es que las URL cuyos cambios de hash serán registradas por el navegador, encontrará que se puede usar el avance y retroceso del navegador, por lo que antes de que apareciera la historia de HTML5, la gente básicamente usaba hash para implementar el front -finalizar el enrutamiento.
Modo historial: el hash es compatible con IE8, el historial solo es compatible con IE10; el hash se usa originalmente para el posicionamiento de la página, pero si se usa para el enrutamiento, la función de anclaje original no se puede usar. En segundo lugar, los parámetros hash se basan en la URL. Si desea transferir datos complejos, habrá restricciones de volumen. Sin embargo, el modo historial no sólo puede poner parámetros en la URL, sino también almacenar los datos en un objeto específico. La API de historial se puede dividir en dos partes: conmutación (atrás, adelante, ir) y modificación (pushState ,
replaceState). Problema con el modo historia: tengo miedo de actualizar.
18. Hablemos de cuáles son las instrucciones más utilizadas y cómo personalizarlas.
v-if: renderiza el nodo si es verdadero; de lo contrario, no renderiza el nodo
v-if, v-else y v-else-if: js-like if...else declaraciones de juicio
v-show: controla la visualización y ocultación de elementos a través de display:none;
v-for: bucle, v-for tiene mayor prioridad que v-if y no se recomienda su uso conjunto.
v-bind: vincular atributos,
v-on: evento vinculante,
.stop evita que el evento continúe propagándose
El evento .prevent ya no recarga la página
.capture utiliza el modo de captura de eventos, es decir, los eventos desencadenados por el elemento en sí se procesan aquí primero y luego se entregan a los elementos internos para su procesamiento.
.self solo activa la función de controlador cuando event.target es el elemento actual
El evento .once solo se activará una vez
.passive le dice al navegador que no desea bloquear el comportamiento predeterminado del evento
modelo v: enlace de datos bidireccional
.lazy De forma predeterminada, v-model sincroniza el valor y los datos del cuadro de entrada. Puede utilizar este modificador para cambiar a resincronización en el evento de cambio.
.number convierte automáticamente el valor de entrada del usuario en un tipo numérico
.trim filtra automáticamente los espacios iniciales y finales ingresados por el usuario
v-text y v-html: se utilizan para actualizar textContent y generar la estructura html real
v-pre: Se utiliza principalmente para omitir el proceso de compilación de este elemento y sus subelementos.
v-cloak: permanece en el elemento hasta el final de la instancia asociada para compilar.
v-once: la instancia asociada solo se representará una vez. En posteriores renderizaciones, la instancia y todos sus elementos secundarios se tratarán como contenido estático y se omitirán. Esto se puede utilizar para optimizar el rendimiento de la actualización.
// Directiva personalizada directivas v-focus : { focus: { // Definición de directiva insertada: function(el) { el.focus(); }, }, },
19. Cómo utilizar la ranura vue
// 比如新建一个<diseño base> 组件 <div class="container"> <encabezado> <ranura nombre="encabezado"></ranura> </encabezado> <principal> <ranura></ranura> </ principal> <pie de página> <nombre de la ranura="pie de página"></slot> </ pie de página > </div> // 使用插槽 <diseño-base> < plantilla v-slot:encabezado> // 或者 <plantilla #encabezado > <h1>Aquí podría haber un título de página</h1> </template> < template v-slot:default> <p>Un párrafo para el contenido principal.</p> <p>Y otro.</p> </template> < template v-slot:footer> <p>Aquí tienes información de contacto</p> </template> </base-layout> // Ranura de alcance, como crear un nuevo componente <current-user> <span> <slot v-bind:user="user"> { { user.lastName }} </slot> </span> // Utilice slot <current-user> <template v-slot:default="slotProps"> { { slotProps.user.firstName }} </template> </current-user> // o abreviatura <current-user v - slot="slotProps"> { { slotProps.user.firstName }} </current-user>
20. Ventajas y desventajas de la aplicación Vue de una sola página
Ventajas: el objetivo de Vue es implementar el enlace de datos receptivo y los componentes de vista combinados a través de la API más simple posible. El núcleo es un sistema de enlace de datos receptivo. MVVM, basado en datos, componenteizado, liviano, conciso, eficiente, rápido y compatible con módulos. Sólo se preocupa por los datos, no por el DOM. Hay muchos complementos. Estado de fácil mantenimiento.
Desventajas: no es compatible con navegadores de versiones inferiores y solo es compatible con IE9 al menos; no favorece la optimización SEO (si desea admitir SEO, se recomienda renderizar los componentes a través del servidor); lleva un tiempo relativamente largo cargar la página de inicio por primera vez; no es posible. Debe utilizar los botones de navegación del navegador para avanzar y retroceder usted mismo.
21. ¿Por qué hacer RSS y cómo implementarla?
Mejor SEO, ya que los rastreadores de los motores de búsqueda pueden ver directamente la página completamente renderizada.
Tiempos de llegada de contenido más rápidos, especialmente para condiciones de red lentas o dispositivos lentos. A menudo resulta en una mejor experiencia de usuario.
limitado por las condiciones de desarrollo. El código específico del navegador solo se puede utilizar en determinadas funciones de enlace del ciclo de vida; algunas bibliotecas de extensiones externas pueden requerir un manejo especial para ejecutarse en aplicaciones renderizadas en el servidor.
Más requisitos relacionados con la configuración y la implementación de la compilación. A diferencia de las aplicaciones de una sola página (SPA) totalmente estáticas que se pueden implementar en cualquier servidor de archivos estático, las aplicaciones renderizadas en el servidor deben estar en el entorno de ejecución del servidor Node.js.
Más carga del lado del servidor
La estructura html se devuelve a través del backend y se procesa y muestra en el frontend, lo que se puede implementar usando Nuxt.
22. Cómo implementar la carga diferida de rutas
Para brindarles a los clientes una mejor experiencia, el primer componente de pantalla se carga más rápido para resolver el problema de la pantalla blanca.
Las páginas se pueden dividir y cargar cuando sea necesario, lo que puede compartir efectivamente la presión de carga en la página de inicio.
Reduzca el tiempo que lleva cargar la página de inicio.
componente: () => import('./Foo.vue') // Componente adicional: resolver => require(['@/components/home'],resolve)
23. Cómo establecer un estilo global en menos
// vue.config.js función addStyleResource(regla) { regla .use("style-resource") .loader("style-resources-loader") .options({ patrones: [path.resolve(__dirname, ". /src/assets/less/global.less")], }); } // module.export es menos css: { loaderOptions: { less: { lessOptions: { javascriptEnabled: true, globalVars: { primario: "#fff", }, }, }, }, }, // less全局变量 paquete web de cadena: (config) => { tipos constantes = ["módulos-vue", "vue", tipos.forEach((tipo) => addStyleResource(config.module.rule("less").oneOf(tipo)) ); },
24. ¿Cuál es la función del ámbito?
con alcance significa que el alcance de los siguientes estilos es el componente actual y no afectará los estilos globales.
25. La diferencia entre $router y $route
$router es el salto de ruta, $route es la información de ruta
26. La diferencia entre datos:{} y datos(){return {}}
Debido a que los datos que no están empaquetados con retorno serán visibles globalmente en el proyecto y causarán contaminación variable. Después de empaquetar con retorno, las variables en los datos solo tendrán efecto en el componente actual y no afectarán a otros componentes. Tiene el efecto de proteger los datos de origen.
27. Configuración, encapsulación, interceptación y dominio cruzado de Axios
// Dominio cruzado: complete proxyTable en devServe en index.js en la carpeta de configuración : { // cli3.0+ configura el proxy en vue.config.js '/api':{ Destino: 'Dirección de destino del servidor proxy', changeOrigin: verdadero, PathRewrite: {“^/api”:” ”} } }
// Encapsula e intercepta axios importados desde "axios"; const http = axios.create({ baseURL: "/api", timeout: 5000, headers: { "Context‐Type": "application/json", }, } ); // Solicitar interceptación http.interceptors.request.use( (res) => { // const token = sessionStorage.getItem('token') ? sessionStorag.getItem('token'): ''; // if( token){Agregar token a los encabezados} return res; }, (err) => { return err; } ); // Intercepción de respuesta http.interceptors.response.utilizar( (res) => { // código constante = res.code // if(code === 404){router.replace()} // if(code === 200){router.replace()} return res; }, (err) => { return err; } ); función get(url, params = {}) { return nueva Promesa((resolver, rechazar) => { http .get(url, params) .then((res) => resolver(res)) .catch ((err) => rechazar(err)); }); } function post(url, params = {}) { return new Promise((resolver, rechazar) => { http .post(url, params) .luego((res) => resolver(res)) .catch((err) => rechazar(err)); }); } exportar {obtener, publicar};
28. Comandos y comandos de inicio para crear proyectos en cada versión de cli
Crear proyecto: cli2.0: vue init webpack nombre del proyecto cli3.0+: vue crear nombre del proyecto iniciar proyecto: cli2.0: npm run dev cli3.0+: npm run server
29. Hable brevemente sobre su comprensión de vue3.0.
29.1 La mayor diferencia entre vue3.0 y vue2.0 es que la API ha cambiado de la API de opciones original a la API de composición + API de opciones, lo que hace que la escritura de código sea más flexible y la tasa de reutilización sea mayor.
29.2.vue3.0 es 2 veces más rápido que vue2.0 y la vibración de árboles es más amigable.
29.3, vue3.0 admite TypeScript y PWA
29.4. El enlace de datos bidireccional ha cambiado de Object.defineProperty al nuevo Proxy. Ya no es necesario usar $set.
29.5 Otros cambios: soporte para renderizadores personalizados, soporte para componentes Fragment y Portal, etc.
30. Explique brevemente el principio de vinculación bidireccional.
// Recopilador de dependencia de datos implementado en modo publicación-suscripción class Dep { constructor() { this.subs = []; } addSub(sub) { this.subs.push(sub); } notify() { this.subs.forEach ((sub) => sub.update()); } } Dep.depTargets = null; class Watcher { constructor(data, getter) { this.getter = getter; this.value = this.get(); } obtener () { Dep.depTargets = esto; let valor = this.getter(); Dep.depTargets = nulo; valor de retorno; } update() { this.value = this.get(); } } const typeTo = (val) => Object.prototype.toString.call(val); // El modo observador escucha los cambios en todas las propiedades function defineReactive( obj, clave, valor) { let dep = new Dep(); Object.defineProperty(obj, clave, { set(newValue) { if (newValue === value) return; value = newValue; dep.notify(); } , get () { const topTarget = Dep.depTargets; dep.addSub(topTarget); valor de retorno; }, }); } función función caminar(obj) {//监听所有属性 Object.keys(obj).forEach((clave) => { if (typeTo(obj[clave]) === "[objeto Objeto]") { caminar(obj[ clave]); } defineReactive(obj, clave, obj[clave]); }); } función observar(valor) { if (typeTo(valor) !== "[objeto Objeto]") return null; caminar(valor); } observar (esto.datos); new Watcher(this.data, () => { this.$mounte(this.el); });
31. ¿Qué optimizaciones de rendimiento de Vue se han realizado?
31.1 Optimización del rendimiento de listas largas: puede congelar un objeto mediante el método Object.freeze. Una vez que el objeto está congelado, ya no se puede modificar.
exportar valor predeterminado { datos: () => ({ libros: [] }), async creado() { const libros = esperar axios.get("/api/books"); this.libros = Object.freeze(libros); } };
31.2 Optimice el rendimiento de la lista infinita: si la aplicación tiene una lista de desplazamiento muy larga o infinita, entonces se debe utilizar la tecnología de "ventanas" para optimizar el rendimiento. Solo se debe representar una pequeña área de contenido, lo que reduce el tiempo de reproducción. -renderizar componentes y crear nodos DOM. El método window.requestAnimationFrame puede configurar la función de carga diferida
setTimeout(() => { // Insertar 100.000 piezas de datos const total = 100000; // 20 piezas a la vez, que se pueden ajustar según los problemas de rendimiento const MAX_ONCE = 20; // Número de veces necesarias para representar los datos const loopCount = total / MAX_ONCE; let countOfRender = 0; let el = document.querySelector("ul"); function add() { // Optimización, no se permite insertar datos para provocar un reflujo const fragment = document.createDocumentFragment(); for (sea i = 0; i < MAX_ONCE; i++) { const li = document.createElement("li"); li.innerText = `${i} + ${Math.floor(Math.random() * total)} `; fragmento.appendChild(li); } el.appendChild(fragmento); cuentaDeRender += 1; bucle(); } function loop() { if (countOfRender < loopCount) { window.requestAnimationFrame(add); } } bucle(); }, 0);
32. Algoritmo de diferenciación de Vue y dom virtual
Virtual DOM está diseñado para resolver problemas de rendimiento del navegador. Si hay N actualizaciones del DOM en una operación, el DOM virtual no operará el DOM inmediatamente, sino que guardará el contenido diferencial de las N actualizaciones en un objeto JS local y, finalmente, agregará el objeto JS al árbol DOM. a la vez., y luego realice operaciones posteriores para evitar una gran cantidad de cálculos innecesarios. Por lo tanto, la ventaja de utilizar objetos JS para simular nodos DOM es que todas las actualizaciones de la página se pueden reflejar primero en los objetos JS (DOM virtual). La velocidad de operación de los objetos JS en la memoria es obviamente más rápida. Una vez completada la actualización, el Los objetos JS finales se asignan al DOM real y se entregan al navegador para que los dibuje.
Algoritmo de diferenciación de Vue: compare solo en el mismo nivel, ignore las operaciones entre niveles y compare desde ambos extremos hasta el medio.
// La función patch se llama durante la diferencia. patch recibe dos parámetros vnode y oldVnode, que representan los nodos antiguos y nuevos respectivamente. función parche (oldVnode, vnode) { if (sameVnode(oldVnode, vnode)) { patchVnode(oldVnode, vnode) } else { const oEl = oldVnode.el let parentEle = api.parentNode(oEl) createEle(vnode) if (parentEle ! == null) { api.insertBefore(parentEle, vnode.el, api.nextSibling(oEl)) api.removeChild(parentEle, oldVnode.el) oldVnode = null } } return vnode } // El primer juicio if en la función de parche SameVnode (oldVnode, vnode) es para determinar si los dos nodos son del mismo tipo. función de nodo SameVnode (oldVnode, vnode) { // Los valores clave de los dos nodos son los mismos y el valor del atributo sel es el mismo, es decir, los dos Los nodos se consideran del mismo tipo y se pueden comparar en el siguiente paso. == = oldVnode.key && vnode.sel === oldVnode.sel } // En otras palabras, incluso si el mismo elemento de nodo, como un div, tiene diferentes nombres de clase, Vue lo considerará dos tipos diferentes de nodos y realizará operaciones de eliminando el nodo antiguo e insertando el nuevo nodo. Esto es diferente de la implementación de react diff. React considera que el mismo elemento de nodo es del mismo tipo de nodo y solo actualiza los atributos de su nodo. // Para nodos del mismo tipo, llame a patchVnode(oldVnode, vnode) para comparar más patchVnode (oldVnode, vnode) { const el = vnode.el = oldVnode.el // Deje que vnode.el se refiera al dominio real actual, cuando se modifica el, vnode.el cambiará sincrónicamente. let i, oldCh = oldVnode.children, ch = vnode.children if (oldVnode === vnode) return // Las referencias de los nodos antiguos y nuevos son consistentes y no hay cambios // Comparación de nodos de texto if (oldVnode.text! == nulo && vnode .text !== nulo && oldVnode.text !== vnode.text) { api.setTextContent(el, vnode.text) }else { updateEle(el, vnode, oldVnode) // Para dos nodos que tienen nodos secundarios (los nodos secundarios de los dos son diferentes), llame a updateChildren if (oldCh && ch && oldCh !== ch) { updateChildren(el, oldCh, ch ) }else if (ch){ //Solo el nuevo nodo tiene nodos secundarios, agrega un nuevo nodo secundario createEle(vnode) //crea el dom secundario de el }else if (oldCh){ //Solo el nodo antiguo tiene nodos secundarios, realizar eliminación operación de nodo secundario api.removeChildren(el) } } } //Actualizar vnode: función updateChildren updateChildren (parentElm, oldCh, newCh, insertVnodeQueue, removeOnly) { var oldStartIdx = 0; var newStartIdx = 0; var oldEndIdx = oldCh.length - 1; var oldStartVnode = oldCh[0]; var oldEndVnode = oldCh[oldEndIdx]; if (isUndef(oldStartVnode)) { var newEndIdx = newCh.length - 1; var newStartVnode = newCh[0]; var newEndVnode = newCh[newEndIdx]; var oldKeyToIdx, idxInOld, vnodeToMove, refElm; // removeOnly es un indicador especial utilizado solo por <transition-group> // para garantizar que los elementos eliminados permanezcan correctos posiciones relativas // durante las transiciones de salida var canMove = !removeOnly; { checkDuplicateKeys(newCh); } // Si el índice es normal while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) { // El nodo antiguo inicial actual no lo es definido, ingrese el siguiente nodo // El nodo antiguo final actual no está definido, ingrese el nodo anterior oldStartVnode = oldCh[++oldStartIdx]; // Vnode se ha movido a la izquierda } else if (isUndef(oldEndVnode)) { oldEndVnode = oldCh[--oldEndIdx]; // Si el antiguo nodo de inicio es el mismo que el nuevo nodo de inicio , luego comience a actualizar el nodo y luego vaya al siguiente nodo } else if (sameVnode(oldStartVnode, newStartVnode)) { //Actualizar el nodo patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue); oldStartVnode = oldCh[++oldStartIdx]; newStartVnode = newCh[++ newStartIdx]; // Si el antiguo nodo final es el mismo que el nuevo nodo final, comience a actualizar el nodo y luego vaya al siguiente nodo } else if (sameVnode(oldEndVnode, newEndVnode)) { patchVnode(oldEndVnode, newEndVnode, insertVnodeQueue); oldEndVnode = oldCh[--oldEndIdx]; newEndVnode = newCh[--newEndIdx]; // If el antiguo nodo de inicio es el mismo que El nuevo nodo final es el mismo. Después de actualizar el nodo, mueva el antiguo nodo de inicio al final del nodo. } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode se movió hacia la derecha patchVnode(oldStartVnode, newEndVnode, insertVnodeQueue); canMove && nodeOps.insertBefore(parentElm, oldStartVnode.elm, nodeOps.nextSibling(oldEndVnode.elm)); oldStartVnode = oldCh[++oldStartIdx]; newEndVnode = newCh[--newEndIdx]; // Si el antiguo nodo final es el mismo que el nuevo nodo inicial, actualiza el nodo y mueve el antiguo nodo final al principio del nodo } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode se movió hacia la izquierda patchVnode(oldEndVnode, newStartVnode, insertVnodeQueue); canMove && nodeOps.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm); } demás { oldEndVnode = oldCh [--oldEndIdx]; newStartVnode = newCh[++newStartIdx]; // Si el nodo antiguo no tiene una clave definida, crea una clave if (isUndef(oldKeyToIdx)) { oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx); } idxInOld = isDef(newStartVnode .key) ? oldKeyToIdx[newStartVnode.key] : findIdxInOld(newStartVnode, oldCh, oldStartIdx, oldEndIdx); // Si el índice no está definido, crea un nuevo elemento de nodo if (isUndef(idxInOld)) { // Nuevo elemento createElm(newStartVnode , insertVnodeQueue, parentElm, oldStartVnode.elm); } else { vnodeToMove = oldCh[idxInOld]; if (sameVnode(vnodeToMove, newStartVnode)) { patchVnode(vnodeToMove, newStartVnode, insertVnodeQueue); refElm = isUndef(newCh[newEndIdx + 1]) ? null : newCh[newEndIdx + 1].elm; oldCh[idxInOld] = indefinido; canMove && nodeOps.insertBefore(parentElm, vnodeToMove.elm, oldStartVnode.elm); } else { // misma clave pero elemento diferente. Tratar como nuevo elemento createElm(newStartVnode, insertVnodeQueue, parentElm, oldStartVnode.elm); } } newStartVnode = newCh [++newStartIdx]; } } // Si el índice inicial del nodo antiguo es mayor que el índice final, crea un nuevo nodo. Si el índice del nuevo nodo inicial es mayor que el nuevo nodo final, elimina el nodo antiguo si ( oldStartIdx > oldEndIdx) { removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx); } addVnodes(parentElm, refElm, newCh, newStartIdx, newEndIdx, insertVnodeQueue); } más si (newStartIdx > newEndIdx) { }
33. ¿Se pierden datos después de actualizar la página de vuex? ¿Y el problema 404 de actualización del modo historial?
// Lee la información de estado en sessionStorage cuando se carga la página if ( sessionStorage.getItem('state') ) { this.$store.replaceState( Object.assign( {}, this.$store.state, JSON.parse( sessionStorage.getItem('state') ) ) ) } // Almacena datos de estado en sessionStorage cuando se actualiza la página window.addEventListener('beforeunload',()=>{ sessionStorage.setItem('state',JSON.stringify( this .$store.state) ) }) // Problema 404 de actualización del modo historial Configure module.exports en vue.config.js = { publicPath: '/', //Esto es necesario, los recursos estáticos deben importarse desde la raíz ruta, de lo contrario no se encontrará el recurso estático devServer: { // La URL en modo historial se solicitará al servidor, pero el servidor no tiene este archivo de recursos y se devolverá 404, por lo que este elemento debe configurarse historiaApiFallback: { índice: '/index.html' //ruta pública con salida html' //ruta pública con salida }, }, }
34. ¿Cómo utilizar constantes de estado globales en el desarrollo de Vue? ¿Para qué utilizas esta constante de estado?
Por ejemplo, la constante de estado global más común es proceso.env.NODE_ENV
Sus posibles valores son: producción, desarrollo.
Es el modo en webpack.config.js.
{ mode: "", entrada: "", salida: {} } // Por ejemplo, si está en modo de desarrollo, mostraré un determinado botón de función. <button v‐if="process.env.NODE_ENV === 'develpment'"> Botón de prueba </button> Este botón es visible cuando npm ejecuta servicio. Este botón no es visible cuando npm ejecuta compilación.
35. Enrutamiento dinámico
Agregue dinámicamente información de enrutamiento a través de addRoutes()