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... |
Directorio de artículos
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 // 是否删除成功
}
})
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 // 是否删除成功
}
})
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
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...