1. Vue组件的生命周期有哪些,它们的执行顺序是什么?
答:Vue组件的生命周期包括beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy和destroyed等。它们的执行顺序如下:
beforeCreate -> created -> beforeMount -> mounted -> beforeUpdate -> updated -> beforeDestroy -> destroyed。
2. 什么是计算属性,它和方法有什么区别?
答:计算属性(computed)是Vue中的一个属性,它是一个函数,根据响应式的数据进行计算返回结果。计算属性可以多次使用,并且当计算属性所依赖的响应式数据改变时会重新计算,避免了不必要的计算。而方法(methods)则需要手动调用,无法自动触发并且不能被缓存,所以当方法所依赖的数据需要更新时需要手动调用。
3. VueRouter的路由模式有哪几种?
答: VueRouter路由模式有三种:hash模式、history模式和abstract模式。hash模式使用URL的hash(#)来模拟一个完整的URL,当URL有变化时,页面不会重新加载,而是通过hashchange事件监听到URL的变化,然后通过hash来实现视图的更新;history模式使用HTML5的History API来进行URL跳转,通过pushState和replaceState方法可以动态改变浏览器的URL,而不需要刷新页面;abstract模式将路由进行抽象,不依赖于浏览器的URL,主要用于非浏览器环境下的应用。
4. 什么是Vuex,它的作用是什么?
答:Vuex是Vue的状态管理库,它将组件的共享状态抽取出来,以一个全局单例模式进行管理,使得多个组件可以共享同一状态。Vuex包含了状态管理、状态获取、状态修改、同步数据和异步数据管理等功能,它的作用是方便了组件之间的数据交互,特别是在大型复杂应用中非常有用。
5. 什么是Vue的父子组件传值,有哪些传值方式?
答:父子组件传值是指在Vue组件中,通过组件之间的数据传递方式,让父组件向子组件传递数据或者让子组件向父组件传递数据。Vue的父子组件传值方式有props、 a t t r s 、 attrs、 attrs、listeners、v-bind和v-on等,其中props是最常用的一种方式,它可以向子组件传递数据并且可以设置数据类型、默认值和校验等。 a t t r s 和 attrs和 attrs和listeners则是用于解决父组件向子组件传递不符合规范的属性和监听事件。v-bind和v-on是Vue的两个指令,用于绑定属性和事件,可以实现父组件向子组件传递数据和接收子组件的事件。
6. Vue 的优点是什么?
答:Vue 的主要优点是具有简单易学、高效、灵活、功能强大的特点,可以实现组件化、模块化、响应式编程、指令系统、过滤器等功能。
7. Vue 框架中是否有 MVC 的思想?
答:是的,Vue 框架本身就具有 MVVM 思想(将 Model、View、ViewModel 分离),并且通过数据绑定的方式实现了数据与视图的同步。
8. Vue 中的组件通信有哪些方式?
答:Vue 中的组件通信有父子组件通信、兄弟组件通信、跨越多级组件的祖孙组件通信、任意组件之间的通信,可以使用 props、、
emit、refs、事件中心、Vuex 等方法进行实现。
9. nextTick方法有什么作用?
答:nextTick 方法可以用于在 DOM 更新后对页面进行操作,在 Vue 生命周期中的 updated 阶段完毕后执行回调函数,确保数据已经更新的情况下再进行操作。
10. Vue 中的 v-model 指令有什么作用?
答:v-model 指令可以完成双向数据绑定,即实时将用户在输入框中输入的值绑定到 Vue 数据模型中,并且在 Vue 数据模型中的数据发生变化时,可以自动同步到输入框中。
11. Vue 中的 mixin 有什么作用?
答:mixin 可以通过复用已有的 Vue 实例对象中的选项,比如 data、methods、components 等,来增强 Vue 实例的功能。mixin 可以用于扩展多个组件之间的公共逻辑,降低代码的重复度
12. computed 和 watch 的区别和运用的场景?
答:computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;
运用场景:
当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
13. v-show 与 v-if 有什么区别?
答:v-if 是真正的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建;也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次变为真时,才会开始渲染条件块。
v-show 就简单得多——不管初始条件是什么,元素总是会被渲染,并且只是简单地基于 CSS 的 “display” 属性进行切换。
所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
14. 在哪个生命周期内调用异步请求?
答:可以在钩子函数 created、beforeMount、mounted 中进行调用,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。但是本人推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:
能更快获取到服务端数据,减少页面 loading 时间;
ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;
15. 在什么阶段才能访问操作DOM?
答:在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。
16. 你有对 Vue 项目进行哪些优化?
(1)代码层面的优化
-
v-if 和 v-show 区分使用场景
-
computed 和 watch 区分使用场景
-
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
-
长列表性能优化
-
事件的销毁
-
图片资源懒加载
-
路由懒加载
-
第三方插件的按需引入
-
优化无限列表性能
-
服务端渲染 SSR or 预渲染
(2)Webpack 层面的优化
-
Webpack 对图片进行压缩
-
减少 ES6 转为 ES5 的冗余代码
-
提取公共代码
-
模板预编译
-
提取组件的 CSS
-
优化 SourceMap
-
构建结果输出分析
-
Vue 项目的编译优化
(3)基础的 Web 技术的优化
-
开启 gzip 压缩
-
浏览器缓存
-
CDN 的使用
-
使用 Chrome Performance 查找性能瓶颈
17. Vue 组件间通信有哪几种方式?
答:Vue 组件间通信是面试常考的知识点之一,这题有点类似于开放题,你回答出越多方法当然越加分,表明你对 Vue 掌握的越熟练。
Vue 组件间通信只要指以下 3 类通信:父子组件通信、隔代组件通信、兄弟组件通信,以下通信分类:
- props / $emit 适用 父子组件通信
- ref 与 $parent / $children 适用 父子组件通信
- EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
- a t t r s / attrs/ attrs/listeners 适用于 隔代组件通信
- provide / inject 适用于 隔代组件通信
- Vuex 适用于 父子、隔代、兄弟组件通信
18.vue实现双向数据绑定
答:vue实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应监听回调。当把一个普通 Javascript 对象传给 Vue 实例来作为它的 data 选项时,Vue 将遍历它的属性,用 Object.defineProperty 将它们转为 getter/setter。用户看不到 getter/setter,但是在内部它们让 Vue 追踪依赖,在属性被访问和修改时通知变化。
vue的数据双向绑定 将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起observer和Compile之间的通信桥梁,达到数据变化 —>视图更新;视图交互变化(input)—>数据model变更双向绑定效果。
19. 绑定 class 的数组用法
- 对象方法 v-bind:class=“{‘orange’: isRipe, ‘green’: isNotRipe}”
- 数组方法v-bind:class=“[class1, class2]”
- 行内 v-bind:style=“{color: color, fontSize: fontSize+‘px’ }”
20. v-for 与 v-if 的优先级
答:v-for的优先级比v-if高
21. vue-router有哪几种路由守卫?
- 全局守卫:beforeEach
- 后置守卫:afterEach
- 全局解析守卫:beforeResolve
- 路由独享守卫:beforeEnter
22. 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、甚至是嵌套子模块——从上至下进行类似的分割
23. 使用过 Vue SSR 吗?说说 SSR
答:SSR 也就是服务端渲染,也就是将 Vue 在客户端把标签渲染成 HTML 的工作放在服务端完成,然后再把 html 直接返回给客户端。
优点:
SSR 有着更好的 SEO、并且首屏加载速度更快
缺点: 开发条件会受到限制,服务器端渲染只支持 beforeCreate 和 created 两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于 Node.js 的运行环境。
服务器会有更大的负载需求
24. vue 中使用了哪些设计模式
-
工厂模式 - 传入参数即可创建实例
-
单例模式 - 整个程序有且仅有一个实例
-
发布 - 订阅模式 (vue 事件机制)
-
观察者模式 (响应式数据原理)
-
装饰模式: (@装饰器的用法)
-
策略模式 策略模式指对象有某个行为, 但是在不同的场景中, 该行为有不同的实现方案 - 比如选项的合并策略
25. nextTick 使用场景和原理
答:nextTick 中的回调是在下次 DOM 更新循环结束之后执行的延迟回调。在修改数据之后立即使用这个方法,获取更新后的 DOM。主要思路就是采用微任务优先的方式调用异步方法去执行 nextTick 包装的方法
相关代码如下
let callbacks = [];
let pending = false;
function flushCallbacks() {
pending = false;
for (let i = 0; i < callbacks.length; i++) {
callbacks[i]();
}}
let timerFunc;
if (typeof Promise !== "undefined") {
const p = Promise.resolve();
timerFunc = () => {
p.then(flushCallbacks);
};
} else if (typeof MutationObserver !== "undefined") {
let counter = 1;
const observer = new MutationObserver(flushCallbacks);
const textNode = document.createTextNode(String(counter)); observer.observe(textNode, { characterData: true, });
timerFunc = () => { counter = (counter + 1) % 2;
textNode.data = String(counter); };
} else if (typeof setImmediate !== "undefined") {
timerFunc = () => { setImmediate(flushCallbacks);
};
} else {
timerFunc = () => { setTimeout(flushCallbacks, 0);
};
}
export function nextTick(cb) {
callbacks.push(cb);
if (!pending) {
pending = true; timerFunc();
}
}
nextTick 原理详解传送门
26. 简单谈谈你对vue3.0的理解
-
vue3.0和vue2.0最大的区别就是api从原来的options API 变成了 composition API + options API ,编写代码更灵活、复用率更高。
-
vue3.0比vue2.0快2倍,Tree-shaking 更友好
-
vue3.0支持TypeScript以及PWA
-
数据双向绑定从Object.defineProperty变成了 new Proxy,不用再使用$set了
-
其他方面的更改:支持自定义渲染器、支持 Fragment和 Protal组件等。
27. axios 是什么,其特点和常用语法是什么?
答:Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。前端最流行的 ajax 请求库,react/vue 官方都推荐使用 axios 发 ajax 请求
特点:
- 基于 promise 的异步 ajax 请求库,支持promise所有的API
- 浏览器端/node 端都可以使用,浏览器中创建XMLHttpRequests
- 支持请求/响应拦截器
- 支持请求取消
- 可以转换请求数据和响应数据,并对响应回来的内容自动转换成 JSON类型的数据
- 批量发送多个请求
- 安全性更高,客户端支持防御 XSRF,就是让你的每个请求都带一个从cookie中拿到的key, 根据浏览器同源策略,假冒的网站是拿不到你cookie中得key的,这样,后台就可以轻松辨别出这个请求是否是用户在假冒网站上的误导输入,从而采取正确的策略
28. 为什么使用虚拟DOM
-
创建真实DOM的代价高:真实的 DOM 节点 node 实现的属性很多,而 vnode 仅仅实现一些必要的属性,相比起来,创建一个 vnode 的成本比较低。
-
触发多次浏览器重绘及回流:使用 vnode ,相当于加了一个缓冲,让一次数据变动所带来的所有 node 变化,先在 vnode 中进行修改,然后 diff 之后对所有产生差异的节点集中一次对 DOM tree 进行修改,以减少浏览器的重绘及回流。
-
虚拟dom由于本质是一个js对象,因此天生具备跨平台的能力,可以实现在不同平台的准确显示。
-
Virtual DOM 在性能上的收益并不是最主要的,更重要的是它使得 Vue 具备了现代框架应有的高级特性。