一、组件中的data为什么必须是一个函数?
一个组件被复用多次的话,就会创建多个实例。本质上,这些实例用的都是同一个构造函数。如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数
二、Computed和watch
相同点:都可以观察属性的变化从而做出响应
不同点:
计算属性computed更多是作为缓存功能的观察者,它可以将一个或者多个data的属性进行复杂的计算生成一个新的值,提供给渲染函数使用,当依赖的属性变化时,computed不会立即重新计算生成新的值,而是先标记为脏数据,当下次computed被获取时候,才会进行重新计算并返回。
而监听器watch并不具备缓存性,监听器watch提供一个监听函数,当监听的属性发生变化时,会立即执行该函数
三、nextick实现原理是什么?
setImmediate(function () { console.log(1); }, 0); setTimeout(function () { console.log(2); }, 0); newPromise(function (resolve) { console.log(3); resolve(); console.log(4); }).then(function () { console.log(5); }); console.log(6); process.nextTick(function () { console.log(7); }); console.log(8); //输出结果是3 4 6 8 7 5 2 1
四、v-model的原理
v-model本质就是一个语法糖,可以看成是value + input方法的语法糖。
//可以通过model属性的prop和event属性来进行自定义。
原生的v-model,会根据标签的不同生成不同的事件和属性。
如下代码<input v-model="test">本质上是<input :value="test" @input="test = $event.target.value"> 在自定义组件中 <my-component v-model="inputValue"></my-component> 相当于 <my-component :value="inputValue" @input="inputValue = argument[0]"></my-component> 这个时候,inputValue接受的值就是input事件的回调函数的第一个参数,所以在自定义组件中,要实现数据绑定,还需要$emit去触发input的事件。 this.$emit('input', value)
五、Vue事件绑定原理说一下
原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。
六.Vue模版编译原理
简单说,Vue的编译过程就是将template转化为render函数的过程。会经历以下阶段:
生成AST树:使用大量的正则表达式对template字符串进行解析,将标签、指令、属性等转化为抽象语法树AST
优化::遍历AST,找到其中的一些静态节点并进行标记,方便在页面重渲染的时候进行diff比较时,直接跳过这一些静态节点,优化runtime的性能
codegen:将最终的AST转化为render函数字符串