前言
新的一年,来一波总结~
1、箭头函数没有自己的this值,箭头函数中所使用的this来自于函数作用域链;
2、vue数据代理原理:
1). 通过Object.defineProperty(vm, key, {})给vm添加与data对象的属性对应的属性;
2). 所有添加的属性都包含get/set方法;
3). 在get/set方法中去操作data中对应的属性。
3、computed和watch的区别:
computed执行场景: 1、页面渲染的时候;2、所依赖的值发生变化的时候
watch执行场景:当值第一次绑定的时候,不会执行监听函数,只有值发生改变才会执行。如果我们需要在最初绑定值得时候也执行函数,就需要用到 immediate 属性immediate: true。
immediate 表示在 watch 中首次绑定数据的时候是否执行 handler ,值为 true 则表示在 watch 声明的时候就立即执行 handler 方法,值为 false 时,则和一般使用 watch 一样,在数据发生变化的时候才执行 handler。
1、computed支持缓存,只有依赖数据发生改变,才会重新进行计算;而watch不支持缓存,数据变,直接会触发相应的操作。
2、computed不支持异步 ,当computed内有异步操作时无效,无法监听数据的变化;而watch支持异步。
3、computed属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值;而watch监听的函数接收两个参数,第一个参数是最新的值,第二个参数是输入之前的值。
4、如果一个数据受多个数据影响 ,一般用computed;一个数据影响多个数据,一般用watch。
5、如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有-个get和一 个set方法,当数据变化时,调用set方法。而watch监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其它操作,函数有两个参数。
4、v-show和v-if的区别:
v-show 本质是修改元素的的CSS属性(display)来决定实现显示还是隐藏
v-if 本质是通过操纵dom元素来进行切换显示
v-if需要操作dom元素,有更高的切换消耗,v-show只是修改元素的的CSS属性有更高的初始渲染消耗,如果需要非常频繁的切换,建议使用v-show较好,如果在运行时条件很少改变,则使用v-if较好
5、谈谈重绘(repaint)和回流(reflow)
比如我们增删DOM节点,修改一个元素的宽高,页面布局发生变化,DOM树结构发生变化,那么肯定要重新构建DOM树,而DOM树与渲染树是紧密相连的,DOM树构建完,渲染树也会随之对页面进行再次渲染,这个过程就叫回流。
当你给一个元素更换颜色,这样的行为是不会影响页面布局的,DOM树不会变化,但颜色变了,渲染树得重新渲染页面,这就是重汇。
总结:引起DOM树结构变化,页面布局变化的行为叫回流,且回流一定伴随重绘。
只是样式的变化,不会引起DOM树变化,页面布局变化的行为叫重绘,且重绘不一定会便随回流。
6、当数据发生变化时,vue是怎样更新节点的?
渲染真实DOM的占用是很大的,比如有时我们修改了某个数据,如果直接渲染到真实dom上会引起整个dom树的重绘和重排
有没有可能我们只更新我们修改的那一小块dom而不是更新整个dom呢?回答:diff算法能够帮助我们。
diff算法:
我们先根据真实DOM生成virtual DOM
当virtual DOM某个节点的数据改变后生成一个新的vnode
然后Vnode和oldVnode作对比,发现有不一样的地方就直接修改在真实的DOM上
然后使oldVnode的值为Vnode。
7、v-for循环中:key的作用是什么?key的默认值为index,用index作为key会有什么坑?
key作为列表的唯一标识。
如果用index作为key,在这种特殊情况下会出问题
向一个列表中的最前面添加新数据,根据diff算法,第一个数据进行对比时,先对比key,再对比节点内容,发现节点内容会对不上,从而导致不能复用,重新渲染。这样的写法造成列表所有的key和节点内容都不一样,从而所有列表项都要重新生成真实dom,影响性能。
8、数据监测原理
(1)监测对象
通过setter实现监视,且要在new Vue时就传入要监测的数据。
对象中后追加的属性,Vue默认不做响应式处理,如需给后添加的属性做响应式,请使用如下API:
Vue.set(target,propertyName/index,value) 或者
this.$set(target,propertyName/index,value)
Vue.set()和this.$set()都可以为对象添加一个新属性。
🌹调用方法:this.$set( target, key, value )
🌹 target:要更改的数据源(可以是对象或者数组)
🌹 key:要更改的具体数据
🌹 value :重新赋的值
Vue.set()和this.$set()区别:
1、Vue.set()是将set函数绑定在Vue构造函数上,this.$set()是将set函数绑定在Vue原型上;
2、Vue.set() 只允许给data里面的一个对象新增属性,有局限性。
1 | //创建一个监视的实例对象,用于监视data中属性的变化 |
(2)监测数组
通过数组更新元素的方法实现,本质就是做了两件事:
1.调用原生数组方法对数据进行更新;
2.重新解析模板,进而更新页面。
在vue中修改数组中的某个元素可以使用如下方法:
1.使用这些API: push,pop,shift,unshift,splice, sort,reverse;
2.替换原数组,使用这些API:filter concat slice 。它们虽然不会变更原始数组,而是返回一个新数组。所以可以使用新数组替换旧数组,从而实现数组的变更;
3.使用Vue.set()和this.$set()。
注意:
在Vue2.x中数组变化监听的问题,其实不是Object.definePropertype方法监听不到,而是为了性能和收益比例综合考虑之下,改变了监听方式,从原本的直接监听结果变化这种思路变换到监听会导致结果变化的方法上,也就上面所提到的对数组的重写。
而Vue3.0中利用Proxy的方式则完美解决了2.0中出现的问题。
参考链接: https://blog.csdn.net/qq_27053493/article/details/105062078
9、XSS攻击
盗走用户的cookie(用户信息),使用v-html就容易被XSS攻击,所以要确保赋值内容的安全性。
10、v-cloak
解决的问题:
网速过慢时,解决页面展示Mustache标签的问题。
用法:
这个指令保持在元素上直到关联实例结束编译。和 css 规则如
[v-cloak] { display: none }
一起用时,这个指令可以隐藏未编译的 Mustache 标签直到实例准备完毕。
11、自定义指令
注意:
1、自定义指令不支持驼峰的写法,要用‘-’符号连接;
2、自定义指令中的this不是vm,而是window;
(1)自定义指令为函数写法时
1 | directives:{ |
(2)自定义指令为对象写法时
bind
:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。inserted
:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。update
:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
1 | directives:{ |
以上写法为局部指令,全局指令用以下写法:
1 | // 注册一个全局自定义指令 `v-focus` |