Sitio de prueba de alta frecuencia de entrevistas front-end web: Vue3.x (reutilización lógica de la API de composición, proxy para lograr la capacidad de respuesta)

Directorio de artículos de la serie

contenido Link de referencia
Sitio de prueba de alta frecuencia de entrevistas de JavaScript HTML, CSS, JavaScript, ES6, AJAX, sitio de prueba de entrevista HTTP
Vue2.x entrevista sitio de prueba de alta frecuencia Vue2.x entrevista sitio de prueba de alta frecuencia
Vue3.x nueva API Ciclo de vida, comprensión y mejor uso de ref, toRef y toRefs
Características importantes de la actualización de Vue3.x emite propiedad, ciclo de vida, eventos múltiples, fragmento, eliminar .async, escritura de componentes asíncronos, eliminar filtro, teletransporte, suspenso...


1. Cómo la API de composición implementa la reutilización lógica

  • Extraer código lógico en una función
  • La convención de nomenclatura de funciones es el formato useXxx (React Hooks también)
  • Funciones de referencia useXxx en la configuración

archivo useMousePosition.js

  • Evento de movimiento del mouse, que muestra la posición del mouse
  • Escrito en archivos js para reutilización lógica
import {
    
     ref, onMounted, onUnmounted} from 'vue'

function useMousePosition() {
    
    
    // 初始化坐标
    const x = ref(0)
    const y = ref(0)

    // 更新坐标
    function update(e) {
    
    
        x.value = e.pageX
        y.value = e.pageY
    }

    // 挂载:添加鼠标移动事件
    onMounted(() => {
    
    
        console.log('useMousePosition mounted');
        window.addEventListener('mousemove', update)
    })

    // 销毁:删除鼠标移动事件
    onUnmounted(() => {
    
    
        console.log('useMousePosition unMounted');
        window.removeEventListener('mousemove', update)
    })

    return {
    
    
        x,
        y
    }
}

export default useMousePosition

Componente principal de App.vue

  • Haga clic en el botón para crear/destruir el componente
<template>
  <MousePosition v-if="flag" />
  <button @click="changeFlagHandler">change flag</button>
</template>

<script>
import MousePosition from "./components/index.vue";
export default {
    
    
  data() {
    
    
    return {
    
    
      flag: true,
    };
  },
  methods: {
    
    
    // 实现组件的创建/销毁
    changeFlagHandler() {
    
    
      this.flag = !this.flag;
    },
  },
  components: {
    
     MousePosition },
};
</script>

componente secundario index.vue

  • Deconstruye la x y la y definidas en la función.
<template>
  <p>mouse position {
    
    {
    
     x }} {
    
    {
    
     y }}</p>
</template>

<script>
import useMousePosition from "./useMousePosition";

export default {
    
    
  name: "MousePosition",
  setup() {
    
    
    // 解构 x 和 y
    const {
    
     x, y } = useMousePosition();

    return {
    
    
      x,
      y,
    };
  },
};
</script>

Reutilización de API de composición

2. Cómo implementa Vue3 la capacidad de respuesta

1. Desventajas de Object.defineProperty

  • La escucha profunda requiere una recursividad única (los niveles profundos afectarán el rendimiento)
  • No se pueden escuchar las propiedades de agregar/eliminar (Vue.set Vue.delete)
  • No se pueden monitorear los arreglos de forma nativa, se requiere un manejo especial

2. Proxy implementa capacidad de respuesta

  • target: son los datos del objeto definido
  • clave: la clave para obtener
  • val: el valor a obtener
  • receptor: es proxyData

Ejemplo: Object implementa pruebas reactivas a través de Proxy

const data = {
    
    
    name: '杂货铺',
    age: 20
}

const proxyData = new Proxy(data, {
    
    
	// 监听获取
    get(target, key, receiver) {
    
    
        const result = Reflect.get(target, key, receiver)
        console.log('get', key);
        return result // 返回结果
    },
    
    // 监听设置
    set(target, key, val, receiver) {
    
    
        const result = Reflect.set(target, key, val, receiver)
        console.log('set', key, val)
        console.log('result', result); // true
        return result // 是否设置成功
    },
    
    // 监听删除
    deleteProperty(target, key) {
    
    
        const result = Reflect.deleteProperty(target, key)
        console.log('delete property', key);
        console.log('result', result); // true
        return result // 是否删除成功
    }
})

inserte la descripción de la imagen aquí

Ejemplo: Array implementa pruebas reactivas a través de Proxy

const data = ['a', 'b', 'c']

const proxyData = new Proxy(data, {
    
    
    get(target, key, receiver) {
    
    
        // 只处理本身(非原型的)属性
        const ownKeys = Reflect.ownKeys(target) // 获取对象的键
        if (ownKeys.includes(key)) {
    
    
            console.log('get', key);  // 监听
        }
        const result = Reflect.get(target, key, receiver)
        console.log('get', key);
        return result // 返回结果
    },
    set(target, key, val, receiver) {
    
    
        // 重复的数据,不处理
        const oldVal = target[key]
        if(val === oldVal) {
    
    
            return true
        }
        const result = Reflect.set(target, key, val, receiver)
        console.log('set', key, val)
        console.log('result', result); // true
        return result // 是否设置成功
    },
    deleteProperty(target, key) {
    
    
        const result = Reflect.deleteProperty(target, key)
        console.log('delete property', key);
        console.log('result', result); // true
        return result // 是否删除成功
    }
})

inserte la descripción de la imagen aquí

3. Función de reflejo

  • Correspondencia uno a uno con capacidades de Proxy
  • Normalizado, estandarizado, funcional
  • Sustitución de funciones de utilidad en el objeto
    inserte la descripción de la imagen aquí

4. Proxy implementa capacidad de respuesta

  • Monitoreo profundo, mejor rendimiento (escuchar cuando sea necesario)
  • Puede monitorear propiedades nuevas/eliminadas
  • Los cambios de matriz se pueden monitorear
  • El proxy puede evitar el problema de Object.defineProperty
  • El proxy no es compatible con todos los navegadores y no se puede polillenar (se usa para implementar código que los navegadores no admiten API nativas)

Ejemplo: Reactivo con Proxy

  • El monitoreo profundo no es un monitoreo de una sola vez, sino solo cuando se usa.
// 创建响应式
function reactive(target = {
     
     }) {
    
    
    if (typeof target !== 'object' || target == null) {
    
    
        // 不是对象或数组
        return target
    }

    // 代理配置
    const proxyConf = {
    
    
        get(target, key, receiver) {
    
    
            // 只处理本身(非原型的)属性
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
    
    
                console.log('get', key); // 监听
            }
            const result = Reflect.get(target, key, receiver)

            // 深度监听
            // 性能如何提升的? 什么时候 get 到,什么时候去做响应式
            return reactive(result) // 返回结果
        },
        set(target, key, val, receiver) {
    
    
            // 重复的数据,不处理
            const oldVal = target[key]
            if (val === oldVal) {
    
    
                return true
            }

            // 监听是已有的键还是新增的键
            const ownKeys = Reflect.ownKeys(target)
            if (ownKeys.includes(key)) {
    
    
                console.log('已有的 key', key);
            } else {
    
    
                console.log('新增的 key', key);
            }

            const result = Reflect.set(target, key, val, receiver)
            console.log('set', key, val)
            return result // 是否设置成功
        },
        deleteProperty(target, key) {
    
    
            const result = Reflect.deleteProperty(target, key)
            console.log('delete property', key);
            console.log('result', result); // tru            return result // 是否删除成功
        }
    }

    // 生成代理对象
    const observed = new Proxy(target, proxyConf)
    return observed
}

// 测试数据
const data = {
    
    
    name: '杂货铺',
    age: 21,
    info: {
    
    
        city: 'beijing'
    }
}

const proxyData = reactive(data)

不积跬步无以至千里 不积小流无以成江海

Pulsa para seguir y no te pierdas, sigue actualizando...

Supongo que te gusta

Origin blog.csdn.net/qq_45902692/article/details/126681278
Recomendado
Clasificación