Conceptos básicos de la entrevista: preguntas de la entrevista VUE (incluidas las respuestas)

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()

Supongo que te gusta

Origin blog.csdn.net/xiaozgm/article/details/125677842
Recomendado
Clasificación