1、Vue的优点和缺点?
1.1、优点
渐进式、组件化,轻量级,虚拟dom,响应式,单页面路由,数据与视图分开。
1.2、缺点
单页面不利于seo,不支持IE8以下,首屏加载时间过长。
2、为什么说Vue是渐进式框架?
渐进式:通俗点老讲就是,你想用啥就用啥,没有过多的强求;不用多做职责之外的事情。
3、Vue和React的异同点?
相同点:
- 1、都是用了虚拟
dom。 - 2、组件化开发。
- 3、都是单向数据流(父子组件之间,不建议子修改父传下来的数据)。
- 4、都支持服务端渲染。
不同点:
- 1、
React的JSX,Vue的template。 - 2、数据变化,
React手动(setState),Vue自动(初始化已做响应式处理,Object.defineProperty)。 - 3、
React单向绑定,Vue双向绑定。 - 4、
React的Redux,Vue的Vuex。
4、Vue和JQuery的区别在哪?为什么放弃JQuery用Vue
- 1、
JQuery是直接操作DOM,Vue不直接操作DOM,Vue的数据和视图是分开的,Vue只需要操作数据即可。 - 2、在操作
DOM频繁的场景里,JQuery的操作DOM行为是频繁的,而Vue利用虚拟DOM技术,大大提高了更新DOM时的性能。 - 3、
Vue中不提倡直接操作DOM,开发者只需要把大部分精力放在数据层面上。 - 4、
Vue集成了一些库,大大提高了开发效率。比如Vuex、Router等。
5、为什么data是个函数并且返回一个对象呢?
data之所以是一个函数,是因为一个组件可能会多处调用,而每一次调用都会执行data函数并返回一个新的数据对象,这样可以避免多处调用之间的数据污染。
6、组件之间的传值方式有哪些?
- 父组件传值给子组件,子组件使用
props进行接收。 - 子组件传值给父组件,子组件使用
$emit+事件对父组件进行传值。 - 组件中可以使用
$parent和$children获取到父组件实例和子组件实例,进而获取数据。 - 使用
¥attrs和$listeners,在对一些组件进行二次封装的时候可以方便传值,例如A->B->C。 - 使用
$refs获取组件实例,进而获取数据。 - 使用
Vuex进行状态管理。 - 使用
eventBus进行跨组件触发事件,进而传递数据。 - 使用
provide和inject,官方建议我们不要用这个,我在看ElementUI源码时发现大量使用。 - 使用浏览器本地缓存,例如
localStorage。
7、 路由有哪些模式呢?又有什么不同呢?
-
hash模式:通过#号后面的内容的更改,触发hashchange事件,实现路由切换。 -
history模式:通过pushState和replaceState切换url,实现路由切换,需要后端配合
8、 如何设置动态class,动态style?
- 动态
class对象:
<div:class="{'is-active':true, 'red': isRed}"></div>
- 动态
class数组:
<div:class="T'is-active! isRed ? 'red' : " ""></div>
- 动态
style对象:
<div:style="{ color:textColor, fontSize: '18px' }"></div>
- 动态
style数组:
<div :style="E color:textColor, fontSize: '18px' }, { fontWeight:'300' }"></div>
9、v-if 和v-show有何区别?
- 1、
v-if是通过控制dom元素的删除和生成来实现显隐,每一次显隐都会使组件重新跑一遍生命周期,因为显隐决定了组件的生成和销毁. - 2、
v-show是通过控制dom元素的css样式来实现显隐,不会销毁。 - 3、频繁或者大数量显隐使用
v-show,否则使用v-if。
10、computed 和 watch 有何区别?
- 1、
computed是依赖已有的变量来计算一个目标变量,大多数情况都是多个变量凑在一起计算出一个变量,并且computed具有缓存机制,依赖值不变的情况下其会直接读取缓存进行复用,computed不能进行异步操作。 - 2、
watch是监听某一个变量的变化,并执行相应的回调函数,通常是一个变量的变化決定多个变量的变化,watch可以进行异步操作。 - 3、简单记就是:一般情况下
computed是多对一,watch是一对多。
11、 为什么v-if和v-for不建议用在同一标签?
在vue2中,v-for优先级是高于v-if的,咱们来看例子
<div v-for="item in [1, 2,3,4,5,6,7]" v-if="item !== 3">
{item}}
</div>
上面的写法是v-for和v-if同时存在,会先把7个元素都遍历出来,然后再一个个判断是否为3,并把3给隐藏掉,这样的坏处就是,渲染了无用的3节点,增加无用的dom操作,建议使用computed来解决这个问题:
<div v-for="item in list">
{{item}}
</div>
computed({
list(){
return [1, 2, 3, 4, 5, 6, 7].filter (item => item!== 3)
}
}
12、watch有哪些属性,分别有什么用?
当我们监听一个基本数据类型时:
watch:{
value(){
//do something
}
}
当我们监听一个引用数据类型时:
watch:{
obj:{
handler(){//执行回调
//do something
},
deep:true,//是否进行深度监听
immediate:true//是否初始执行handler函数
}
}
13、父子组件生命周期顺序
父beforeCreate-> 父created -> 父beforeMount -> 子beforeCreate -> 子created-> 子beforeMount -> 子mounted -> 父mounted。
14、对象新属性无法更新视图,删除属性无法更新视图,为什么?怎么办?
- 原因:
Object.defineProperty没有对对象的新属性进行属性劫持。 - 对象新属性无法更新视图:使用
Vue.$set(obj,key,value)。 - 删除属性无法更新视图:使用
Vue.$delete(obj,key),组件中this.$delect(obj.key)。
15、直接arr[index] = xxx 无法更新视图怎么办?为什么?怎么解决?
- 原因:Vue没有对数组进行
Object.defineProperty的属性劫持,所以直接arr[index] = xxx是无法更新视图的。 - 使用数组的
splice方法,arr.splice(index,1,item)。 - 使用
Vue.$set(arr,index,value)。
16、vue 的SSR 是什么?有什么好处?
-
SSR就是服务端渲染。 - 基于
nodejs serve服务环境开发,所有html代码在服务端渲染。 - 数据返回给前端,然后前端进行“激活”,即可成为浏览器识别的
html代码。 -
SSR首次加载更快,有更好的用户体验,有更好的seo优化,因为爬虫能看到整个页面的内容如果是vue项目,由于数据还要经过解析,这就造成爬虫并不会等待你的数据加载完成,所以其实vue 项的
seo体验并不是很好。
17、 vue 响应式是怎么实现的?
整体思路是数据劫持+观察者模式
对象内部通过defineReactive方法,使用Object.defineProperty将属性进行劫持 (只会劫持已经存在的属性),数组则是通过重写数组方法来实现。当页面使用对应属性时,每个属性都拥有自己的dep属性,存放他所依赖的watcher (依赖收集),当属性变化后会通知自己对应的watcher去更新(派发更新)。
18、 为什么只对对象劫持,而要对数组进行方法重写?
因为对象最多也就几十个属性,拦截起来数量不多,但是数组可能会有几百几千项,拦截起来非常耗性能,所以直接重写数组原型上的方法,是比较节省性能的方案。
19、vue.set方法的原理?
function set (target, key, val) {
//判断是否是数组
if (Array.isArray (target)) {
//判断谁大谁小
target.length = Math.max(target.length,key)
//执行 splice
target.splice (key, 1, val)
return val
}
const ob = target.__ob__
//如果此对象没有不是响应式对象,直接设置并返回
if (key in target && ! (key in target.prototype) || !ob){
target[key] = val
return val
//否则,新增属性,并响应式处理
defineReactive (target, key, val)
return val
}
20、如果子组件改变props 里的数据会发生什么?
- 改变的
props数据是基本类型
如果修改的是基本类型,则会报错
props: {
num: Number,
}
created(){
this.num = 999
}
Ietvuc wornJ : Avoid rucatins a prop cirectiy since the voiuc wsll oe overaritten wncnever she parent cotponcnt re-renacrs• insteoa, use a aoti
- 改变的
props数据是引用类型
props: {
item: {
default: () => ({})
}
}
created{}
//不报错,并且父级数据会跟着变
this.item.name ='sanxin';
//会报错,跟基础类型报错一样
this.item = 'sss'
}
21、props怎么自定义验证?
props: {
num: {
default: 1.
validator: function (value) {
//返回值为false 则验证不通过,报错
return{
[1, 2, 3, 4, 5].indexOf (value) !== -1
}
}
}
22、watch的immediate 属性有什么用?
比如平时created时要请求一次数据,并且当搜索值改变,也要请求数据,我们会这么写:
created{
this.getList()
},
watch: {
searchInputvalue(){
this.getList()
}
}
使用immediate完全可以这么写,当它为true时,会初始执行一次
watch: {
searchInputValue:{
handler: 'getList',
immediate:true
}
}
23、计算变量时,methods 和computed 哪个好?
<div>
<div>{{howMuch1()}}</div>
<div>{{howMuch}2}</div>
<div>{{findex}}</div>
</div>
data: () {
return {
index: 0
}
},
methods: {
howMuch1(){
return this.num + this.price
}
},
computed: {
howMuch2() {
return this.num + this.price
}
}
computed会好一些,因为computed会有缓存。例如index由0变成1,那么会触发视图更新,这时候methods会重新执行一次,而computed不会,因为computed依赖的两个变量num和price都没变。
24、如何将获取 data 中某一个数据的初始状态?
在开发中,有时候需要拿初始状态去计算。例如
data(){
return{
num: 10
}
}
mounted(){
this.num = 1000
}
methods: {
howMuch(){
//计算出num增加了多少,那就是1000-初始值
//可以通过 this. $options.data0.xxx 来获取初始值
console.log(1000 - this.$options.data().num)
}
}
25、自定义v-model
默认情况下,v-model是@input事件侦听器和:value属性上的语法糖。但是,你可以在你的vue 组件中指定一个模型属性来定义使用什么事件和value属性。
export default: {
model: {
event: 'change',
prop: 'checked'
}
}
26、相同的路由组件如何重新渲染?
开发人员经常遇到的情况是,多个路由解析为同一个vue组件。问题是,vue出于性能原因默认情况下共享组件将不会重新渲染,如果你尝试在使用相同组件的路由之间进行切换,则不会发生任何变化。
const routes = [
{
path: "/a",
component: MyComponent
},
{
path: "/b",
component: MyComponent
},];
如果依然想重新渲染,怎么办呢?可以使用key
<template>
<router-view :key="$route.path"></router-view>
</template>









网友评论