1.说说你对SPA单页面的理解。它的优缺点分别是什么?
SPA仅在Web页面初始化加载相应的HTML、Javascript和CSS,一旦页面加载完成,SPA不会因为用户的操作而进行页面的重新加载或跳转,取而代之的是利用路由机制实现HTML内容的变换,UI与用用户的交互,避免页面重新加载。
优点
- 用户体验好,快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染
- 基于上面一点,SPA相对对服务器压力小
- 前后端分离职责,架构清晰,前端进行交互逻辑,后端负责数据处理
缺点
- 初次加载耗时多,为实现单页Web应用功能及显示效果,需要再加载页面的时候讲Javascript、CSS统一加载,部分页面按需加载
- 前进后退路由管理,由于单页应用再同一个页面中显示所有内容,所以不能使用浏览器的前进后退功能,所有页面切换需要自己建立堆栈管理
- SEO难度较大,由于所有的内容都在一个页面中动态显示,所以再SEO上有天然的劣势
2.v-show和v-if的区别
v-if是真正的条件渲染,因为它会确保再切换过程中条件快内的事件监听和子组件适当地被销毁和重建,也是惰性的,如果在出事渲染时条件为假,则什么也不做,直到条件第一次编程真时才会开始渲染条件快
v-show就简单得多不管条件是什么,元素总会被渲染,并且知识简单地基于CSS的’display’属性进行切换
所以,v-if适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show则适用于需要非常频繁切换条件的场景
3.Class和Style如何动态绑定
Class可以通过对象语法和数组语法进行动态绑定
- 对象语法
<div :class="{ active: isActive, 'text-danger' : hasError }></div>
data: {
isActive: true,
hasError: false
}
- 数组语法
<div :class="[ isActive? activeClass : '', errorClass ]></div>
data: {
activeClass: 'active'
errorClass: 'text-danger'
}
Style也可以通过对象语法和数组语法进行动态绑定
- 对象语法
<div :style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeCOlor: 'red',
fontSize: 30
}
- 数组语法
<div :style="[ styleColor,styleSize ]"></div>
data: {
styleColor: {
color: 'red'
},
styleSize: {
fontSize: '23px'
}
4.怎么理解Vue的单项数据流
所有的prop都使得其父子prop之间形成了一个单向下行绑定: 父级prop的过呢更新会向下流动到自组件中,但是反过来则不行,这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。
额外的,每次父级组件发生更新的时,子组件中所有的prop都将会刷新成最新的值,这意味着你不应该在一个子组件内部改变prop,如果你这样做了,Vue会在浏览器的控制台发出警告,子组件想修改时,只能通过 $emit 派发要给自定义事件,父组件接受到后,由父组件修改
有两种常见的试图改变一个 prop 的情形:
- 这个prop用来传递一个初始值,这个自u见接下来希望将其作为本地的 prop数据来使用,在这种情况下,最好定义一个本地的data属性并将这个prop用作其初始值
props: ['initialCounter']m
data: function {
return {
counter: this.initalCounter
}
}
- 这个prop以一种原始值的传入且需要进行转换。 在这种情况下,最好使用这个porp的值来定义一个计算属性
props: ['size'],
computed: {
normalizedSize: function() {
return this.size.trim().toLowerCase()
}
}
5.computed 和 watch 的区别和应用的场景
computed
: 是计算属性,以来其他属性值,并且computed的值有缓存,只有它依赖的属性值发生改变,下一次获取computed的值才会重新计算computed的值
watch
: 更多的是[观察]的作用,类似某些数据的监听回调,每当监听的数据变化时都会执行回调进行后续操作。
运用场景
-
当我们需要进行数值计算,并且依赖于其他数据时,应该使用computed,因为可以利用computed的缓存特性,避免每次获取值时,都要重新计算。
-
当我们需要在数据变化时执行异步或者开销较大的操作时,应该使用watch,使用watch选项允许我们执行异步操作(访问一个API),限制我们执行操作的频率,并在我们得到最终结果前,设置中间状态,这些都是计算属性无法做到的。
6.直接给一个数组项赋值,Vue能检测到变化吗
由于Javascript的限制,Vue不能检测到以下数组的变动:
- 当你利用索引值设置一个数组项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组长度的时, 例如:
vm.items.length =- newLength
为了解决第一个问题,Vue提供了以下操作方法:
// Vue.set
Vue.set(vm.items, indexOfItem ,newValue)
// vm.$set,Vue.set的一个别名
vm.$set(vm.items, indexOfItem ,newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
为了解决第二个问题,Vue提供了以下操作方法
// Array.prototype.splice
vm.items.splice(newLengh)
7.谈谈你对Vue生命周期的理解
(1)
(2)
8.Vue的父组件和子组件生命周期钩子函数执行顺序
Vue的父组件和子组件生命周期钩子函数执行顺序可以归类为以下四部分
- 加载渲染过程
父 beforeCrete -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 mounted -> 父 mounted
- 子组件更新过程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
- 父组件更新过程
父 beforeUpdate -> 父 updated
- 销毁过程
父 beforeDestroy -> 子 beforeDestroy -> 子 destoryed -> 父 destoryed
9.在哪个生命周期内调用异步请求
可以在钩子函数created,beforeMount,mounted中进行调用,因为在这三个钩子函数中,data已经创建,可以将服务器端返回的数据进行赋值,但是我推荐在created钩子函数中调用异步请求,因为在created钩子函数中调用异步请求有以下优点
- 能更快获取到服务端数据,减少页面loading时间
- ssr不支持beforeMount、mounted钩子函数,所以放在created有助于一致性。
10.组件中的data为什么是一个函数
为什么组件中data必须是一个函数,然后return一个对象,而new Vue实例里,data可以直接是一个对象
// data
data() {
return {
message: '子组件',
childName: this.name
}
}
// new Vue
new Vue({
el: '#app',
router,
template: '<App />',
components: { App }
})
因为组件是用来复用的,且JS里对象是引用关系,如果组件中data是一个对象,那么这样作用域没有隔离,子组件中的data属性值会相互影响,如果组件中的data选项是一个函数,那么每个实例可以维护一份被返回对象的独立的拷贝,组件实例之间的data属性值不会相互影响,而new Vue的实例,是不会被复用的,因此不存在引用对象的问题.