vue相关知识(非原创)
1.对于Vue是一套渐进式框架的理解
渐进式代表的含义是:主张最少,没有多做职责之外的事。
-
比如Angular,它两个版本都是强主张的,如果你用它,必须接受以下东西:
必须使用它的模块机制- 必须使用它的依赖注入- 必须使用它的特殊形式定义组件(这一点每个视图框架都有,难以避免)所以Angular是带有比较强的排它性的,如果你的应用不是从头开始,而是要不断考虑是否跟其他东西集成,这些主张会带来一些困扰。 -
比如React,它也有一定程度的主张,它的主张主要是函数式编程的理念,比如说,你需要知道什么是副作用,什么是纯函数,如何隔离副作用。它的侵入性看似没有Angular那么强,主要因为它是软性侵入。
-
Vue可能有些方面是不如React,不如Angular,但它是渐进的,没有强主张,你可以在原有大系统的上面,把一两个组件改用它实现,当jQuery用;也可以整个用它全家桶开发,当Angular用;还可以用它的视图,搭配你自己设计的整个下层用。你可以在底层数据逻辑的地方用OO和设计模式的那套理念,也可以函数式,都可以,它只是个轻量视图而已,只做了自己该做的事,没有做不该做的事,仅此而已。
2.Vue的两个核心
数据驱动、组件系统
数据驱动:ViewModel,保证数据和视图的一致性。
组件系统(组件化):应用类UI可以看作全部是由组件树构成的。
3.v-if 和 v-show 有什么区别
V-show指令是通过修改元素的display的css样式使其显示隐藏
V-if指令是销毁和重建DOM达到让元素显示隐藏
4.Vue的常用的修饰符
1.事件修饰符
- .stop 阻止点击事件冒泡。等同于JavaScript中的event.stopPropagation()
- .prevent 防止执行预设的行为(如果事件可取消,则取消该事件,而不停止事件的进一步传播),等同于JavaScript中的event.preventDefault(),prevent等同于JavaScript的event.preventDefault(),用于取消默认事件。
- .capture 与事件冒泡的方向相反,事件捕获由外到内,捕获事件:嵌套两三层父子关系,然后所有都有点击事件,点击子节点,就会触发从外至内 父节点-》子节点的点击事件
- .self 只会触发自己范围内的事件,不包含子元素
- .once 只执行一次,如果我们在@click事件上添加.once修饰符,只要点击按钮只会执行一次。
- .passive Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。这个 .passive 修饰符尤其能够提升移动端的性能。不要把 .passive 和 .prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。
2.键盘修饰符
- .enter:回车键
- .tab:制表键
- .delete:含delete和backspace键
- .esc:返回键
- .space: 空格键
- .up:向上键
- .down:向下键
- .left:向左键
- .right:向右键
3.系统修饰键
可以用如下修饰符来实现仅在按下相应按键时才触发鼠标或键盘事件的监听器。
- .ctrl
- .alt
- .shift
- .meta
- .exact 修饰符允许你控制由精确的系统修饰符组合触发的事件。
4.修饰符
- .lazy 在改变后才触发(也就是说只有光标离开input输入框的时候值才会改变)
- .number 将输出字符串转为Number类型·(虽然type类型定义了是number类型,但是如果输入字符串,输出的是string)
- .trim 自动过滤用户输入的首尾空格
5.Vue中 key 值的作用
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。
打个比方,我们希望可以在B和C之间加一个F,Diff算法默认执行起来是这样的:
把C更新成F,D更新成C,E更新成D,最后再插入E,是不是很没有效率?
所以我们需要使用key来给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,找到正确的位置区插入新的节点。
所以一句话,key的作用主要是为了高效的更新虚拟DOM。
6.$nextTick的使用
虽然 Vue.js 通常鼓励开发人员沿着“数据驱动”的方式思考,避免直接接触 DOM,但是有时我们确实要这么做。为了在数据变化之后等待 Vue 完成更新 DOM ,可以在数据变化之后立即使用Vue.nextTick(callback) 。这样回调函数在 DOM 更新完成后就会调用。
(在dom更新后执行,一般用于dom操作)
7.Vue 组件中 data 为什么必须是函数
在 new Vue() 中,data 是可以作为一个对象进行操作的,然而在 vue组件 中,data 只能以函数的形式存在,不能直接将对象赋值给它。
实际上,它首先需要创建一个组件构造器,然后注册组件。注册组件的本质其实就是建立一个组件构造器的引用。使用组件才是真正创建一个组件实例。所以,注册组件其实并不产生新的组件类,但会产生一个可以用来实例化的新方式。
如果两个实例同时引用一个对象,那么当你修改其中一个属性的时候,另外一个实例也会跟着改。这怎么可以,两个实例应该有自己各自的域才对。所以vue组件里面的data必须是一个函数,这是因为js本身的特性带来的,跟vue本身设计无关。
8.v-for 与 v-if 的优先级
当它们都处于同一节点时,v-for 的优先级高于 v-if。这意味着,v-if 将分别在循环中的每次迭代上运行。
9.Vue组件之间传值
- 父向子传值:属性传值,父组件通过给子组件标签上定义属性,子组件通过props方法接收数据;
- 子向父传值:事件传值,子组件通过$emit(‘自定义事件名’,值),父组件通过子组件上的@自定义事件名=“函数”接收
- 非父子组件传值:全局定义bus,var bus=new Vue() ;
- 发送者,bus.$emit(‘自定义名’,值);
- 接受者,bus.$on(‘自定义名’,(值)=>{})
- 状态管理工具vuex组件之间传值
- ref传值(比较少用)
- .sync修饰符(比较少用)
- provide和inject 父组件中通过provider来提供变量,然后在子组件中通过inject来注入变量(可以隔多代)
10.Vue中 keep-alive 组件的作用
keep-alive是Vue提供的一个抽象组件,用来对组件进行缓存,从而节省性能,由于是一个抽象组件,所以在v页面渲染完毕后不会被渲染成一个DOM元素
被包含在 中创建的组件,会多出两个生命周期的钩子: activated 与 deactivated
activated:在组件被激活时调用,在组件第一次渲染时也会被调用,之后每次keep-alive激活时被调用。
deactivated:在组件被停用时调用。
注意:只有组件被 keep-alive 包裹时,这两个生命周期才会被调用,如果作为正常组件使用,是不会被调用,以及在 2.1.0 版本之后,使用 exclude 排除之后,就算被包裹在 keep-alive 中,这两个钩子依然不会被调用!另外在服务端渲染时此钩子也不会被调用的。
什么时候获取数据?
当引入keep-alive 的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。
别的用法:利用include、exclude属性;利用meta属性
11.什么是Vue生命周期和生命周期钩子函数
vue生命周期就是从开始创建,初始化数据,编译模板,挂载DOM,渲染->更新->渲染,销毁等一系列过程。生命周期钩子如下:
组件实例周期:
BeforeCreate:实例初始化后,无法访问方法和数据;
Created:实例创建完成,可访问数据和方法,注意,假如有某些数据必须获取才允许进入页面的话,并不适合;
beforeMonut:挂载DOM之前
Mounted :el被新创建的vm.$el替换,可获取dom,改变data,注意,beforeRouterEnter的next的钩子比mountend触发靠后;
beforeUpdate:数据更新时调用,发生在虚拟DOM重新渲染前;
Updated:数据更改后,可以执行依赖于DOM的操作,注意,应该避免在此期间更改状态,可能会导致更新无限循环;
beforeDestroy:实例销毁之前,这一步还可以用this获取实例,一般在这一步做重置操作,比如清定时器监听dom事件;
Destroyed:实例销毁后,会解除绑定,移除监听。
(还有keep-alive的activated和deactivated)
12.Vue中监听键盘事件
在Vue中,已经为常用的按键设置了别名,这样我们就无需再去匹配keyCode,直接使用别名就能监听按键的事件。
比如:
.delete 删除键
.enter 回车键
.space 空格键
另外,Vue中还支持组合写法:
@keyup.alt.67=”function” 是 Alt + C
@click.ctrl=”function” 是 Ctrl + Click
但是注意,如果是在自己封装的组件或者是使用一些第三方的UI库时,会发现并不起效果,这时就需要用到.native修饰符了。如果遇到.native修饰符也无效的情况,可能就需要用到$listeners了,具体用法请参考Vue官方文档!
13.Vue中数组更新检测需要注意的
由于 JavaScript 的限制,Vue 不能检测以下数组的变动:
- 当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:vm.items.length = newLength
可以用vm.$set和使用 splice解决数组问题
还是由于 JavaScript 的限制,Vue 不能检测对象属性的添加或删除:
对于已经创建的实例,Vue 不允许动态添加根级别的响应式属性。但是,可以使用 Vue.set(object, propertyName, value) 方法向嵌套对象添加响应式属性。
可以用vm.$set和使用 Vue.set(object, propertyName, value) 解决对象问题
14.Vue中v-model语法糖
v-model 主要是用于表单上数据的双向绑定,主要用于 input,select,textarea,component
<input type="text" v-model="mes">
此时mes值就与input的值进行双向绑定
实际上上面的代码是下面代码的语法糖。
<input v-bind:value="mes" v-on:input="mes= $event.target.value"/>
要理解这行代码,首先你要知道 input 元素本身有个 oninput 事件,这是 HTML5 新增加的,类似 onchange ,每当输入框内容发生变化,就会触发 oninput ,把最新的value传递给 mes。从而实现了v-model
15.Vue优缺点
优点:低耦合,可重用性,独立开发,可测试,渐进式
缺点:不利于SEO,社区维护力度不强,相比还不够成熟
16.什么是MVVM
MVVM是是Model-View-ViewModel的缩写,Model代表数据模型,定义数据操作的业务逻辑,View代表视图层,负责将数据模型渲染到页面上,ViewModel通过双向绑定把View和Model进行同步交互,不需要手动操作DOM的一种设计思想。
17.MVVM和MVC区别
MVVM和MVC都是一种设计思想,主要就是MVC中的Controller演变成ViewModel,,MVVM主要通过数据来显示视图层而不是操作节点,解决了MVC中大量的DOM操作使页面渲染性能降低,加载速度慢,影响用户体验问题。主要用于数据操作比较多的场景。
18.Vue数据双向绑定原理
答:vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
具体步骤:
第一步:需要observe的数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter
这样的话,给这个对象的某个值赋值,就会触发setter,那么就能监听到了数据变化
第二步:compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
第三步:Watcher订阅者是Observer和Compile之间通信的桥梁,主要做的事情是:
1、在自身实例化时往属性订阅器(dep)里面添加自己
2、自身必须有一个update()方法
3、待属性变动dep.notice()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,则功成身退。
第四步:MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。
19.对Vue.js的template编译的理解
答:简而言之,就是先转化成AST树,再得到的render函数返回VNode(Vue的虚拟DOM节点)
详情步骤:
首先,通过compile编译器把template编译成AST语法树(abstract syntax tree 即 源代码的抽象语法结构的树状表现形式),compile是createCompiler的返回值,createCompiler是用以创建编译器的。另外compile还负责合并option。
然后,AST会经过generate(将AST语法树转化成render funtion字符串的过程)得到render函数,render的返回值是VNode,VNode是Vue的虚拟DOM节点,里面有(标签名、子节点、文本等等)
20.vue和react区别
- 相同点:
都鼓励组件化,都有’props’的概念,都有自己的构建工具,Reat与Vue只有框架的骨架,其他的功能如路由、状态管理等是框架分离的组件。
- 不同点:
React:数据流单向,语法—JSX,在React中你需要使用setState()方法去更新状态
Vue:数据双向绑定,语法–HTML,state对象并不是必须的,数据由data属性在Vue对象中进行管理。适用于小型应用,但对于对于大型应用而言不太适合。
21.单页面和多页面的区别
- 单页面:
整个项目中只有一个完整的HTML页面,其它"页面"只是一段HTML片断而已
优: 请求少
缺: 不利于搜索引擎优化
页面跳转本质:把当前DOM树中某个DIV删除,下载并挂载另一个div片断
- 多页面:
项目中有多个独立的完整的HTML页面
缺: 请求次数多,效率低
页面跳转本质:
删除旧的DOM树,重新下载新的DOM树
22.VNode是什么?虚拟DOM是什么?
Vue在页面上渲染的节点,及其子节点称为虚拟节点,简称VNode;虚拟DOM时由组件树建立起来的整个VNode树的称呼