2024-8-18 打卡第十二天 学习视频链接
Object.defineProperty与Proxy的区别
- vue2.x 使用Object.defineProperty进行代理。vue3.x 使用Proxy进行代理
- 使用Object.defineProperty进行代理会产生的问题
- 不能监听数组的变化
- 必须遍历对象的每个属性,使用Object.keys()解决
- 必须深层遍历嵌套的对象
- 关于Proxy
- 针对整个对象
- 解决了无法劫持数组的问题
- 有更多拦截方法,有助于性能的提升
promise相关方法
- promise instanceof Promise 如果当前项是Promise实例,则尝试解决它;如果不是(如示例中的promise3),则直接将其视为已fulfilled的值,并添加到结果数组中
- if(count === promises.length) 每当一个promise解决时,
count
递增。当count
等于传入的promises数组的长度时,意味着所有promises都已解决(无论是fulfilled还是rejected),此时可以解析外层Promise,并返回结果数组res
<script>
function allSettled(promises){
return new Promise((resolve,reject) => {
const res = [];
let count = 0;
const addData = (status,value,i) => {
res[i] = {
status,
value
}
count++;
if(count === promises.length){
resolve(res)
}
};
promises.forEach((promise,index) => {
if(promise instanceof Promise){
promise.then(res => {
addData('fulfilled',res,index)
},err => {
addData('rejected',err,index)
})
}else{
addData('fulfilled',promise,index)
}
})
})
}
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Error'));
const promise3 = 3; // 非Promise值
allSettled([promise1, promise2, promise3]).then(results => {
console.log(results);
});
</script>
- 仿照race (允许同时执行多个Promise任务,并返回一个新的Promise实例。这个新的Promise实例的解决(fulfilled)或拒绝(rejected)状态将由传入的Promise数组中第一个解决或拒绝的Promise决定)
function race(promises){
return new Promise((resolve,reject) => {
promises.forEach(promise => {
if(promise instanceof Promise){
promise.then(res => {
resolve(res);
},err => {
reject(err);
})
} else{
resolve(promise);
}
})
})
}
const promise1 = Promise.resolve(1);
const promise2 = new Promise((resolve, reject) => setTimeout(reject, 100, 'Error'));
const promise3 = 3; // 非Promise值
race([promise1, promise2, promise3]).then(results => {
console.log(results);
});
vue组件中的通信方式
- 父子之间
- props 父组件向子组件
- emit 子组件向父组件
- parent 获得父组件实例
- child 获得子组件
- 兄弟之间
- parent
- root
- eventsBus
- vuex
- 跨层级
- eventBus
- vuex
- provide inject
v-if和v-for优先级
- 不推荐一起使用。比如<li v-for="todo in todos" v-if="!todo.isComple">会报错,因为此时v-if判断条件中的to还不存在,官方解决方法如下
<script>
<template v-for="todo in todos">
<li v-if="!todo.isComplete"></li>
</template>
</script>
- vue2中,v-for的优先级高于v-if。渲染组件会先进性循环在进行判断,哪怕只渲染一部分元素也会遍历整个列表。vue3中,v-if的层级高于v-for
vue生命周期以及每个周期
- beforeCreate:在组件实例创建之初,内部的data等都获取不到
- created:实例创建完成,真实的js对象
- beforeMount:组件挂载之前的事情
- mounted:组件挂载到实例触发,视图已经更新
- beforeUpdate:组件的数据发生变化,在真正更新前
- updated:数据更新后
- beforeDestory:组件销毁前
- destoryed:组件销毁之后
- activated:keep-alive 激活时执行
- deactivated:keep-alive 停止时使用
- errorCaptured: 错误日志监听 vue.config.errorHandle
- renderTracked renderTriggered serverPrefetch
vue双向绑定原理和使用
- v-model:双向绑定指令
- v-model更倾向于是一个语法糖
- 基本在表单上使用 <input v-model="XX">
vue响应式
- vue2:object.defineProperty getter. setter Vue.$set动态触发数据监听,项目过程中就有碰到这个问题,已经将接口的结果赋值给变量了,然后再调用方法去添加属性,要不更换顺序,要不添加属性的时候使用set,不然这个数据的更新无法监听
- vue3:Proxy
- vue给响应式对象,比如data里定义的对象,都加了一个__ob__属性,如果一个对象有这个__ob__属性,就说明这个对象是响应式对象,修改对象已有属性的时候会触发页面渲染,非data里定义的就不是响应式对象
vue模版渲染原理
- template{{}} -> compiler 将模版转换成js,再最终转换成html对象,模版编译
- 实现跨平台的原因,编译成js后,js就是一个数据结构,然后根据不同的api编译成相应的语言进行页面渲染,实现了跨平台
- 模版对应的原理更多是一个编译原理
- parse:先通过一些条件判断,正则,进行一层层解析,解析成完成对象,从template转换为AST
- AST -> 哪些节点发生改变,发生改变就加tag,最终再页面渲染进行diff的时候根据tag进行更新
- generate AST-> render 转换成真实的DOM