Vue 实现数据绑定的原理(面试题)
vue数据绑定是通过 数据劫持和观察者模式 的方式来实现的
1、数据劫持:使用Object.defineProperty();
当你把一个普通的 JavaScript 对象(json)传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的属性,并使用 Object.defineProperty 把这些属性全部转为 getter/setter。
目的是:感知属性的变化。当给属性赋值时,程序是能够感知的(知道的)。如果知道的话,就可以控制属性值的有效范围,也可以改变其它属性的值等。
Object.defineProperty()函数:https://blog.csdn.net/jiang7701037/article/details/102785223
2、观察者模式(发布订阅模式): 目的:当属性发生变化时,其它使用该数据地方跟着变化
面试题: v-if和 v-show的区别?
相同点:
v-show和 v-if都是 控制 dom元素 的 显示和隐藏 的。
不同点:
1、原理:
v-show是通过控制元素的样式属性display的值,来完成显示和隐藏;
v-if是通过对dom元素的添加和删除,完成显示和隐藏
2、使用场景:由原理(做法)得出使用场景的区别
v-show:使用在dom元素频繁切换的场景
v-if:当dom元素的切换不频繁,可以使用。特别是,首次元素处于隐藏的情况下。
另外,v-if指令还可以结合v-else-if , v-else一起使用。
虚拟DOM和diff算法
什么是虚拟DOM(virtual DOM):
所谓的虚拟 dom,也就是我们常说的虚拟节点,它是通过JS的Object对象模拟DOM中的节点,然后再通过特定的render(渲染)方法将其渲染成真实的DOM的节点。
为什么使用虚拟DOM:
使用js操作DOM时(增删改查等等),那么DOM元素的变化自然会引起页面的回流(重排)或者重绘,页面的DOM重绘自然会导致页面性能下降,那么如何尽可能的去减少DOM的操作是框架需要考虑的一个重要问题!
https://blog.csdn.net/jiang7701037/article/details/98516468
真实DOM和虚拟DOM的区别:
虚拟DOM不会进行排版与重绘操作
真实DOM频繁排版与重绘的效率是相当低
虚拟DOM进行频繁修改,然后一次性比较并修改真实DOM中需要改的部分,最后并在真实DOM中进行排版与重绘,减少过多DOM节点排版与重绘损耗
虚拟DOM有效降低的重绘与排版,因为最终与真实DOM比较差异,可以只渲染局部
diff算法:
虚拟DOM,是一种为了尽可能减少页面DOM频繁操作DOM的方式,那么在虚拟DOM中,通过什么方式才能做到呢? 就是Diff算法进行对比
diff算法的原理:
逐步解析newVdom的节点,找到它在oldVdom中的位置,如果找到了就移动对应的DOM元素,如果没找到说明是新增节点,则新建一个节点插入。遍历完成之后如果oldVdom中还有没处理过的节点,则说明这些节点在newVdom中被删除了,删除它们即可。
总结:
1、产生两个虚拟DOM树:newVDom,oldVDom。
2、oldVDom和真实DOM保持一致
3、操作的newVDom
4、操作完毕后,通过diff算法对比newVDom和oldVDom的差异,并在oldVDom标注哪些节点要删除,哪些节点要增加,修改
5、根据oldVDom操作真实的DOM,让真实Dom和oldVDom保持一致
组件编写方式与 Vue 实例的区别:
1、 data是个函数(面试题)
一个组件的 data 选项必须是一个函数,且要有返回object,只有这样,每个实例(vue组件对象)就可以维护一份被返回对象的独立的拷贝,否则组件复用时,数据相互影响,也就是说,组件的作用域是独立的。
2、组件模板(html代码)只能有一个根标签
3、组件名不可和html官方的标签名同名
4、组件没有el选项,只有根实例存在el
5、书写:组件名如果小驼峰,那么使用时,用短横线(羊肉串的写法),或者组件名直接都用大驼峰。
生命周期(面试题)
每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会
链接
https://blog.csdn.net/jiang7701037/article/details/83118665
vue对象核心的四个阶段八个钩子函数:
1)、数据挂载 阶段 :把把传入的data属性的内容,赋给vue对象。即:把形参中data的属性赋给vue对象。
前后分别的钩子函数是:beforeCreate、created
2)、模板渲染阶段:把vue对象中data渲染到dom对象上。
前后分别的钩子函数是:beforeMount、mounted
3)、组件更新阶段:当数据发生变化时,会触发组件的更新,组件会重新渲染。
前后分别的钩子函数是:beforeUpdate、updated
4)、组件销毁阶段:
前后分别的钩子函数是:beforeDestroy、destroyed
如果组件在缓存的话,那么,组件切换时,会调用的钩子函数是:
activated 和 deactivated
总结:
1、vue组件(对象)从创建到(初次)显示在用户眼前:经历了 beforeCreate,created,beforeMount,mounted
2、数据(必须在模板中使用的数据)更新:调用beforeUpdate和updated函数
3、为什么叫钩子函数
vue项目input标签checkbox,change和click绑定事件的区
click执行的时间要早于change执行的时间,因为v-modal的时间是一个异步的。
当点击之后,v-modal可能还没有来得及将绑定在data里面的数据改变,click绑定的事件就执行了,这会导致click绑定事件里面拿到的data数据不是最新的。
change绑定的事件是一定要等到input框的value值改变之后才会被触发。
关于这一系列的顺序我是这样理解
点击input框–> click事件生效 --> v-modal改变绑定的data数据 --> 渲染到页面上改变input的value值 --> change事件生效
get和post的区别
1、相同点:
都是发送请求时的请求方式
2、不同点:
get:数据是出现在地址栏中,不安全,请求速度快,传输少量数据,如:查询数据。
post:数据在请求体中,安全,请求速度慢,传输大量数据,如:登录,注册,添加商品。
Ajax、jQuery ajax、axios和fetch的区别
Ajax:
ajax:最早出现的前后端交互技术,是原生js,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回调地狱。
Jquery Ajax:
jquery Ajax是原生ajax的封装
Fetch:
fetch是ES6新增的,Fetch是基于promise设计的。fetch不是ajax的进一步封装,而是原生js。Fetch函数就是原生js,没有使用XMLHttpRequest对象。
axios:
axios是原生ajax的封装,基于promise对象的。Axios也可以在请求和响应阶段进行拦截。它不但可以在客户端使用,也可以在nodejs端使用。
动态创建dom
-
vue更新dom是异步队列的方式。vue的数据更新后,不会理解更新dom。如果想在dom更新后,做些事情,就用nextTick。
-
this.$nextTick(回调函数);这个函数里是知道什么时候处理dom的,当你传入回调函数时,nextTick内部会在处理完dom后,调用该回调函数
this.$nextTick(()=>{
new Swiper(".swiper-container", {
autoplay: true,
// loop: true, // 循环模式选项
initialSlide: 1,
// 如果需要分页器
pagination: {
el: ".swiper-pagination"
},
// 如果需要前进后退按钮
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
},
// 如果需要滚动条
scrollbar: {
el: ".swiper-scrollbar"
}
});
});