目录
常见笔试面试题:
Q:vue几种常用的指令
A:v-for 、 v-if 、v-show、v-bind、v-on
Q:v-if 和 v-show 区别
A:v-if按照条件是否渲染,v-show是display的block或none,会一直存在于DOM。v-if是动态创建和销毁元素,因此对性能的影响较大,不适合频繁切换条件。
Q:css只在当前组件起作用
A:在style标签中写入scoped即可 例如:<style scoped></style>
Q:vue常用的修饰符?
A:
- .sync:会被扩展为一个自动更新父组件属性的 v-on 监听器,需手动进行更新父组件中的值;
- .prevent: 提交事件不再重载页面;
- .stop: 阻止单击事件冒泡;
- .self: 当事件发生在该元素本身而不是子元素的时候会触发;
- .capture: 事件侦听,事件发生的时候会调用
Q:v-for和v-if 可以在同一个标签内使用吗?有什么问题?
A:可以,v-for的优先级比v-if高,会先循环,再判断,造成性能浪费。
Q:vue中 key 值的作用?
A:当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。key的作用主要是为了高效的更新虚拟DOM。
Q:什么是vue的计算属性?
A:在模板中放入太多的逻辑会让模板过重且难以维护,在需要对数据进行复杂处理,且可能多次使用的情况下,尽量采取计算属性的方式。好处:①使得数据处理结构清晰;②依赖于数据,数据更新,处理结果自动更新;③计算属性内部this指向vm实例;④在template调用时,直接写计算属性名即可;⑤常用的是getter方法,获取数据,也可以使用set方法改变数据;⑥相较于methods,不管依赖的数据变不变,methods都会重新计算,但是依赖数据不变的时候computed从缓存中获取,不会重新计算。
Q:$route和$router的区别
A:$route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。而$router是“路由实例”对象包括了路由的跳转方法,钩子函数等。
Q:怎么定义 vue-router 的动态路由? 怎么获取传过来的值
A:在 router 目录下的 index.js 文件中,对 path 属性加上 /:id,使用 router 对象的 params.id 获取。
Q:vue.js的两个核心是什么?
A:数据驱动、组件系统
Q:vue等单页面应用及其优缺点
A:优点:Vue 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件,核心是一个响应的数据绑定系统。MVVM、数据驱动、组件化、轻量、简洁、高效、快速、模块友好。
缺点:不支持低版本的浏览器,最低只支持到IE9;不利于SEO的优化(如果要支持SEO,建议通过服务端来进行渲染组件);第一次加载首页耗时相对长一些;不可以使用浏览器的导航按钮需要自行实现前进、后退 (引入vue router)。
对于MVVM的理解?
MVVM 是 Model-View-ViewModel 的缩写。
Model:数据模型,可以在Model中定义数据修改和操作的业务逻辑。
View:视图,它负责将数据模型转化成UI 展现出来。
ViewModel: 视图模型,监听模型数据的改变和控制视图行为、处理用户交互,简单理解就是一个连接View 和 Model的中转站。
在MVVM架构下,View 和 Model 之间并没有直接的联系,ViewModel 通过双向数据绑定把 View 层和 Model 层连接了起来,而View 和 Model 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。
Vue的生命周期
beforeCreate(创建前)此阶段为实例初始化之后,此时的数据观察和事件机制都未形成,不能获得DOM节点。
created(创建后) 在这个阶段vue实例已经创建,已完成数据监测、属性和方法的运算、data和事件的初始化,但$el属性还没有显示出来,所以仍然不能获取DOM元素。
beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成编译模板,把data里面的数据和模板生成html,但此时还没有挂载html到页面上,所以在这一阶段,我们依然得不到具体的DOM元素。
mounted(载入后) 在这个阶段,el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用,数据和DOM都已被渲染出来。一般的异步请求都写在这里。
beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。
updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。
beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。
destroyed(销毁后) 在实例销毁之后调用。此时所有的事件监听器、子实例都被移除销毁。
vue的生命周期的思想贯穿在组件开发的始终,通过熟悉其生命周期调用不同的钩子函数,可以准确地控制数据流和其对DOM的影响;vue生命周期的思想是Vnode和MVVM的生动体现和继承。
Question:
Q:什么是Vue生命周期?
A: Vue 实例从创建到销毁的过程,就是生命周期。从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、销毁等一系列过程,称之为 Vue 的生命周期。
Q:Vue生命周期的作用是什么?
A:Vue生命周期提供了多个钩子函数,让开发者准确地控制数据流和其对DOM的影响。
Q:第一次页面加载会触发哪几个钩子?
A:会触发 下面这几个beforeCreate, created, beforeMount, mounted 。
Q:DOM 渲染在 哪个周期中就已经完成?
A:DOM 渲染在 mounted 中就已经完成了。
Vue实现数据双向绑定的原理
Vue2 是响应式原理基于 Object.defineProperty 方法重定义对象的 getter 与 setter。
这种方法并不能对诸如数组长度变化、增删元素操作、对象新增属性进行感知,在 vue 层面不得不重写一些数组方法(push、pop、unshift、shift 等),动态添加响应式属性,也要使用 $set 方法等。
关于Object.defineProperty() 的详细介绍可看这两篇文章,这里就不赘述了:《JavaScript中的Object.defineProperty()》《深入浅出Object.defineProperty()》
vue3 则基于 Proxy 代理对象,拦截对象属性的访问与赋值过程。
经过proxy拦截的对象会返回所有的属性,包括之前定义的和新增的属性,这就解决了之前所无法监听的问题。
Proxy实现数据劫持:
observe(data) { const that = this; let handler = { get(target, property) { return target[property]; }, set(target, key, value) { let res = Reflect.set(target, key, value); that.subscribe[key].map(item => { item.update(); }); return res; } } this.$data = new Proxy(data, handler); }
Vue3.0 所采用的 Composition Api与 Vue2.x 使用的Options Api有什么不同?
composition API 可以说是 Vue3 的最大特点,通常使用 vue2 开发的项目,普遍会存在以下问题:
1、代码的可读性随着组件变大而变差
2、每一种代码复用的方式,都存在缺点
3、TypeScript 支持有限options API:
即大家常说的选项 API,即以 vue 为后缀的文件,通过定义methods,computed,watch,data 等属性与方法,共同处理页面逻辑。随着组件变得复杂,对应属性的列表也会增长,这可能会导致组件难以阅读和理解。
Composition API:
在 Vue3 Composition API 中,组件根据逻辑功能来分类的,一个功能所定义的所有 API 会放在一起(更加的高内聚,低耦合)
即使项目很大,功能很多,我们都能快速的定位到这个功能所用到的所有 API。
Vue3新增:
Vue3中的
Tree shaking
是什么?它的作用是什么?
答:Tree shaking
是一种通过清除多余代码方式来优化项目打包体积的技术,简单来讲,就是在保持代码运行结果不变的前提下,去除无用的代码。Vue3中的Teleport是什么?它的作用是什么?
答:Vue3中的Teleport 是控制渲染位置的新指令。它的作用是在DOM中移动一个组件的内容而不改变组件的父级。
Vue3中的Suspense是什么?它的作用是什么?
答:Vue3中的Suspense是Vue3中新增的一个组件,它的作用是实现延迟加载和错误处理。在组件中加入Suspense,可以让异步组件可以渲染出加载状态,并且如果异步组件加载时出现错误,也能够处理这些错误。
Vue3中的Fragment是什么?它的作用是什么?
答:Vue3中的Fragment是用来承载多个子元素的虚拟组件。它的作用是可以解决在Vue2中,使用v-for迭代元素时需要添加一个包装元素的问题。
Vue组件间通信
父子级通信推荐使用:props/$emit、$parent/$children/$refs、$attrs/$listeners
兄弟组件通信推荐使用:$emit/$on、Vuex
无关系组件通信推荐使用:$emit/$on、Vuex、$attrs/$listeners、provide/inject
想了解全部详细的组件通信,请点这里《Vue组件通信》
Vue Router的路由守卫
router.beforeEach、router.beforeResolve、router.afterEach......
路由守卫接受三个参数:
- to:route即将进入的目标路由对象,
- from:route当前导航正要离开的路由
- next:function一定要调用该方法resolve这个钩子。执行效果依赖next方法的调用参数。可以控制网页的跳转。
Vue Router的hash和history模式
对于vue这类渐进式前端开发框架,为了构建 SPA(单页面应用),需要引入前端路由系统,这也就是 Vue-Router 存在的意义。前端路由的核心,就在于 —— 改变视图的同时不会向后端发出请求。
为了达到这一目的,浏览器当前提供了以下两种支持:
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,但浏览器不会e向后端发送请求。
Vuex有五个核心概念:
state
, getters
, mutations
, actions
, modules
。
1. state:vuex的基本数据,用来存储变量
2. geeter:从基本数据(state)派生的数据,相当于state的计算属性
3. mutation:提交更新数据的方法,必须是同步的(如果需要异步使用action)。每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数,提交载荷作为第二个参数。
4. action:和mutation的功能大致相同,不同之处在于:1. Action 提交的是 mutation,而不是直接变更状态。 2. Action 可以包含任意异步操作。
5. modules:模块化vuex,可以让每一个模块拥有自己的state、mutation、action、getters,使得结构非常清晰,方便管理。
keep-alive的作用是什么?
keep-alive 是 Vue 内置的一个组件,可以使被包含的组件缓存下来保留状态,避免重新渲染。两个钩子:activated 和 deactivated,钩子会在 <keep-alive> 树内的所有嵌套组件中触发。
常用应用场景有:
- 商品列表页点击商品跳转到商品详情,返回后仍显示原有信息
- 订单列表跳转到订单详情,返回,等等场景。
keep-alive的生命周期
- 初次进入时:created > mounted > activated;退出后触发 deactivated
- 再次进入:会触发 activated;事件挂载的方法等,只执行一次的放在 mounted 中;组件每次进去执行的方法放在 activated 中
有关keep-alive->《利用Vue中keep-alive,快速实现页面缓存》
react和vue的异同:
- 模板写法,Vue的模板写法接近标准HTML,只是多了一些属性;React的模板使用JSX书写,写法是原生JS。
- 监听数据变化的实现原理不同,vue 双向数据流,数据可变;React 单向响应数据流,强调数据的不可变。
- 在 Vue 中我们组合不同功能的方式是通过 mixin,而在React中我们通过 HoC (高阶组件)。
- 组件通信:父组件都可以通过 props 向子组件传递数据或者回调;子组件向父组件传值,Vue有事件和回调两种,一般更倾向于使用事件,但是在 React 中都是使用回调函数的。
- 使用typescript,react比vue更合适。