1、Vue中的修饰符有哪些?
修饰符是用于限定类型以及类型成员的声明的一种符号。Vue中修饰符分为如下五种:表单修饰符、事件修饰符、鼠标按键修饰符、键值修饰符和v-bind修饰符。
1)表单修饰符
我们在填写表单时用到最多的就是input标签,指令用的最多的是v-model,关于表单修饰符有lazy、trim、number。
使用.lazy 可以让val1的变化由input事件转化为change事件的时机触发,也就是说用户在输入的时候不会触发,只有在blur的时候才会触发;
使用.trim 默认会对事件的event.target.value 调用一次trim方法,自动过滤用户输入的首空格字符,而中间的空格不会过滤;
使用.number 默认会对值进行一个parseFloat的转换,如果转换失败,保留原来的值。
2)事件修饰符
事件修饰符是对事件捕获以及目标进行了处理。
stop 阻止了事件冒泡,相当于调用了event.stopPropagation方法。
prevent 阻止了事件的默认行为,相当于调用了event.preventDefault方法
self 只当在event.target是当前元素自身时触发处理函数。
once 绑定了事件以后只能触发一次,第二次就不会触发。
passive 当我们在监听元素滚动事件的时候,会一直触发onscroll事件会让我们的网页变卡,因此我们使用这个修饰符的时候,相当于给onscroll事件整了一个.lazy修饰符。
3)鼠标修饰符
left 左键点击;right 右键点击;middle 中键点击。
4)键盘修饰符
键盘修饰符是用来修饰键盘事件。
普通键(enter、tab、delete、space、esc、up...);系统修饰键(ctrl、alt、meta、shift...)
5)v-bind修饰
async 能对props进行一个双向绑定。使用sync的时候,子组件传递的事件名格式必须为update:value,其中value必须与子组件中props中声明的名称完全一致。
props 设置自定义标签属性,避免暴露数据,防止污染HTML结构。
camel 将命名变为驼峰命名法,如将view-Box属性名转换为viewBox
2、nextTick 的原理
Vue 在更新 DOM 时是异步执行的。当数据发生变化,Vue将开启一个异步更新队列,视图需要等队列中所有数据变化完成之后,再统一进行更新。NextTick就是在DOM更新循环结束之后执行延迟回调。
如果没有nextTick 更新机制,那么数据每次更新都会触发视图更新(若改变10万次就是会更新10万次视图),有了nextTick机制,只需要更新一次,所以nextTick本质是一种优化策略。
使用场景:如果想要在修改数据后立刻得到更新后的DOM结构,可以使用Vue.nextTick()。
3、new Vue()过程
1)首先找到vue的构造函数,包含一个options参数。options是用户传递过来的配置项,如data、methods等常用的方法。
2)vue构建函数调用_init方法。
initLifecycle(vm):初始化组件生命周期标志位;
initEvents(vm):初始化组件事件侦听;
initRender(vm):初始化渲染方法;
initInjections(vm):初始化依赖注入内容,在初始化data、props之前;
initState(vm):初始化props/data/method/watch/methods;
vm.$mount(vm.$options.el):挂载元素。
调用beforeCreate之前,数据初始化并未完成,像data、props这些属性无法访问到;
created阶段,数据已经初始化完成,能够访问data、props这些属性,但这时候并未完成dom的挂载,因此无法访问到dom元素;
3)挂载方法是调用vm.$mount方法。
initState(vm)
initState方法是完成props/data/method/watch/methods的初始化。
vm.$mount(vm.$options.el)
获取或查询挂载元素。vue 不允许直接挂载到body或页面文档上;
获取template模板,解析vue模板文件;
将temmplate解析ast tree;
将ast tree转换成render语法字符串;
生成render方法,挂载到vm上后,会再次调用mount方法渲染组件。
监听组件数据,一旦发生变化,触发beforeUpdate生命钩子。
updateComponent方法主要执行在vue初始化时声明的render,update方法。
render的作用主要是生成vnode。调用patch,将vnode转换为真实DOM,并且更新到页面
4、Vue编译原理
Vue编译原理主要分三个部分,也可以说是分三步:
第一步:将模板字符串转换成element ASTs(解析器);
第二步:对AST进行静态节点标记(跳过此节点),主要用来做虚拟DOM的渲染优化(优化器);
第三步:使用element ASTs生成render函数代码字符串(代码生成器)。通过调用这个函数就可以得到模板对应的虚拟DOM。
解析器分为HTML解析器、文本解析器以及过滤器解析器。
HTML解析器是主线,先用HTML解析器进行解析整个模板,在解析过程中如果碰到文本内容,那就调用文本解析器来解析文本,如果碰到文本中包含过滤器那就调用过滤器解析器来解析。
模板解析的过程就是不断调用钩子函数的处理过程。有如下钩子函数:
每当解析到标签的开始位置时,触发该函数start (tag, attrs, unary, start, end),
每当解析到标签的结束位置时,触发该函数end(tag, start, end),
每当解析到文本时,触发该函数chars(text: string, start: number, end: number),
每当解析到注释时,触发该函数comment(text: string, start, end)
整个过程,读取template字符串,使用不同的正则表达式,匹配到不同的内容,然后触发对应不同的钩子函数处理匹配到的截取片段,比如开始标签正则匹配到开始标签,触发start钩子函数,钩子函数处理匹配到的开始标签片段,生成一个标签节点添加到抽象语法树上。解析到{{xxx}}这行文本,此时触发了文本钩子函数chars,处理匹配片段,生成一个带变量文本标签节点并作为上一个节点的子节点添加到AST上;然后解析到结束标签,触发了标签结束的钩子函数end。
5、Vue.use()
Vue.use()是全局注册一个组件或者插件的方法。原理如下:
第一,判断这个插件是否被注册过,如果已经注册了,不允许重复注册。如果插件没有被注册过,那么注册成功之后会给插件添加一个installed的属性,其值为true。Vue.use方法内部会检测插件的installed属性,从而避免重复注册插件.
第二,接收的plugin参数的限制是Function | Object两种类型之一。
自己来实现一个插件也是超级简单,只要对外暴露一个install方法即可,在使用Vue.use的时候,会调用这个方法。
6、keep-alive
keep-alive是Vue的一个内置组件。它能够不活动的组件实例保存在内存中,而不是直接将其销毁,它是一个抽象组件,不会被渲染到真实DOM中,也不会出现在父组件链中。它提供了include与exclude两个属性,允许组件有条件地进行缓存。keep-alive组件的缓存也是基于VNode节点的而不是直接存储DOM结构
created钩子会创建一个cache对象,用来作为缓存容器,保存vnode节点。
destroyed钩子则在组件被销毁的时候清除cache缓存中的所有组件实例。
Render函数首先通过getFirstComponentChild获取第一个子组件,获取该组件的name。接下来会将这个name通过include与exclude属性进行匹配,匹配不成功(说明不需要进行缓存)则不进行任何操作直接返回vnode。
根据key在this.cache中查找,如果存在则说明之前已经缓存过了,直接将缓存的vnode的componentInstance(组件实例)覆盖到目前的vnode上面。否则将vnode存储在cache中。
用watch来监听pruneCache与pruneCache这两个属性的改变,在改变的时候修改cache缓存中的缓存数据。
keep-alive提供了两个生命钩子,分别是activated与deactivated。
因为keep-alive会将组件保存在内存中,并不会销毁以及重新创建,所以不会重新调用组件的created等方法,需要用activated与deactivated这两个生命钩子来得知当前组件是否处于活动状态。