在你准备面试的时候 , 最愁的恐怕就是面试题太多记不过来吧 , 下面为大家整理了 Vue 经常问到的面试题 , 希望可以帮到你们
1.vue优点?
轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb;
简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习;
双向数据绑定:保留了angular的特点,在数据操作方面更为简单;
组件化:保留了react的优点,实现了html的封装和重用,在构建单页面应用方面有着独特的优势;
视图,数据,结构分离:使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作;
虚拟DOM:dom操作是非常耗费性能的, 不再使用原生的dom操作节点,极大解放dom操作,但具体操作的还是dom不过是换了另一种方式;
运行速度更快: 相比较与react而言,同样是操作虚拟dom,就性能而言,vue存在很大的优势。
2.vue父子组件传递数据?
父组件通过 props 给子组件传参,子组件用 $emit 方法调用父组件自定义事件并传参
3.兄弟组件传参?
eventBus 总线通过 $emit 和 $on 结合
详情参照 https://zhuanlan.zhihu.com/p/72777951
4.v-show和v-if指令的共同点和不同点?
共同点:都能控制元素的显示和隐藏;
不同点:实现本质方法不同,v-show本质就是通过控制css中的display设置为none,控制隐藏,只会编译一次;v-if是动态的向DOM树内添加或者删除DOM元素,若初始值为false,就不会编译了。而且v-if不停的销毁和创建比较消耗性能。
总结:如果要频繁切换某节点,使用v-show(切换开销比较小,初始开销较大)。如果不需要频繁切换某节点使用v-if(初始渲染开销较小,切换开销比较大)。
5.如何让CSS只在当前组件中起作用?
在组件中的style前面加上scoped
6. vue的两个核心点
数据驱动、组件系统 ( 高效的数据绑定 灵活的组件应用 )
数据驱动:ViewModel,保证数据和视图的一致性。
组件系统:应用类UI可以看作全部是由组件树构成的
7. vue的生命周期
(1) beforeCreate : 实例创建之前,这个时候vue的实例上只有一些生命周期函数 , data和methods还不能使用
(2) created : 创建结束的时候,vue实例上的data 和 methods就能正常使用了 最早可以在created里使用data和methods
(3) beforeMount : 挂载之前 模板进行编译, 把指令循环插值语句都进行执行,生成一个虚拟的dom节点,在挂载之前,这个虚拟的dom被放在内存中
(4) mounted : 挂载完毕 最早在这个生命周期函数里用dom节点 把上一步生成的虚拟的dom挂载进#app里
(5) beforeUpdate : 数据更新之前之后指的是视图上数据的更新前后,数据更新之前 data里的数据已经发生变化,视图还没有更新
(6) updated : 数据更新之后 视图也跟着变化了
(7) beforeDestroy : 实例销毁之前
(8) destroyed : 实例销毁之后
8. 解释单向数据流和双向数据绑定
单向数据流: 顾名思义,数据流是单向的。数据流动方向可以跟踪,流动单一,追查问题的时候可以更快捷。缺点就是写起来不太方便。要使UI发生变更就必须创建各种 action 来维护对应的 state
双向数据绑定:数据之间是相通的,将数据变更的操作隐藏在框架内部。优点是在表单交互较多的场景下,会简化大量业务无关的代码。缺点就是无法追踪局部状态的变化,增加了出错时 debug 的难度
9. Vue 如何去除url中的 #
vue-router 默认使用 hash 模式,所以在路由加载的时候,项目中的 url 会自带 #。如果不想使用 #, 可以使用 vue-router 的另一种模式 history
new Router({
mode: 'history',
routes: [ ]
})
需要注意的是,当我们启用 history 模式的时候,由于我们的项目是一个单页面应用,所以在路由跳转的时候,就会出现访问不到静态资源而出现 404 的情况,这时候就需要服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面
10. vuex有哪几种属性?
有五种,分别是 State、 Getter、Mutation 、Action、 Module
state => 基本数据(数据源存放地)
getters => 从基本数据派生出来的数据
mutations => 提交更改数据的方法,同步!
actions => 像一个装饰器,包裹mutations,使之可以异步。
modules => 模块化Vuex
11. Vue的双向绑定数据的原理(响应式原理)
2.0 vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调
3.0 proxy代理代替Object.defineProperty()
12. 单页面应用和多页面应用区别及优缺点
单页面应用(SPA),通俗一点说就是指只有一个主页面的应用,浏览器一开始要加载所有必须的 html, js, css。所有的页面内容都包含在这个所谓的主页面中。但在写的时候,还是会分开写(页面片段),然后在交互的时候由路由程序动态载入,单页面的页面跳转,仅刷新局部资源。多应用于pc端。
多页面(MPA),就是指一个应用中有多个页面,页面跳转时是整页刷新
单页面的优点:
用户体验好,快,内容的改变不需要重新加载整个页面,基于这一点spa对服务器压力较小;前后端分离;页面效果会比较炫酷(比如切换页面内容时的专场动画)。
单页面缺点:
不利于seo;导航不可用,如果一定要导航需要自行实现前进、后退。(由于是单页面不能用浏览器的前进后退功能,所以需要自己建立堆栈管理);初次加载时耗时多;页面复杂度提高很多。
13. <keep-alive></keep-alive>的作用是什么?
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。
14. 说出几种vue当中的指令和它的用法?
v-model双向数据绑定;
v-for循环;
v-if v-show 显示与隐藏;
v-on事件;
v-once: 只绑定一次
15. Vue 组件 data 为什么必须是函数
因为js本身的特性带来的,如果 data 是一个对象,那么由于对象本身属于引用类型,当我们修改其中的一个属性时,会影响到所有Vue实例的数据。如果将 data 作为一个函数返回一个对象,那么每一个实例的 data 属性都是独立的,不会相互影响了
16. Vue 中 key 的作用
key 的特殊属性主要用在 Vue 的虚拟 DOM 算法,在新旧 nodes 对比时辨识 VNodes。如果不使用 key,Vue 会使用一种最大限度减少动态元素并且尽可能的尝试修复/再利用相同类型元素的算法。使用 key,它会基于 key 的变化重新排列元素顺序,并且会移除 key 不存在的元素。
有相同父元素的子元素必须有独特的 key。重复的 key 会造成渲染错误
17. Vue 中怎么自定义过滤器
可以用全局方法 Vue.filter() 注册一个自定义过滤器,它接收两个参数:过滤器 ID(名称) 和过滤器函数。过滤器函数以值为参数,返回转换后的值
Vue.filter('reverse', function (value) {
return value.split('').reverse().join('')
})
<!-- 'abc' => 'cba' -->
<span v-text="message | reverse"></span>
过滤器也同样接受全局注册和局部注册
18. new操作符具体干了什么呢?
- 创建⼀个空对象,并且this变量引⽤该对象,同时还继承了该函数的原型
- 属性和⽅法被加⼊到 this 引⽤的对象中
- 新创建的对象由 this 所引⽤,并且最后隐式的返回 this
19.vuex是什么
vuex是一个专为vue.js应用程序开发的状态管理模式(它采用集中式存贮管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化)
20.vuex中的mutations的方法如何在组件中调用、如何在actions中调用
组件调用: this.$store.commit(‘mutations方法名’,值)
actions调用: this.$store.dispatch(‘mutations方法名’,值)
21. Vue的路由实现有几种方式,特点分别是什么
• hash —— 即地址栏 URL 中的 # 符号(此 hash 不是密码学里的散列运算)。
比如这个 URL:http://www.abc.com/#/hello,hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
• history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
22.Vue的路由跳转有几种方式,分别是什么
声明式:
(1) <router-link :to="{name:'home', params: {id:1}}">
//params传参数,路由配置 path: "/home/:id" 或者 path: "/home:id"
//不配置path ,第一次可请求,刷新页面id会消失; 配置path,刷新页面id会保留
//html 取参 $route.params.id
//script 取参 this.$route.params.id
(2) <router-link :to="{name:'home', query: {id:1}}">
//query传参数 (类似get,url后面会显示参数),路由可不配置
//html 取参 $route.query.id
//script 取参 this.$route.query.id
编程式:
(1) query传参
this.$router.push({name:'home',query: {id:'1'}})
this.$router.push({path:'/home',query: {id:'1'}})
//html 取参 $route.query.id
//script 取参 this.$route.query.id
(2) params传参
this.$router.push({name:'home',params: {id:'1'}}) // 只能用 name
区别 :
this.$router.push
跳转到指定url路径,并想history栈中添加一个记录,点击后退会返回到上一个页面
this.$router.replace
跳转到指定url路径,但是history栈中不会有记录,点击返回会跳转到上上个页面 (就是直接替换了当前页面)
this.$router.go(n)
向前或者向后跳转n个页面,n可为正整数或负整数
23. 简述axios的安装以及使用
使用npm安装:
$ npm install axios
$ npm install --save axios vue-axios
入口文件引入:
import axios from ‘axios’
Vue.prototype.axios=axios //全局注册,使用方法为:this.axios
axios.defaults.withCredentials = true; //解决跨域请求
开始使用请求
24.什么是 MVVM
MVVM分为Model、View、ViewModel三者。
Model 代表数据模型,数据和业务逻辑都在Model层中定义;
View 代表UI视图,负责数据的展示;
ViewModel 负责监听 Model 中数据的改变并且控制视图的更新,处理用户交互操作;
Model 和 View 并无直接关联,而是通过 ViewModel 来进行联系的,Model 和 ViewModel 之间有着双向数据绑定的联系。因此当 Model 中的数据改变时会触发 View 层的刷新,View 中由于用户交互操作而改变的数据也会在 Model 中同步。
这种模式实现了 Model 和 View 的数据自动同步,因此开发者只需要专注对数据的维护操作即可,而不需要自己操作 dom。
25.请说出vue-cli项目中的src目录每个文件夹和文件的用法
assets存放静态资源,例如图片
components存放组件,通过路由跳转实现
lib需要引入的静态资源
router定义路由相关的配置
store仓库,即vuex,存放公共数据
views存放视图组件
App.vue根组件,一进入页面显示
main.js入口文件,引入所有需要的文件
26. $route 和 $router 的区别
$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数,而$router是“路由实例”对象,包括了路由的跳转方法,钩子函数等。
27. 写出组件之间的通信有哪些
参考https://juejin.im/post/5d267dcdf265da1b957081a3
28. 写出计算属性、方法methods、watch的区别
计算属性只能获取不能改变数据,不支持异步操作
methods可以对数据进行修改
watch监听数据,在数据更改时触发,也可以进行异步操作
29. 写出对es6模块化的理解
暴露用export,或export default, 前者将暴露为一个对象,后者为自定义暴露;
引入用import
引入export的模块,用{}解构赋值来按需加载
引入export default 暴露的模块可直接用变量来接收,且接收到的值为暴露的值
30. es6提供的数组方法有哪些
Array.of(): 将参数中所有值作为元素形成数组 , 即定义数组。
Array.from(): 将类数组对象或转化为数组。
find(): 查找数组中符合条件的元素,若有多个符合条件的元素,则返回第一个元素。
findIndex(): 查找数组中符合条件的元素索引,若有多个符合条件的元素,则返回第一个元素索引。
fill(): 填充替换数组 , 含头不含尾
copyWithin(): 将一定范围索引的数组元素修改为此数组另一指定范围索引的元素。
keys(): 遍历键名 , 只能在循环里使用,因为返回的是迭代器
values(): 遍历键值 , 只能在循环里使用,因为返回的是迭代器
includes(): 数组是否包含指定值。
flat(): 嵌套数组转一维数组
31.描述promise如何使用
jq的 $.ajax返回的本身就是一个promise对象,可以直接调用then方法,假设$.ajax返回的不是promise的话我们需要自己new Promise方法 , 才能调用then方法, then 方法里放成功的回调,继续.catch放失败的回调, jq 的 ajax 比较特殊,因为他是自己已经封装好的promise对象,catch的写法变成了fail
32.描述async与await如何使用。
async函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而await命令就是内部then命令的语法糖
async function timeout(ms) {
await new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
async function asyncPrint(value, ms) {
await timeout(ms);
console.log(value);
}
asyncPrint('hello world', 50);
33.写出vue-router中导航守卫的钩子函数有哪些
全局导航钩子: beforeEach afterEach
路由独享的钩子: beforeEnter
组建内的导航钩子:
beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
34.Vue-loader是什么?使用它的用途有哪些
vue-loader 是 vue 的一个加载器,能把vue 组件的template/js/style转化成JavaScript模块
用途:js可以写es6、style样式可以scss或less、template可以加jade等
35.Vue.js中ajax请求代码应该写在组件的methods中还是vuex的actions中?
一种是:“请求后端接口”这个ajax代码应该是写在按钮的点击事件处理函数中,然后在这个处理函数里面提交mutations
另一种是:直接将“请求后端接口”这个ajax代码写在actions中,actions中提交mutations,按钮的点击事件处理函数中只写一个分发actions的按钮
36.常见的进行路由传参的方式有几种
(1)path中添加/:id来对应 this.$router.push 中path携带的参数
获取this.$route.params.id
(2)通过路由属性中的name来确定匹配的路由,通过params来传递参数
(3)使用path来匹配路由,然后通过query来传递参数
获取this.$route.query.id
37.最简单的深复制及相关问题
参考此链接, 有详细介绍https://blog.csdn.net/u013565133/article/details/102819929