vue面试题(重点)

一、Vue生命周期

Vue生命周期都有哪些?

解答:系统自带了八个生命周期,分别是:

  beforeCreate
  created
  beforeMount
  mounted
  beforeUpdate
  updated
  beforeDestroy
  destroyed

一旦进入组件或者一旦进入页面,会执行哪些生命周期?

解答:会之前前面4个

  beforeCreate
  created
  beforeMount
  mounted

如果使用了keep-alive会多出来俩个生命周期

activated
deactivated

如果使用了keep-alive第一次进入组件会执行5个生命周期

beforeCreate
created
beforeMount
mounted
activated

如果使用了keep-alive第二次或者第N次,每次都会执行一个生命周期

activated

二、对keep-alive的了解

  • 1. 是什么

        vue系统自带的一个组件,功能:是来缓存组件的。===》提升性能

  • 2. 使用场景

        就是来缓存组件,提升项目的性能。具体实现比如:首页进入到详情页,如果用户在首页每次点击都是相同的,那么详情页就没必要请求N次了,直接缓存起来就可以了,当然如果点击的不是同一个,那么就直接请求。

三、v-show和v-if是干什么?有什么区别?

v-show

显示和隐藏 : display:none 进行隐藏 、display:block 进行显示     

v-if

创建和删除:remove、append     

区别:

显示和隐藏用:v-show
创建和删除用:v-if
​
频繁切换用:v-show
不频繁切换用:v-if 
​
首次加载:用v-if,不用v-show
为什么:
            如果用v-if可以没有这个盒子,然后再通过v-if进行创建(但是第一次进入页面是没有这个盒子,是不加载的)。
            如果用v-show这个盒子不管是显示还是隐藏,该盒子都是在的(节点都是存在)

使用场景:

v-show : 加入购物车、分享、蒙层这种都基本上用v-show
v-if : 首页栏目切换的时候v-if

四、v-if和v-for 优先级

v-for的优先级要比v-if的优先级高

证明这个事情,是在vue.js源码种10997行

if (el.staticRoot && !el.staticProcessed) {
  return genStatic(el, state)
} else if (el.once && !el.onceProcessed) {
  return genOnce(el, state)
} else if (el.for && !el.forProcessed) {
  return genFor(el, state)
} else if (el.if && !el.ifProcessed) {
  return genIf(el, state)
} else if (el.tag === 'template' && !el.slotTarget && !state.pre) {
  return genChildren(el, state) || 'void 0'
} else if (el.tag === 'slot') {
  return genSlot(el, state)
} else {

注:v-if和v-for不要写在同一个节点上,这个性能很差。(v-if要写在父节点上)

五、ref

是什么?

获取dom

场景?

如果项目中使用插件,并且插件是要获取dom的,那么就可以使用ref了。

六、keep-alive

是什么?

缓存组件

一旦使用keep-alive会多倆个生命周期

activated ​ deactivated

功能

提升性能的

七、nextTick

是什么?

当dom更新完毕执行内部代码

场景

使用插件的时候会用到。例如new Swiper这个插件可能会获取当前元素的宽度或者高度,等dom都加载完毕再去获取宽度和高度就不会有任何问题了。

八、computed、methods、watch区别

computed:计算属性

可以监听某些数据的变化,并且有缓存。

如果一进入页面调用,就会触发

methods : 可以放入函数

没有缓存

如果一进入页面调用,就会触发

watch :监听(路由和数据)

当数据发生改变时,才会触发

可以得到现在的值和过去的值

九、Vue组件的通信(组件的传值)

父传子

父:
<HelloWorld :msg="str" />
<HelloWorld :msg="str" ></HelloWorld>
​
子:
props:['msg']
props: {
    msg: String,
},

子传父

子:
<button @click="changeParentName">改变父组件的name</button>
export default {
    methods: {
        //子组件的事件
        changeParentName: function() {
            this.$emit('handleChange', 'Jack') // 触发父组件中handleChange事件并传参Jack
            // 注:此处事件名称与父组件中绑定的事件名称要一致
        }
    }
}
​
父:
<child @handleChange="changeName"></child>
methods: {
    changeName(name) {  // name形参是子组件中传入的值Jack
        this.name = name
    }
}

兄弟组件传值

创建bus作为中转

import Vue from "vue";
export default new Vue;
A组件:
<button @click='btn'>HelloWorld按钮</button>
data () {
    return {
      hlStr:"这是helloWorld组件的数据"
    }
},
methods:{
    btn(){
      bus.$emit('selectItem',this.hlStr);
    }
}
​
B组件:
created(){
        bus.$on('selectItem',(val)=>{
            console.log( val , 1111);
        })
}

十、slot插槽

使用场景:组件中有些地方的布局可能大多一致,但是细微有些小小变化

十一、Vue路由的高频面试题

SPA单页面应用和传统页面跳转有什么区别?

SPA跳转是一个页面进行切换
​
传统页面跳转就是跳转不同的html了
SPA对于seo部分不是特别好,只能收录一个
​
传统的页面对于seo比较好,多个html文件收录

路径传值

显示:

传:
this.$router.push({
        path:'/about',
        query:{
          key:'你好'
        }
})
接:
this.$route.query

隐示:

传:
this.$router.push({
        name:'About',
        params:{
          key:'你好'
        }
})
接:
this.$route.params

路由的模式

mode: "history"   http://localhost:8080/about

mode:"hash"       http://localhost:8080/#/about

路由导航守卫(拦截、路由钩子函数)

全局

router.beforeEach((to,from,next)=>{})
router.afterEach((to,from,next)=>{})

路由独享

beforeEnter((to,from,next)=>{})

组件内

beforeRouteEnter((to,from,next)=>{})
beforeRouteUpdate((to,from,next)=>	{})
beforeRouteLeave((to,from,next)=>{})

    to         :   这是你跳转到哪个路由对象
    from    :   这是你要离开的路由对象
    next    :   是一个方法,可以接收参数。这个方法是必须调用,如果不使用就跳转不过去,你可以把next看做一个保安,必须要跟next打个招呼你才可以通过。

    next()        ==> 就是告诉保安为要过去,去哪里就是to
    next(false) ==> 可以不通过,中断跳转
    next('/')   ==> 就意思是保安不让过,你可以去另外一个地方进行通过

场景:要去拦截,判断用户是否是登录状态。功能:进入地址管理,用户如果没有登录是进入不了地址管理(在进入之前判断拦截),需要先登录。

子路由、动态路由

子路由:children
动态路由:path: '/user/:id'

十二、Vuex

Vuex有哪些部分构成

state、getters、mutations、actions、modules

什么场景用Vuex

共享、方便管理、方便维护、组件传值......

项目:购物车数据,订单数据,用户的登录信息....

mutations和actions的区别

本质区别:
mutations    必须是同步函数
actions        “可以包含”任意异步操作

使用区别:

mutations中可以放入函数,actions也可以放入函数,但是一般我们在mutations中放入函数而actions是提交mutations

十三、双向绑定原理

原理:
    vue的双向数据绑定,采用的是数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据改变时发布消息给订阅者,从而触发相应的回调来渲染视图。


    它的原理主要有这么几点,首先是需要observer的数据对象进行递归遍历,包括子属性的对象的属性,都加上 setter和getter,那么这样的话,就给这个对象的某个值赋值,从而触发setter,就能监听到了数据变化。

    接着是compile解析模板指令,将模板中的变量替换成数据,然后初始化渲染视图,并将每个指令对应的节点更新,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图。

    最后是Watcher, Watcher订阅者是Observer和Compile之间通信的桥梁,它会在自身实例化时往属性订阅器(dep)里面添加自己,并且自身必须有update()方法,等到属性变动dep.notify()通知时,能调用自身的update()方法,并触发Compile中绑定的回调,然后完成自己的任务。

    



    总的来说,MVVM作为数据绑定的入口,整合Observer、Compile和Watcher三者,通过Observer来监听自己的model数据变化,通过Compile来解析编译模板指令,最终利用Watcher搭起Observer和Compile之间的通信桥梁,达到数据变化 -> 视图更新;视图交互变化(input) -> 数据model变更的双向绑定效果。

十四、vue中key的作用

key的作用主要是为了高效的更新虚拟dom
没有加key,diff默认算法的问题(虚拟dom)

  • 如果节点类型不同,直接干掉前面所有的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点
  • 如果节点类型相同,则会重新设置节点的属性,从而实现节点的更新
     

十五、vue组件data为什么必须是函数

因为JS本身的特性带来的,如果data是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue 实例的数据。如果将data作为一个函数返回一个对象,那么每一个实例的data属性都是独立的,不会相互影响了。

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值