1, vue2 响应式原理的缺点及解决办法?
响应式 : 数据改变 ==> 视图跟着改变
原理:
1).(第一步,就是把data变成响应式数据)通过Object.defineProperty遍历对象的每一个属性,把每一个属性变成getter和setter函数。读取属性的时候就它就会运行getter,给属性赋值的时候就会运行setter。就是把data变成响应式数据。
2).(第二步骤响应式数据和界面挂钩)组建里有render函数。模版里写的任何东西都会变成render函数。会生成虚拟Dom树,就会影响到界面。当我们运行render函数的时候,里面用到的一些数据,(比如说 h(“h1”,this.msg),这里的this.msg就是来源于响应式数据,如果是使用msg的时候就会运行对应的getter,这个getter就会记录当前有一个函数就render,这个render用到这个msg属性。这个过程就叫依赖收集,收集的就是watcher,将来对msg属性重新赋值的时候,比如 this.masg=“saddsadsa”,这个时候就会运行对应的setter,这个setter就会根据这个属性对应的watcher,去通知/派发更新对于的render。render函数重新执行,就会重新生成虚拟daom树)
https://blog.csdn.net/qq_44603011/article/details/122672396
https://blog.csdn.net/Qiemo_/article/details/124788613
答案:
Object.defineProperty(obj,'name', {
get() {},
ser() {}
})
1.由于只有get()、set() 方式,所以只能捕获到属性读取和修改操作,当 新增、删除属性时,捕获不到,导致界面也不会更新。无法监听到对象属性的动态添加和删除。
2无法监听到数组下标和length长度的变化,(数组的部分操作没有响应式)
解决方式:通过this.delete
2, vue2重写了数组哪些方法。
数组的部分操作没有响应式
数组中有7种操作有响应式
array.pop()
array.push()
array.shift()
array.unshift()
array.sort()
arry.reverse()
array.splice()
以上7中API会修改原数组(vue2的内部重写了这7个API)
其他的操作都不会有响应式,数据修改了,但是视图不更新
比如:
this.arr[0] = 100
this.arr.length = 0
3, vue3中的ref为什么要用.value取值?为什么返回一个对象?
https://blog.csdn.net/weixin_46182770/article/details/124506669
总结:ref接受的值是单值时,可以是一个数字,也可以是布尔值,字符串,那如何知道它被get了,有何时被set了?Proxy的拦截是针对于对象,这种情况下就行不通了,实现的方案就是通过对象包裹,使用class类来实现,在类中可以定义value值,可以实现get set方法,也就可以知道了何时触发get,set了,也就是可以进行依赖收集和触发依赖。
这样也就是 Vue3 中为何需要用ref进行值类型的包裹,也就是为何内部需要一个.value这样的程序设计。
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/zhouxingqi_123/article/details/134400991
4 ,vue3哪方面比vue2好?vue2的缺点。
?????
5 , vue 2,vue3 双向数据绑定原理
?????
6 前端首页白屏
7 webpack中Proxy代理接口跨域的工作原理
8 GET和POST的区别
区别:1、post请求更安全;post请求不会作为url的一部分,不会被缓存、保存在服务器日志、以及浏览器浏览记录中,get请求的是静态资源,则会缓存,如果是数据,则不会缓存。2、post请求发送的数据更大,get请求有url长度限制。3、post请求能发送更多的数据类型,get请求只能发送ASCII字符。4、传参方式不同。5、get产生一个TCP数据包;post产生两个。
9 HTTP 状态消息 200 301 302 304 403 404 500 分别表示什么?
状态码【200】表示【请求成功】,一般在GET和POST请求中可以见到;
状态码【301】表示【资源永久重定向】;
状态码【302】表示【资源临时重定向】;
状态码【304】表示【所请求的资源并未修改】;
状态码【403】表示【服务器拒绝执行客户端的请求】;
状态码【404】表示【服务器找不到客户端所请求的资源(网页)】;
状态码【500】表示【服务器内部错误】。
10 什么是js尾递归
函数调用自身,称为递归。
当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。
递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。
11 ,weakmap和weakset是什么
12, Vue中更新是异步还是同步的,为什么?
数据是同步更新,视图是异步更新
因为如果视图更新是同步的,那会导致多次渲染浪费不必要的性能,没必要,内部做了去重(重新更新的值)和防抖(只更新最后一次)
13 nexttick原理
vue2
复杂的说:
nextTick是全局vue的一个函数,在vue系统中,用于处理dom更新的操作。vue里面有一个watcher,用于观察数据的变化,然后更新dom,vue里面并不是每次数据改变都会触发更新dom,而是将这些操作都缓存在一个队列,在一个事件循环结束之后,刷新队列,统一执行dom更新操作。
在vue生命周期的created()钩子函数进行的DOM操作要放在Vue.nextTick()的回调函数中,因为created()钩子函数执行的时候DOM并未进行任何渲染,而此时进行DOM操作是徒劳的,所以此处一定要将DOM操作的JS代码放进Vue.nextTick()的回调函数中。
而与之对应的mounted钩子函数,该钩子函数执行时所有的DOM挂载和渲染都已完成,此时该钩子函数进行任何DOM操作都不会有个问题。
简单的说:
在Vue内部,nextTick之所以能够让我们看到DOM更新后的结果,是因为我们传入的callback会被添加到列队刷新函数(flushSchedulerQueue)的后面,这样等队列内部的更新函数都执行完毕,所有DOM操作也就结束了,callback自然能够获取到最新的DOM值。
将传入的回调函数包装成异步任务,异步任务又分微任务和宏任务,为了尽快执行所以优先选择微任务;
nextTick 提供了四种异步方法 Promise.then、MutationObserver、setImmediate、setTimeout(fn,0)
注意:vue3抛弃了兼容性,直接使用Promise,来实现nextTick
14. vue2的diff算法的比对过程
vue2 diff算法
Vue2是一款流行的JavaScript框架,它采用了一种高效的Diff算 法来实现数据的更新和渲染。Diff算法是一种比较两个数据结构之 间差异的算法,它可以在更新数据时,只更新需要更新的部分,从 而提高性能和效率。
Vue2的Diff算法主要分为三个步骤:创建虚拟DOM树、比较新 旧虚拟DOM树、更新真实DOM树。
第一步:创建虚拟DOM树
在Vue2中,每个组件都有一个虚拟DOM树,它是一个JavaScript 对象,用来描述组件的结构和状态。当组件需要更新时,Vue2会先 创建一个新的虚拟DOM树,然后与旧的虚拟DOM树进行比较,找 出需要更新的部分。
第二步:比较新旧虚拟DOM树
Vue2的Diff算法采用了一种双端比较的策略,即从新旧虚拟DOM 树的两端开始比较,逐层向内进行比较。如果发现两个节点不同, 就停止比较,将这个节点及其子节点标记为需要更新。
在比较过程中,Vue2还采用了一些优化策略,例如:如果两个节 点的标签名不同,就不需要比较它们的子节点;如果两个节点的 key不同,也不需要比较它们的子节点。
第三步:更新真实DOM树
在比较完成后,Vue2会根据标记的节点,更新真实DOM树。这个 过程是非常高效的,因为Vue2只更新需要更新的部分,而不是整 个DOM树。
总结
Vue2的Diff算法是一种高效的算法,它可以在更新数据时,只更 新需要更新的部分,从而提高性能和效率。Vue2的Diff算法主要分 为三个步骤:创建虚拟DOM树、比较新旧虚拟DOM树、更新真实 DOM树。在比较过程中,Vue2还采用了一些优化策略,例如:双 端比较、标签名和key的比较等。这些优化策略可以使Vue2的Diff 算法更加高效和灵活。
15 vue中$set原理
function set(target, key, val) {
if (isUndef(target) || isPrimitive(target)) {
warn(("无法在未定义、null或基元值上设置被动属性"));
}// 对数组的处理
if (Array.isArray(target) && isValidArrayIndex(key)) {
target.length = Math.max(target.length, key);
target.splice(key, 1, val);
return val
}// target已经存在对应的key
if (key in target && !(key in Object.prototype)) {
target[key] = val;
return val
}// 新增的属性的处理
var ob = (target).__ob__;
if (target._isVue || (ob && ob.vmCount)) {
warn("target不能是vue的实例或根数据对象");
return val
}
if (!ob) {
target[key] = val;
return val
}
defineReactive$$1(ob.value, key, val);
ob.dep.notify();
return val
}
Vue.prototype.$set = set;
16 Vue中keep-alive原理
总结:
Vue.js内部将DOM节点抽象成了一个个的VNode节点,keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构。它将满足条件(pruneCache与pruneCache)的组件在cache对象中缓存起来,在需要重新渲染的时候再将vnode节点从cache对象中取出并渲染。
详情解答:https://blog.csdn.net/weixin_43804496/article/details/125523619
或者 https://blog.csdn.net/cyg_l02/article/details/127813373 更详细
17 computed 原理
18 computed 和watch区别
computed和watch的区别
1、computed是计算属性;watch是监听,监听data中的数据变化。
2、computed支持缓存,当其依赖的属性的值发生变化时,计算属性会重新计算,反之,则使用缓存中的属性值;watch不支持缓存,当对应属性发生变化的时候,响应执行。
3、computed不支持异步,有异步操作时无法监听数据变化;watch支持异步操作。
4、computed第一次加载时就监听;watch默认第一次加载时不监听。
immediate 组件创建时刻执行与否
immediate: true,第一次加载时监听(默认为false)
deep 深度监听 不推荐使用(非常的消耗性能)
监听的属性是对象的话 不开启deep 对象子属性变化不会触发watch
开启了deep 对象内部所有子属性变化 都会触发watch
5、computed中的函数必须调用return;watch不是。
6、使用场景:
computed:一个属性受到多个属性影响,如:购物车商品结算。
watch:一个数据影响多条数据,如:搜索数据。
数据变化响应,执行异步操作,或高性能消耗的操作,watch为最佳选择。