Vue、Angular、React的区别
1.与AngularJS的区别
相同点: 都支持指令:内置指令和自定义指令;都支持过滤器:内置过滤器和自定义过滤器;都支持双向数据绑定;都不支持低端浏览器。
不同点: AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
2.与React的区别
相同点: React采用特殊的JSX语法,Vue.js在组件开发中也推崇编写.vue特殊文件格式,对文件内容都有一些约定,两者都需要编译后使用;中心思想相同:一切都是组件,组件实例之间可以嵌套;都提供合理的钩子函数,可以让开发者定制化地去处理需求;都不内置列数AJAX,Route等功能到核心包,而是以插件的方式加载;在组件开发中都支持mixins的特性。
不同点: React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。
单页面、多页面的区别
单页面的优缺点
优点:
- 具有桌面应用的即时性、网站的可移植性和可访问性
- 用户体验好、快,内容的改变不需要重新加载整个页面
- 良好的前后端分离,分工更明确 缺点:
- 不利于搜索引擎的抓取
- 首次渲染速度相对较慢
v-if、v-show的区别?
控制手段:
- v-if显示隐藏是将dom元素整个添加或删除
- v-show隐藏则是为该元素添加css--display:none,dom元素依旧存在 编译过程:
- v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件
- v-show只是简单的基于css切换
对vue生命周期的理解
总共分为8个阶段创建前/后,载入前/后,更新前/后,销毁前/后。
创建前/后:
- 在beforeCreate阶段,vue实例的挂载元素el和数据对象data都为undefined,还未初始化。
- 在created阶段,vue实例的数据对象data有了,el为undefined,还未初始化。
载入前/后:
- 在beforeMount阶段,vue实例的$el和data都初始化了,但还是挂载之前为虚拟的dom节点,data.message还未替换。
- 在mounted阶段,vue实例挂载完成,data.message成功渲染。
更新前/后:
- 当data变化时,会触发beforeUpdate和updated方法
销毁前/后:
- 在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在
第一次页面加载会触发哪几个钩子
- 会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
DOM 渲染在 哪个周期中就已经完成?
- DOM 渲染在 mounted 中就已经完成了
父子组件生命周期执行顺序
- 首先执行的是父组件的beforeCreate周期
- 执行的是父组件的created周期
- 执行的是父组件的beforeMount周期
- 执行的是子组件的beforeCreate周期
- 执行的是子组件的created周期
- 执行的是子组件的beforeMount周期
- 执行的是子组件的mounted周期
- 执行的是父组件的mounted周期
vue组件中data必须是一个函数
JavaScript只有函数构成作用域(注意理解作用域,只有函数{}构成作用域,对象的{}以及if(){}都不构成作用域),
data是一个函数时,每复用一次组件,就会返回一份新的data,每个组件实例都有自己的作用域,每个实例相互独立,不会相互影响。 如果是写成对象形式,Object是引用数据类型,每个组件的data 都是内存的同一个地址,就会使所有组件实例共用了一份data,一个数据改变了其他也改变了。
Vue中key属性的作用
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。
- 如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。
- 使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
key值的存在保证了唯一性,可以用于dom的重新渲染或是就地复用。
vue在执行时,会对节点进行检查,如果没有key值,那么,vue检查到这里有dom节点,则会对内容进行清空,并且赋予新值;如果有key值的存在,那么vue会对oldnode和newnode进行对比,发现两者key值是否相同,进行调换位置或是删除操作。
key值的作用是:
更精准-->在虚拟dom节点中赋予key值,会更加快速的拿到需要的目标节点,不会造成就地复用的情况,对于节点的把控更加精准。
使用key给每个节点做一个唯一标识,Diff算法就可以正确的识别此节点,为了高效的更新虚拟DOM。
v-modal的使用
v-model用于表单数据的双向绑定,其实它就是一个语法糖,这个背后就做了两个操作:
- v-bind绑定一个value属性;
- v-on指令给当前元素绑定input事件。
computed和watch的区别
计算属性computed:
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
- 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
侦听属性watch:
- 不支持缓存,数据变,直接会触发相应的操作;
- watch支持异步;监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 当一个属性发生变化时,需要执行对应的操作;一对多;
- 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数:
watch: {
'obj.a': {
handler(newName, oldName) {
console.log('obj.a changed');
},
immediate: true, // 组件加载立即触发回调函数执行
deep: true //深入观察,监听器会一层层的往下遍历,给对象的所有属性都加上这个监听器
}
}
vue如何监听对象或者数组某个属性的变化
监听对象的变化:
- watch: 通过watch中的deep属性,监听对象的所有属性。
watch: {
user: {
handler: function (val) {
console.log(val)
},
deep: true
}
},
- object.assign()对象复制:新建一个空对象将对象复制进空对象再赋值给监听的值,这种方法可以监听到对象属性的新增和修改。
this.user = Object.assign({}, this.user)
- this.$set(你要改变的对象,你要改变的key,你要改成什么value)
this.$set(this.obj,'a','tom') // 改变对象
监听数组的变化:
-
watch(同上)
-
this.$set(你要改变的数组,你要改变的位置,你要改成什么value)
this.$set(this.arr,0,'tom') // 改变数组
- 调用数组的方法
splice()、 push()、pop()、shift()、unshift()、sort()、reverse()
$router和$route的区别
-
$route为当前router跳转对象里面可以获取name、path、query、params等
-
$router为VueRouter实例,想要导航到不同URL,则使用router.push方法
vue路由的钩子函数
首页可以控制导航跳转,beforeEach,afterEach等,一般用于页面title的修改。一些需要登录才能调整页面的重定向功能。
beforeEach主要有3个参数to,from,next:
-
to:route即将进入的目标路由对象,
-
from:route当前导航正要离开的路由
-
next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
vue常用的修饰符
- .prevent: 提交事件不再重载页面;
- .stop: 阻止单击事件冒泡;
- .self: 当事件发生在该元素本身而不是子元素的时候会触发;
- .capture: 事件侦听,事件发生的时候会调用
<!-- 阻止单击事件继续传播 -->
<a v-on:click.stop="doThis"></a>
<!-- 提交事件不再重载页面 -->
<form v-on:submit.prevent="onSubmit"></form>
<!-- 修饰符可以串联 -->
<a v-on:click.stop.prevent="doThat"></a>
<!-- 只有修饰符 -->
<form v-on:submit.prevent></form>
<!-- 添加事件监听器时使用事件捕获模式 -->
<!-- 即内部元素触发的事件先在此处理,然后才交由内部元素进行处理 -->
<div v-on:click.capture="doThis">...</div>
<!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
<!-- 即事件不是从内部元素触发的 -->
<div v-on:click.self="doThat">...</div>
Vue组件通信入门之Provide和Inject机制
原理:父组件中通过provide来提供变量,子组件中通过inject来注入变量。
provide/inject需要一起使用,以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
从父组件的provide属性传入一个对象,子组件(或者是孙组件,只要是子级组件)可以用inject属性接收父组件的provide属性。
// 父级组件提供 'foo'
var Provider = {
provide: {
foo: 'bar'
},
// ...
}
// 子组件注入 'foo'
var Child = {
inject: ['foo'],
created () {
console.log(this.foo) // => "bar"
}
// ...
}