2021前端vue面试题(高频)


Vue相关

***:
##(1)说一下vue最大特点是什么或者说vue核心是什么
答:vue最大特点我感觉就是“组件化“和”数据驱动“
组件化就是可以将页面和页面中可复用的元素都看做成组件,写页面的过程,就是写组件,然后页面是由这些组件“拼接“起来的组件树
数据驱动就是让我们只关注数据层,只要数据变化,页面(即视图层)会自动更新,至于如何操作dom,完全交由vue去完成,咱们只关注数据,数据变了,页面自动同步变化了,很方便

##(2)说一下vue常用基本指令有哪些
v-if:根据表达式的值的真假条件渲染元素。在切换时元素及它的数据绑定 / 组件被销毁并重建。
v-show:根据表达式之真假值,切换元素的 display CSS 属性。
v-for:循环指令,基于一个数组或者对象渲染一个列表,vue 2.0以上必须需配合 key值 使用。
v-bind:动态地绑定一个或多个特性,或一个组件 prop 到表达式。
v-on:用于监听指定元素的DOM事件,比如点击事件。绑定事件监听器。
v-model:实现表单输入和应用状态之间的双向绑定
v-pre:跳过这个元素和它的子元素的编译过程。可以用来显示原始 Mustache 标签。跳过大量没有指令的节点会加快编译。
v-once:只渲染元素和组件一次。随后的重新渲染,元素/组件及其所有的子节点将被视为静态内容并跳过。这可以用于优化更新性能。

1.4、Vue常用的修饰符
v-on 指令常用修饰符:
.stop - 调用 event.stopPropagation(),禁止事件冒泡。
.prevent - 调用 event.preventDefault(),阻止事件默认行为。
.capture - 添加事件侦听器时使用 capture 模式。
.self - 只当事件是从侦听器绑定的元素本身触发时才触发回调。
.{keyCode | keyAlias} - 只当事件是从特定键触发时才触发回调。
.native - 监听组件根元素的原生事件。
.once - 只触发一次回调。
.left - (2.2.0) 只当点击鼠标左键时触发。
.right - (2.2.0) 只当点击鼠标右键时触发。
.middle - (2.2.0) 只当点击鼠标中键时触发。
.passive - (2.3.0) 以 { passive: true } 模式添加侦听器
注意: 如果是在自己封装的组件或者是使用一些第三方的UI库时,会发现并不起效果,这时就需要用`·.native修饰符了,如:
//使用示例:
<el-input
v-model=“inputName”
placeholder=“搜索你的文件”
@keyup.enter.native=“searchFile(params)”
>

v-bind 指令常用修饰符:
.prop - 被用于绑定 DOM 属性 (property)。(差别在哪里?)
.camel - (2.1.0+) 将 kebab-case 特性名转换为 camelCase. (从 2.1.0 开始支持)
.sync (2.3.0+) 语法糖,会扩展成一个更新父组件绑定值的 v-on 侦听器。
v-model 指令常用修饰符:
.lazy - 取代 input 监听 change 事件
.number - 输入字符串转为数字
.trim - 输入首尾空格过滤
Vue 组件中 data 为什么必须是函数
问题一:Vue 组件中 data 为什么必须是函数?
简单回答
//为什么data函数里面要return一个对象

```javascript
<script>
    export default {
        data() {
            return {  // 返回一个唯一的对象,不要和其他组件共用一个对象进行返回
                menu: MENU.data,
                poi: POILIST.data
            }
        }
    }
</script>
```

因为一个组件是可以共享的,但他们的data是私有的,所以每个组件都要return一个新的data对象,返回一个唯一的对象,不要和其他组件共用一个对象。

##(3)说一下v-if和v-show的区别
答:v-if和v-show都可以显示和隐藏一个元素,但有本质区别
v-if是惰性的,只是值为false就不会加载对应元素,为true才动态加载对应元素
v-show:是无论为true和为false都会加载对应html代码,但为false时用display:none隐藏不在页面显示,但为true时页面上用display:block显示其效果

适用场景:切换频繁的场合用v-show,切换不频繁的场合用v-if

##(4)说一下vue自定义指令如何实现的和适用场景?
答:哦,这个问题是这样的,vue除有了v-for,v-if等自带vue指令外,但不能满足所有的开发需求,有时需要自定义指令,自定义指令创建有全局自定义指令和局部自定义指令
全局自定义指令:Vue.directive(‘指令名’,{ inserted(el) { } })
局部自定义指令:directives:{ }
##(5)说一下vue过滤器做什么的(vue1.x和vue2.x这块的区别)
答:vue过滤器主要用于对渲染出来的数据进行格式化处理。例如:后台返回的数据性别用0和1表示,但渲染到页面上不能是0和1我得转换为“男“和”女”,这时就会用到过滤器,还有商品价格读取出来的是普通数值,例如:230035,但我要在前面加个货币符号和千分分隔等,例如变成:¥230,035,都得需要vue过滤器

如何创建过滤器呢,跟创建自定义指令类似,也有全局和局部过滤器的形式

全局过滤器:

```javascript
Vue.filter(‘过滤器名’,function(参数1,参数2,…) {

      //………..
      return 要返回的数据格式
})
```

局部过滤器:在组件内部添加filters属性来定义过滤器

```javascript
fitlers:{
   过滤器名(参数1,参数2,,…参数n) {
       //………..
      return 要返回的数据格式

    }
}
```

##(6)说一下vue生命周期钩子函数有哪些,分别什么时候触发
答:vue生命周期即为一个组件从出生到死亡的一个完整周期,主要包括以下4个阶段:创建,挂载,更新,销毁
创建前:beforeCreate, 创建后:created
挂载前:beforeMount, 挂载后:mounted
更新前:beforeUpdate, 更新后:updated
销毁前:beforeDestroy, 销毁后:destroyed
我平时用的比较多的钩了是created和mounted,created用于获取后台数据,mounted用于dom挂载完后做一些dom操作,以及初始化插件等.beforeDestroy用户清除定时器以及解绑事件等,
另外还新增了使用内置组件 keep-alive 来缓存实例,而不是频繁创建和销毁(开销大)
actived 实例激活
deactived 实例失效
以下为详解版,大家理解就ok:
生命周期钩子函数(11个)Function(类型),标注蓝色的那个是属于类型的意思。
beforeCreate Function 在实例初始化之后,数据观测 (data observer) 和 event/watcher 事件配置之前被调用。
created Function 在实例创建完成后被立即调用。在这一步,实例已完成以下的配置:数据观测 (data observer), 属性和方法的运算,watch/event 事件回调。然而,挂载阶段还没开始, e l 属 性 目 前 不 可 见 。 b e f o r e M o u n t F u n c t i o n 在 挂 载 开 始 之 前 被 调 用 : 相 关 的 r e n d e r 函 数 首 次 被 调 用 。 m o u n t e d F u n c t i o n e l 被 新 创 建 的 v m . el 属性目前不可见。 beforeMount Function 在挂载开始之前被调用:相关的 render 函数首次被调用。 mounted Function el 被新创建的 vm. elbeforeMountFunctionrendermountedFunctionelvm.el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。
beforeUpdate Function 数据更新时调用,发生在虚拟 DOM 打补丁之前。这里适合在更新之前访问现有的 DOM,比如手动移除已添加的事件监听器。该钩子在服务器端渲染期间不被调用,因为只有初次渲染会在服务端进行。
updated Function 由于数据更改导致的虚拟 DOM 重新渲染和打补丁,在这之后会调用该钩子。
activated Function keep-alive 组件激活时调用。该钩子在服务器端渲染期间不被调用。
deactivated Function keep-alive 组件停用时调用。该钩子在服务器端渲染期间不被调用。
beforeDestroy Function 实例销毁之前调用。在这一步,实例仍然完全可用。该钩子在服务器端渲染期间不被调用。
destroyed Function Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。
errorCaptured(2.5.0+ 新增) (err: Error, vm: Component, info: string) => ?boolean 当捕获一个来自子孙组件的错误时被调用。此钩子会收到三个参数:错误对象、发生错误的组件实例以及一个包含错误来源信息的字符串。此钩子可以返回 false 以阻止该错误继续向上传播。

##(7)说一下vue组件通讯(即传值)有哪几种形式,分别是如何实现的
答:vue组件通讯大致有三种:父传子,子传父,还有兄弟之间通讯

   第一种:父传子:主要通过props来实现的
			具体实现:父组件通过import引入子组件,并注册,在子组件标签上添加要传递的属性,子组件通过props接收,接收有两种形式一是通过数组形式[‘要接收的属性’ ],二是通过对象形式{  }来接收,对象形式可以设置要传递的数据类型和默认值,而数组只是简单的接收

   第二种:子传父:主要通过$emit来实现
		   具体实现:子组件通过通过绑定事件触发函数,在其中设置this.$emit(‘要派发的自定义事件’,要传递的值),$emit中有两个参数一是要派发的自定义事件,第二个参数是要传递的值
然后父组件中,在这个子组件身上@派发的自定义事件,绑定事件触发的methods中的方法接受的默认值,就是传递过来的参数

   第三种:兄弟之间传值有两种方法:
			 方法一:通过event bus实现
		具体实现:创建一个空的vue并暴露出去,这个作为公共的bus,即当作两个组件的桥梁,在两个兄弟组件中分别引入刚才创建的bus,在组件A中通过bus.$emit(’自定义事件名’,要发送的值)发送数据,在组件B中通过bus.$on(‘自定义事件名‘,function(v) { //v即为要接收的值 })接收数据

 方法二:通过vuex实现
		具体实现:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括state,actions,mutations,getters和modules 5个要素,主要流程:组件通过dispatch到 actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改变state,从而同步到组件,更新其数据状态

##(8)说一下vue封装组件中的slot作用
答:vue封装组件涉及三个东西:
一是事件(v-on,$emit),
二是传参通过props
三是slot:slot作用主要是可以实现内容分发,组件标签内嵌套内容,可通过来定义占位的内容
分为具名的slot和匿名的slot
在编写可复用组件的时候,时刻考虑组件是否可复用是有好处的。一次性组件跟其他组件紧密耦合没关系,但是可复用组件一定要定义一个清晰的公开接口。
Vue.js组件 API 来自 三部分:prop、事件、slot:
prop 允许外部环境传递数据给组件,在vue-cli工程中也可以使用vuex等传递数据。
事件允许组件触发外部环境的 action(就是行为,也就是方法的意思)
slot 允许外部环境将内容插入到组件的视图结构内。
##(9)说一下vue转场动画如何实现的
答:vue转场动画主要通过vue中的提供的transition组件实现的,例如;

<transition name=”名称”>
        <router-view></router-view>
		</transition>

其中name为转场的名称,自己定义,可通过定义进入和离开两种转场动画,格式为:
.名称-enter { } //将要进入动画
.名称-enter-active { } //定义进入的过程动画
.名称-leave { } //将要离开的动画
.名称-leave-active { } //定义离开过程中的动画

##(10)说一下你对单向数据流的理解
答:单向数据流主要是vue 组件间传递数据是单向的,即数据总是由父组件传递给子组件,子组件在其内部维护自己的数据,但它无权修改父组件传递给它的数据,当开发者尝试这样做的时候,vue 将会报错。这样做是为了组件间更好的维护。
在开发中可能有多个子组件依赖于父组件的某个数据,假如子组件可以修改父组件数据的话,一个子组件变化会引发所有依赖这个数据的子组件发生变化,所以 vue 不推荐子组件修改父组件的数据

##(11)说一下vue双向数据绑定的原理
答:核心主要利用ES5中的Object.defineProperty实现的,然后利用里面的getter和setter来实现双向数据绑定的,大致就这些,其实要实现起来比这个要复杂一些,不过我大致了解过。
##(12)说一下vue路由或前端路由实现原理
答:前端路由实现原理主要通过以下两种技术实现的
第一种:利用H5的history API实现
主要通过history.pushState 和 history.replaceState来实现,不同之处在于,pushState会增加一条新的历史记录,而replaceState则会替换当前的历史记录[发布项目时,需要配置下apache]

   第二种:利用url的hash实现
我们经常在 url 中看到 #,这个 # 有两种情况,一个是我们所谓的锚点,路由里的 # 不叫锚点,我们称之为 hash,我们说的就是hash,主要利用监听哈希值的变化来触发事件 —— hashchange 事件来做页面局部更新

        总结:hash 方案兼容性好,而H5的history主要针对高级浏览器。
以下为具体的API的区别:
this.$router.push(location, onComplete?, onAbort?)	这个方法会向 history 	栈添加一个新的记录,所以,当用户点击浏览器后退按钮时,则回到之前的 URL。并且点击 	<router-link :to="...">等同于调用 router.push(...)。
	this.$router.replace(location, onComplete?, onAbort?)	这个方法不会向 	history 添加新记录,而是跟它的方法名一样 —— 替换掉当前的 history 记录,所以,当用	户点击浏览器后退按钮时,并不会回到之前的 URL。
	this.$router.go(n)	这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似  window.history.go(n)。
以上也可能会形成一个新的面试题:replace和push的区别
可以说,以前在一个项目里面配置了一个二级路由,里面有tab切换部分(详情,评价,说明),因为返回上一页的时候,不能在这几个选项卡之间来回切换.所以我使用了this.$router.replace方法,不计入history记录中,所以不会出现,反复切换的bug

##(13)说一下vue路由钩子(或称vue路由守卫)的理解
什么场景下用到
答:vue路由钩子是在路由跳转过程中拦截当前路由和要跳转的路由的信息,有三种路由钩子:
第一种:全局路由钩子 beforeEach(to,from,next) { }
第二种:路由独享的钩子
beforeEnter(to,from,next) { }
第三种:组件内的钩子
beforeRouteEnter(to,from,next) {
//…
}
beforeRouteUpdate(to,from,next) {
//…
}

beforeRouteLeave(to,from,next) {
   //…
}


  适用场景:动态设置页面标题,判断用户登录权限等:代码示例:
//全局路由导航守卫
vueRouter.beforeEach(function (to, from, next) {
    const nextRoute = [ 'detail'];
    const auth = sessionStorage.getItem("username");    
    let FROMPATH = from.path;
    //跳转至上述3个页面
    if (nextRoute.indexOf(to.name) >= 0) {
    	//上述数组中的路径,是相当于有权限的页面,访问数组列表中的页面就应该是在登陆状态下
        if (!auth) {
			let params = Object.assign({frompath:FROMPATH},from.query);
			next({path: '/newlogin',query:params});
        }
    }
    //已登录的情况再去登录页,跳转至首页
    if (to.name === 'newlogin') {
        if (auth) {
//          vueRouter.push({name: 'index'});
 			next({path: '/'});  
        }
    }
    next();
});

##(14)说一下vue路由懒加载解决什么问题的?
答:vue路由懒加载主要解决打包后文件过大的问题,事件触发才加载对应组件中的js
##(15)说一下如何解决vue首屏加载慢或白屏?
答: 1.路由懒加载
2.开启Gzip压缩
3. 使用webpack的externals属性把不需要打包的库文件分离出去,减少打包后文件的大小
4. 使用vue的服务端渲染(SSR)

##(16)说一下vue开发环境和线上环境如何切换
答:主要通过检测process.env.NODE_ENV===”production”和process.env.NODE_ENV===”development”环境,来设置线上和线下环境地址,从而实现线上和线下环境地址的切换
##(17)说一下你们项目中vue如何跨域的
答:跨域前端和后端都可以实现,如果只针对vue,vue本身可以通过代理的方式可以实现,具体实现:
在config中的index.js中配置proxy来实现:

##(18)说一下vue中methods,computed,watch的区别:
答:methods中都是封装好的函数,无论是否有变化只要触发就会执行
computed:是vue独有的特性计算属性,可以对data中的依赖项再重新计算,得到一个新值,应用到视图中,和methods本质区别是computed是可缓存的,也就是说computed中的依赖项没有变化,则computed中的值就不会重新计算,而methods中的函数是没有缓存的。Watch是监听data和计算属性中的新旧变化。
vue用什么绑定事件,用什么绑定属性
答:用v-on绑定事件,简称:@,用v-bind来绑定属性,简称::属性

##(19)vue如何动态添加属性,实现数据响应?
答:vue主要通过用this.$set(对象,‘属性‘,值)实现动态添加属性,以实现数据的响应注意是添加,我记忆中如果是修改引用类型属性的值,是可以自动渲染的.
##(20)vue中的http请求是如何管理的
答:vue中的http请求如果散落在vue各种组件中,不便于后期维护与管理,所以项目中通常将业务需求统一存放在一个目录下管理,例如src下的API文件夹,这里面放入组件中用到的所有封装好的http请求并导出,再其他用到的组件中导入调用。如下面封装的HTTP请求

##(21)说一下你对axios拦截器的理解:
答:axios拦截器可以让我们在项目中对后端http请求和响应自动拦截处理,减少请求和响应的代码量,提升开发效率同时也方便项目后期维护

##(22)说一下vue和jquey的区别
答:jquery主要是玩dom操作的“神器“,强大的选择器,封装了好多好用的dom操作方法和如何获取ajax方法 例如:$.ajax()非常好用
vue:主要用于数据驱动和组件化,很少操作dom,当然vue可能通过ref来选择一个dom或组件
##(23)说一下vue如何实现局部样式的或者说如何实现组件之间样式不冲突的和实现原理是什么?
答:css没有局部样式的概念,vue脚手架通过实现了,即在style标签上添加scoped
scoped的实现原理:vue通过postcss给每个dom元素添加一个以data-开头的随机自定义属性实现的

##(24)说一下vue第三方ui样式库如何实现样式穿透的(ui库和less/sass穿透问题) >>> /deep/

##(25)vue目录结构(面试时可能会这样问说一下vue工程目录结构):这个了解下就可以
答:统一的目录结构可以方便团队协作和职责明晰,也方便项目后期维护和管理,具体vue项目目录结构包括:
build:项目构建目录
config:项目配置,包括代理配置,线上和线下环境配置
node_modules:node包目录,npm install安装的包都在这个目录
src:平时开发时的目录
static:存入一些静态资源资源目录,我们可以把一些图片,字体,json数据放在这里。
.eslintrc.js:Eslint代码检查配置文件
.babelrc:ES6配置
.gitignore:忽略提交到远程仓库的配置
##(26)vue脚手架是你们公司搭建的,还是用的vue的脚本架?webpack了解多少?
答:我们公司用的vue官方的脚手架(vue-cli),vue-cli版本有3.0和2.9.x版本
webpack是一个前端模块化打包构建工具,vue脚手架本身就用的webpack来构建的,webpack本身需要的入口文件通过entry来指定,出口通过output来指定,默认只支持js文件,其他文件类型需要通过对应的loader来转换,例如:less需要less,less-loader,sass需要sass-loader,css需要style-loader,css-loader来实现。当然本身还有一些内置的插件来对文件进行压缩合并等操作
##(27)说一下你对vuex的理解:
答:vuex是一个状态管理工具,主要解决大中型复杂项目的数据共享问题,主要包括state,actions,mutations,getters和modules 5个要素,主要流程:组件通过dispatch到 actions,actions是异步操作,再actions中通过commit到mutations,mutations再通过逻辑操作改变state,从而同步到组件,更新其数据状态,而getters相当于组件的计算属性对,组件中获取到的数据做提前处理的.再说到辅助函数的作用.
##(28)vuex如何实现数据持久化(即刷新后数据还保留)?
答:因为vuex中的state是存储在内存中的,一刷新就没了,例如登录状态,解决方案有:
第一种:利用H5的本地存储(localStorage,sessionStorage)
第二种:利用第三方封装好的插件,例如:vuex-persistedstate
第三种:使用vue-cookie插件来做存储
第四种:可以把数据传递到后台,存储到数据库中,***比较耗费资源

##(29)说一下nextTick的作用和使用场景?
答:vue中的nextTick主要用于处理数据动态变化后,DOM还未及时更新的问题,用nextTick就可以获取数据更新后最新DOM的变化
适用场景:
第一种:有时需要根据数据动态的为页面某些dom元素添加事件,这就要求在dom元素渲染完毕时去设置,但是created与mounted函数执行时一般dom并没有渲染完毕,所以就会出现获取不到,添加不了事件的问题,这回就要用到nextTick处理
第二种:在使用某个第三方插件时 ,希望在vue生成的某些dom动态发生变化时重新应用该插件,也会用到该方法,这时候就需要在 n e x t T i c k 的 回 调 函 数 中 执 行 重 新 应 用 插 件 的 方 法 , 例 如 : 应 用 滚 动 插 件 b e t t e r − s c r o l l 时 第 三 种 : 数 据 改 变 后 获 取 焦 点 再 来 看 以 下 解 析 : 何 为 nextTick 的回调函数中执行重新应用插件的方法,例如:应用滚动插件better-scroll时 第三种:数据改变后获取焦点 再来看以下解析: 何为 nextTick:betterscroll:nextTick?
简单回答:
因为Vue的异步更新队列,$nextTick是用来知道什么时候DOM更新完成的。
详细解读:
我们先来看这样一个场景:有一个div,默认用 v-if 将它隐藏,点击一个按钮后,改变 v-if 的值,让它显示出来,同时拿到这个div的文本内容。如果v-if的值是 false,直接去获取div内容是获取不到的,因为此时div还没有被创建出来,那么应该在点击按钮后,改变v-if的值为 true,div才会被创建,此时再去获取,示例代码如下:

这是一段文本

Vue会根据当前浏览器环境优先使用原生的Promise.then和MutationObserver,如果都不支持,就会采用setTimeout代替。
知道了Vue异步更新DOM的原理,上面示例的报错也就不难理解了。事实上,在执行this.showDiv = true时,div仍然还是没有被创建出来,直到下一个vue事件循环时,才开始创建。$nextTick就是用来知道什么时候DOM更新完成的,所以上面的示例代码需要修改为:

这是一段文本

##(30) v-for 与 v-if 的优先级
当它们处于同一节点,v-for的优先级比v-if更高,这意味着 v-if将分别重复运行于每个 v-for循环中。当你想为仅有的一些项渲染节点时,这种优先级的机制会十分有用,如下:

<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo }}
</li>
上面的代码只传递了未完成的 todos。
而如果你的目的是有条件地跳过循环的执行,那么可以将 v-if 置于外层元素 (或 <template>)上

##(31)vue中 keep-alive 组件的作用
keep-alive:主要用于保留组件状态或避免重新渲染。
比如: 有一个列表页面和一个 详情页面,那么用户就会经常执行打开详情=>返回列表=>打开详情这样的话 列表 和 详情 都是一个频率很高的页面,那么就可以对列表组件使用进行缓存,这样用户每次返回列表的时候,都能从缓存中快速渲染,而不是重新渲染。
1、属性:
include:字符串或正则表达式。只有匹配的组件会被缓存。
exclude:字符串或正则表达式。任何匹配的组件都不会被缓存。
2、用法:
包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 相似,是一个抽象组件:它自身不会渲染一DOM 元素,也不会出现在父组件链中。
当组件在 内被切换,在 2.2.0 及其更高版本中,activated 和 deactivated生命周期 将会在 树内的所有嵌套组件中触发。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值