VUE高频面试题

1、生命周期都有哪些,以及在这些生命周期中都做过哪些事情

beforeCreate创建之前;无法获取响应数据

created创建之后,可以在这加个loading事件和进行数据请求

beforeMount挂载前 ,在这结束loading,还做一些初始数据的获取,实现函数自执行

mounted挂载后 ,在这发起后端请求,拿回数据,配合路由钩子做一些事情

beforeUpdate数据更新之前

updated数据更新完成之后

beforeDestroy销毁之前 ,你确认删除XX吗?或者确认退出吗?

destroyed销毁之后 ,当前组件已被删除,清空相关内容,在这获取不到dom了


2、组件通信

父传子:props、$attrs/$listeners、$children、$root、provide/inject、$refs

子传父:$emit、$parent、

同级传:eventBus、vuex


3、页面通信

url拼接参数:"/a?a1=a1",接收页面:this.$route.query.a1

query传参:{path: 'a', query: {a2:'a2'}},接收页面:this.$route.query.a2

params传参:{name: 'a', params: {a3:'a3'}},接收页面:this.$route.params.a3

动态路由传参:/path/a4 ,接收页面:this.$route.params.id,路由:path: "/a/:id"


4、$set是干什么的

当数据变化但没有更新视图时使用,例如对象新增加的属性,数组新增加的成员

this.$set(obj,"key","value")


5、$nextTick是干什么的

在下次 DOM 更新循环结束之后执行延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。

例如:在created生命周期中想要操作dom就可以使用

this.$nextTick(()=>{ ... })可以在mounted之前的生命周期中操作dom


6、mixin是干什么的

提供了一种非常灵活的方式,来分发 Vue 组件中的可复用功能。一个混入对象可以包含任意组件选项。当组件使用混入对象时,所有混入对象的选项将被“混合”进入该组件本身的选项。

var mixin = {
  data: function () {
    return {
      message: 'hello',
      foo: 'abc'
    }
  }
}
​
new Vue({
  mixins: [mixin],
  data: function () {
    return {
      message: 'goodbye',
      bar: 'def'
    }
  },
  created: function () {
    console.log(this.$data)
    // => { message: "goodbye", foo: "abc", bar: "def" }
  }
})


7、简单说说MVVM的理解

MVVM 是 Model-View-ViewModel 的缩写。 Model代表数据模型,也可以在 Model中定义数据修改和操作的业务逻辑。 View 代表UI 组件,它负责将数据模型转化成 UI 展现出来。 ViewModel 监听模型数据的改变和控制视图行为、处理用户交互,简单理 解就是一个同步View 和 Model的对象,连接Model和View。 在MVVM架构下,View 和 Model 之间并没有直接的联系,而是通过ViewModel进行交互,Model 和 ViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也 会立即反应到View 上。 ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起 来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关 注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维 护完全由 MVVM 来统一管理。


8、watch和computed的区别

Watch只能监听data中的数据变化,computed不需要,watch可以进行异步操作, computed不可以,computed不修改原始数据,通过return返回处理的数据,可以包含大 量的逻辑运算


9、v-if和v-show的区别

9.1、v-show 只是简单的控制元素的 display 属性,而 v-if 才是条件渲染(条件为真,元素将会被渲染,条件为假,元素会被销毁);

9.2、v-show 有更高的首次渲染开销,而 v-if 的首次渲染开销要小的多;

9.3、v-if 有更高的切换开销,v-show 切换开销小;

9.4、v-if 有配套的 v-else-if 和 v-else,而 v-show 没有

9.5、v-if 可以搭配 template 使用,而 v-show 不行


10、为什么不能v-for和v-if一起使用

v-for 优先级是比 v-if 高

永远不要把 v-if 和 v-for 同时用在一个元素上,带来性能方面的浪费(每次渲染都会先循环再进行条件判断)

如果避免出现这种情况,则在外层嵌套 template (页面渲染不生成dom节点),再这一层进行 v-if 判断,然后再内部进行 v-for 循环

<template v-if="isShow">
    <p v-for="item in items">
</template>

如果条件出现再循环内部,可通过计算属性 computed 提前过滤掉那些不需要显示的项

computed:{
    items:function(){
        return this.list.filter(function(item){
            return item.isShow
        })
    }
}


11、key的作用是什么,值写index和id哪个更好

key是为每个vnode指定唯一的id,在同级vnode的Diff过程中,可以根据key快速的进 行对比,来判断是否为相同节点, 利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快,指定key后,可以 保证渲染的准确性(尽可能的复用 DOM 元素。)赋值时应优先使用id。


12、过滤器怎么使用

// 全局使用
Vue.filter('globalFilter', function(){
    // ...
})
​
// 局部使用
filters: {
    formatMoney(num) {
        // ...
    },
}
<p>过滤器{{ money | formatMoney }}</p>


13、vuex五大核心分别是干什么的

state:Vuex中的基本数据,辅助函数mapState

getters:即从store的state中派生出的状态,有点类似计算属性,辅助函数mapGetters

mutations:是更改Vuex中的store中的状态的唯一方法,是同步的,辅助函数mapMutations

actions:Action 提交的是 mutation,而不是直接变更状态。 Action 可以包含任意异步操作。辅助函数mapActions

Modules:Vuex 允许我们将 store 分割到模块(module)。每个模块拥有自己的 state、mutations、actions、getters、甚至是嵌套子模块——从上至下进行类似的分割


14、如何调用mutations和actions的方法

调用mutations:$store.commit('mutations中定义的方法')
​
调用actions:$store.dispatch('actions中定义的方法')
​
actions调用mutations中的方法:
​
fn(context){
​
    context.commit('mutations中定义的方法');
​
}


15、vue-router常写属性都有什么

router-link常用属性:

to表示目标路由的链接

replace设置replace属性的话,当点击时,会调用roter.replace()而不是router.push(),所以导航后不会留下history记录,也就是不能回退到上一个页面

append设置append属性后,则在当前路径前添加基路径,例如,我们从/a导航到一个相对路径b,如果没有配置append,则路径为/b,如果配了,则为/a/b

tag 有时候想要<router-link>渲染成某种标签,例如<li>。于是我们使用tag prop 类指定何种标签,同样它还是会监听点击,触发导航。

active-class 设置链接激活时使用的css类名。默认值可以通过路由的构造选项linkActiveClass来全局配置, 默认值为 ‘router-link-active‘

exact "是否激活",默认是false 。

vue-router常用属性:

path路由路径

name路由名字

component导入路由组件

redirect路由重定向

mode路由模式

children子路由

meta路由元信息


16、路由守卫都有哪些以及都做过哪些事情,三个参数分别是干什么的

全局守卫:beforeEach(登录拦截)、afterEach

路由独享守卫:beforeEnter(部分路由的登录拦截)

组件内守卫:beforeRouteEnter(权限管理)、beforeRouteUpdate、beforeRouteLeave

路由全局解析守卫:beforeResolve(这里根据单页面name的指向不同,去访问的接口域名也不同)

三个参数:to:去哪,from:从哪来,next:下一步

当从a页面离开进入b页面时触发的生命周期
    1.beforeRouteLeave:路由组件的组件离开路由前钩子,可取消路由离开。
    2.beforeEach: 路由全局前置守卫,可用于登录验证、全局路由loading等。
    3.beforeEnter: 路由独享守卫
    4.beforeRouteEnter: 路由的组件进入路由前钩子。
    5.beforeResolve:路由全局解析守卫
    6.afterEach:路由全局后置钩子
    7.beforeCreate:组件生命周期,不能访问this。
    8.created:组件生命周期,可以访问this,不能访问dom。
    9.beforeMount:组件生命周期
    10.deactivated: 离开缓存组件a,或者触发a的beforeDestroy和destroyed组件销毁钩子。
    11.mounted:访问/操作dom。
    12.activated:进入缓存组件,进入a的嵌套子组件(如果有的话)。
    13.执行beforeRouteEnter回调函数next。


17、hash和history模式的区别

hash模式就是url后面写#锚点,由于 hash 值变化不会导致浏览器向服务器发出请求,而且 hash 改变会触发 hashchange 事件(hashchange只能改变 # 后面的url片段);更关键的一点是,因为hash发生变化的url都会被浏览器记录下来,从而你会发现浏览器的前进后退都可以用了,所以人们在 html5 的 history 出现前,基本都是使用 hash 来实现前端路由的

history模式:hash 能兼容到IE8, history 只能兼容到 IE10;hash 本来是拿来做页面定位的,如果拿来做路由的话,原来的锚点功能就不能用了。其次,hash 的传参是基于 url 的,如果要传递复杂的数据,会有体积的限制,而 history 模式不仅可以在url里放参数,还可以将数据存放在一个特定的对象中。history api可以分为两大部分:切换(back、forward、go)和修改(pushState,replaceState)。history模式的问题:就怕刷新,


18、说说常用指令有哪些,如何自定义指令

v-if :如果是真则渲染节点,否则不渲染节点

v-if、v-else 和 v-else-if :类似js的if...else判断语句

v-show :通过display:none;控制元素显示隐藏

v-for :循环,v-for的优先级高于v-if,不推荐一起使用

v-bind :绑定属性,

v-on :绑定事件,

.stop 阻止事件继续传播

.prevent 事件不再重载页面

.capture 使用事件捕获模式,即元素自身触发的事件先在此处处理,然后才交由内部元素进行处理

.self 只当在 event.target 是当前元素自身时触发处理函数

.once 事件将只会触发一次

.passive 告诉浏览器你不想阻止事件的默认行为

v-model :数据双向绑定

.lazy 默认情况下,v-model同步输入框的值和数据。可以通过这个修饰符,转变为在change事件再同步。

.number 自动将用户的输入值转化为数值类型

.trim 自动过滤用户输入的首尾空格

v-text 和 v-html :用来更新textContent和输出真正的html结构

v-pre :主要用来跳过这个元素和它的子元素编译过程。

v-cloak :保持在元素上直到关联实例结束时进行编译。

v-once :关联的实例,只会渲染一次。之后的重新渲染,实例极其所有的子节点将被视为静态内容跳过,这可以用于优化更新性能。

// 自定义指令 v-focus
  directives: {
    focus: {
      // 指令的定义
      inserted: function(el) {
        el.focus();
      },
    },
  },


19、vue插槽如何使用

// 比如新建一个<base-layout> 组件
<div class="container">
  <header>
    <slot name="header"></slot>
  </header>
  <main>
    <slot></slot>
  </main>
  <footer>
    <slot name="footer"></slot>
  </footer>
</div>
// 使用插槽
<base-layout>
  <template v-slot:header> // 或者 <template #header>
    <h1>Here might be a page title</h1>
  </template>
​
  <template v-slot:default>
    <p>A paragraph for the main content.</p>
    <p>And another one.</p>
  </template>
​
  <template v-slot:footer>
    <p>Here's some contact info</p>
  </template>
</base-layout>
​
// 作用域插槽,比如新建一个<current-user>组件
<span>
  <slot v-bind:user="user">
    {{ user.lastName }}
  </slot>
</span>
// 使用插槽
<current-user>
  <template v-slot:default="slotProps">
    {{ slotProps.user.firstName }}
  </template>
</current-user>
// 或者缩写
<current-user v-slot="slotProps">
  {{ slotProps.user.firstName }}
</current-user>
​
​
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值