1.vue 中data 为什么必须是函数
vue中data必须是函数是为了保证组件的独立性和可复用性,data是一个函数,组件实例化的时候这个函数将会被调用,返回一个对象,计算机会给这个对象分配一个内存地址,你实例化几次,就分配几个内存地址,他们的地址都不一样,所以每个组件中的数据不会相互干扰,改变其中一个组件的状态,其它组件不变。
2.computed 和 watch 的区别
computed:通过属性计算而得来的属性
(1).computed内部的函数在调用时不加()
(2).computed是依赖vm中data的属性变化而变化的,也就是说,当data中的属性发生改变的时候,当前函数才会执行,data中的属性没有改变的时候,当前函数不会执行。
(3).computed中的函数必须用return返回
(4).在computed中不要对data中的属性进行赋值操作。如果对data中的属性进行赋值操作了,就是data中的属性发生改变,从而触发computed中的函数,形成死循环了
(5).当computed中的函数所依赖的属性没有发生改变,那么调用当前函数的时候会从缓存中读取
1. 支持缓存,只有依赖数据发生改变,才会重新进行计算
2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3.computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
4. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
5.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
watch:属性监听
(1).watch中的函数名称必须要和data中的属性名一致,因为watch是依赖data中的属性,当data中的属性发生改变的时候,watch中的函数就会执行。
(2).watch中的函数有两个参数,前者是newVal,后者是oldVal。
(3).watch中的函数是不需要调用的。
(4).watch只会监听数据的值是否发生改变,而不会去监听数据的地址是否发生改变。也就是说,watch想要监听引用类型数据的变化,需要进行深度监听。"obj.name"(){}------如果obj的属性太多,这种方法的效率很低,obj:{handler(newVal){},deep:true}------用handler+deep的方式进行深度监听。
(5).特殊情况下,watch无法监听到数组的变化,特殊情况就是说更改数组中的数据时,数组已经更改,但是视图没有更新。更改数组必须要用splice()或者$set。this.arr.splice(0,1,100)-----修改arr中第0项开始的1个数据为100,this.$set(this.arr,0,100)-----修改arr第0项值为100。
(6).immediate:true 页面首次加载的时候做一次监听。
1. 不支持缓存,数据变,直接会触发相应的操作;
2.watch支持异步;
3.监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
4. 当一个属性发生变化时,需要执行对应的操作;一对多;
5. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,
immediate:组件加载立即触发回调函数执行,
deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。
computed 和 watch 的区别
1、功能上:computed是计算属性,watch是监听一个值的变化,然后执行对应的回调。
2、是否调用缓存:computed中的函数所依赖的属性没有发生变化,那么调用当前的函数的时候会从缓存中读取,而watch在每次监听的值发生变化的时候都会执行回调。
3、是否调用return:computed中的函数必须要用return返回,watch中的函数不是必须要用return。
4、使用场景:computed----当一个属性受多个属性影响的时候,使用computed-------购物车商品结算。watch----当一条数据影响多条数据的时候,使用watch-------搜索框。
3.diff 算法
diff算法的本质就是:找出两个对象之间的差异,目的是尽可能做到节点复用。
diff算法的核心是子节点数组对比,思路是通过首尾两端对比
key的作用主要是
- 决定节点是否可以复用
- 建立key-index的索引,主要是替代遍历,提升性能
最小量更新太厉害啦!真的是最小量更新!当然,key很重要。key是这个节点的 唯一标识,告诉diff算法,在更改前后它们是同一个DOM节点。
• 只有是同一个虚拟节点,才的细化比较,否则就是暴力删除旧的、插入新的。
延伸问题:如何定义是同一个虚拟节点?答:选择器相同且key相同。
• 只进行同层比较,不会进行跨层比较。即使是同一片虚拟节点,但是跨层了,对 不起,精细化比较不di什你,而是暴力删除旧的、然后插入新的。
4.$nextTick()
的原理
Vue 异步更新 DOM,$nextTick 就是用来知道什么时候DOM更新完成的
$nextTick()
返回一个Promise
对象,所以你可以使用新的 ES2017 async/await 语法完成相同的事情需要知道 事件循环(Event Loop)
原理如下:
vue用异步队列的方式来控制DOM更新和nextTick回调先后执行
microtask因为其高优先级特性,能确保队列中的微任务在一次事件循环前被执行完毕
因为兼容性问题,vue不得不做了microtask向macrotask的降级方案
5.provide inject 的实现原理
Vue3 的 Provide / Inject 的实现原理其实就是巧妙利用了原型和原型链来实现的
6.keep-alive的作用
keep-alive可以在组件切换时,保存其包裹的组件的状态,使其不被销毁,防止多次渲染
7.vue 的两个特性
数据驱动视图,双向数据绑定