关于vue.js:Vue面试题归总

7次阅读

共计 16412 个字符,预计需要花费 42 分钟才能阅读完成。

Vue 的长处
说说你对 SPA 单页面的了解,它的优缺点别离是什么?
SPA 首屏加载速度慢的怎么解决?
Vue 初始化过程中(new Vue(options))都做了什么?
对 MVVM 的了解?
Vue 数据双向绑定原理
Vue 的响应式原理
Vue3.x 响应式数据原理
Vue3.0 里为什么要用 Proxy API 代替 defineProperty API?
Proxy 与 Object.defineProperty 优劣比照
vue 中组件的 data 为什么是一个函数?而 new Vue 实例里,data 能够间接是一个对象
vue 中 data 的属性能够和 methods 中办法同名吗,为什么?
vue 中 created 与 mounted 区别
Vue 中 computed 与 method 的区别
虚构 DOM 中 key 的作用
用 index 作为 key 可能会引发的问题
Vue 中 watch 用法详解
vue 中对 mixins 的了解和应用
vue 中的插槽
为什么 vue 采纳异步渲染
Vue 的异步更新机制是如何实现的?
$nextTick 的了解
Vue 中罕用的一些指令
vue 的自定义指令
你有写过自定义指令吗?自定义指令的利用场景有哪些?
v-show 和 v -if 指令的共同点和不同点
为什么防止 v -if 和 v -for 一起应用
vue 为什么在 HTML 中监听事件?
Vue.set 扭转数组和对象中的属性
vm.$set(obj, key, val) 做了什么?
说说 vue 的生命周期的了解
第一次页面加载会触发哪几个钩子?
Vue 组件通信有哪些形式
router 和 route 的区别
vue-router 有几种钩子函数?
vue-router 路由跳转形式
vue-router 路由传参
keep-alive 理解吗
Vuex 是什么?怎么应用?
什么状况下应用 Vuex?
Vuex 和单纯的全局对象有什么区别?
为什么 Vuex 的 mutation 中不能做异步操作?
axios 是什么,其特点和罕用语法
对 SSR 有理解吗,它次要解决什么问题?
Vue 要做权限治理该怎么做?管制到按钮级别的权限怎么做?
Vue 我的项目前端开发环境申请服务器接口跨域问题
做过哪些 Vue 的性能优化?
Vue3 有理解过吗?能说说跟 Vue2 的区别吗?
Vue 3.0 所采纳的 Composition Api 与 Vue 2.x 应用的 Options Api 有什么区别?
element-ui 中遇到的问题

Vue 的长处
轻量级框架:只关注视图层,是一个构建数据的视图汇合,大小只有几十 kb;
简略易学:国人开发,中文文档,不存在语言障碍,易于了解和学习;
双向数据绑定:保留了 angular 的特点,在数据操作方面更为简略;
组件化:保留了 react 的长处,实现了 html 的封装和重用,在构建单页面利用方面有着独特的劣势;
视图,数据,构造拆散:使数据的更改更为简略,不须要进行逻辑代码的批改,只须要操作数据就能实现相干操作;
虚构 DOM:dom 操作是十分消耗性能的,不再应用原生的 dom 操作节点,极大解放 dom 操作,但具体操作的还是 dom 不过是换了另一种形式;
运行速度更快:相比拟于 react 而言,同样是操作虚构 dom,就性能而言,vue 存在很大的劣势。

说说你对 SPA 单页面的了解,它的优缺点别离是什么?
是什么

SPA(single page application)仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。
一旦页面加载实现,SPA 不会因为用户的操作而进行页面的从新加载或跳转
而页面的变动是利用路由机制实现 HTML 内容的变换,防止页面的从新加载。
长处

用户体验好,内容的扭转不须要从新加载整个页面,防止了不必要的跳转和反复渲染
缩小了不必要的跳转和反复渲染,这样绝对加重了服务器的压力
前后端职责拆散,架构清晰,前端进行交互逻辑,后端负责数据处理
毛病

首次加载耗时多
不能应用浏览器的后退后退性能,因为单页利用在一个页面中显示所有的内容,所以,无奈后退后退
不利于搜索引擎检索:因为所有的内容都在一个页面中动静替换显示,所以在 SEO 上其有着人造的弱势。
SPA 首屏加载速度慢的怎么解决?
首屏工夫(First Contentful Paint),指的是浏览器从响应用户输出网址地址,到首屏内容渲染实现的工夫,此时整个网页不肯定要全副渲染实现,但须要展现以后视窗须要的内容;

加载慢的起因

网络延时问题
资源文件体积是否过大
资源是否反复发送申请去加载了
加载脚本的时候,渲染内容梗塞了
常见的几种 SPA 首屏优化形式

减小入口文件积
动态资源本地缓存
UI 框架按需加载
图片资源的压缩
组件反复打包
开启 GZip 压缩
应用 SSR
想要具体理解能够点击 SPA(单页利用)首屏加载速度慢的解决详解

Vue 初始化过程中(new Vue(options))都做了什么?
解决组件配置项;初始化根组件时进行了选项合并操作,将全局配置合并到根组件的部分配置上;初始化每个子组件时做了一些性能优化,将组件配置对象上的一些深层次属性放到 vm.$options 选项中,以进步代码的执行效率;
初始化组件实例的关系属性,比方 p a r e n t、parent、parent、children、r o o t、root、root、refs 等
解决自定义事件
调用 beforeCreate 钩子函数
初始化组件的 inject 配置项,失去 ret[key] = val 模式的配置对象,而后对该配置对象进行响应式解决,并代理每个 key 到 vm 实例上
数据响应式,解决 props、methods、data、computed、watch 等选项
解析组件配置项上的 provide 对象,将其挂载到 vm._provided 属性上
调用 created 钩子函数
如果发现配置项上有 el 选项,则主动调用 $mount 办法,也就是说有了 el 选项,就不须要再手动调用 $mount 办法,反之,没提供 el 选项则必须调用 $mount
接下来则进入挂载阶段

// core/instance/init.js
export function initMixin (Vue: Class<Component>) {Vue.prototype._init = function (options?: Object) {
const vm: Component = this
vm._uid = uid++

// 如果是 Vue 的实例,则不须要被 observe
vm._isVue = true

if (options && options._isComponent) {
// optimize internal component instantiation
// since dynamic options merging is pretty slow, and none of the
// internal component options needs special treatment.
initInternalComponent(vm, options)
} else {
vm.$options = mergeOptions(resolveConstructorOptions(vm.constructor),
options || {},
vm
)
}

if (process.env.NODE_ENV !== 'production') {initProxy(vm)
} else {vm._renderProxy = vm}

vm._self = vm

initLifecycle(vm)
initEvents(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props

initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')

if (vm.$options.el) {vm.$mount(vm.$options.el)
}
}
}

对 MVVM 的了解?
MVVM 由 Model、View、ViewModel 三局部形成,Model 层代表数据模型,也能够在 Model 中定义数据批改和操作的业务逻辑;View 代表 UI 组件,它负责将数据模型转化成 UI 展示进去;ViewModel 是一个同步 View 和 Model 的对象。

在 MVVM 架构下,View 和 Model 之间并没有间接的分割,而是通过 ViewModel 进行交互,Model 和 ViewModel 之间的交互是双向的,因而 View 数据的变动会同步到 Model 中,而 Model 数据的变动也会立刻反馈到 View 上。

ViewModel 通过双向数据绑定把 View 层和 Model 层连贯了起来,而 View 和 Model 之间的同步工作齐全是主动的,无需人为干预,因而开发者只需关注业务逻辑,不须要手动操作 DOM,不须要关注数据状态的同步问题,简单的数据状态保护齐全由 MVVM 来对立治理。

Vue 数据双向绑定原理
实现 mvvm 的数据双向绑定,是采纳数据劫持联合发布者 - 订阅者模式的形式,通过 Object.defineProperty()来给各个属性增加 setter,getter 并劫持监听,在数据变动时公布音讯给订阅者,触发相应的监听回调。就必须要实现以下几点:
1、实现一个数据监听器 Observer,可能对数据对象的所有属性进行监听,如有变动可拿到最新值并告诉订阅者
2、实现一个指令解析器 Compile,对每个元素节点的指令进行扫描和解析,依据指令模板替换数据,以及绑定相应的更新函数
3、实现一个 Watcher,作为连贯 Observer 和 Compile 的桥梁,可能订阅并收到每个属性变动的告诉,执行指令绑定的相应回调函数,从而更新视图

Vue 的响应式原理
什么是响应式,也即是说,数据产生扭转的时候,视图会从新渲染,匹配更新为最新的值。
Object.defineProperty 为对象中的每一个属性,设置 get 和 set 办法,每个申明的属性,都会有一个 专属的依赖收集器 subs,当页面应用到 某个属性时,触发 ObjectdefineProperty – get 函数,页面的 watcher 就会被 放到 属性的依赖收集器 subs 中,在 数据变动时,告诉更新;
当数据扭转的时候,会触发 Object.defineProperty – set 函数,数据会遍历本人的 依赖收集器 subs,一一告诉 watcher,视图开始更新;

Vue3.x 响应式数据原理
Vue3.x 改用 Proxy 代替 Object.defineProperty。
因为 Proxy 能够间接监听对象和数组的变动,并且有多达 13 种拦挡办法。并且作为新规范将受到浏览器厂商重点继续的性能优化。
Proxy 只会代理对象的第一层,Vue3 是怎么解决这个问题的呢?
判断以后 Reflect.get 的返回值是否为 Object,如果是则再通过 reactive 办法做代理,这样就实现了深度观测。
监测数组的时候可能触发屡次 get/set,那么如何避免触发屡次呢?咱们能够判断 key 是否为以后被代理对象 target 本身属性,也能够判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行 trigger。

Vue3.0 里为什么要用 Proxy API 代替 defineProperty API?
1.defineProperty API 的局限性最大起因是它只能针对单例属性做监听。
Vue2.x 中的响应式实现正是基于 defineProperty 中的 descriptor,对 data 中的属性做了遍历 + 递归,为每个属性设置了 getter、setter。这也就是为什么 Vue 只能对 data 中预约义过的属性做出响应的起因。
2.Proxy API 的监听是针对一个对象的,那么对这个对象的所有操作会进入监听操作,这就齐全能够代理所有属性,将会带来很大的性能晋升和更优的代码。
Proxy 能够了解成,在指标对象之前架设一层“拦挡”,外界对该对象的拜访,都必须先通过这层拦挡,因而提供了一种机制,能够对外界的拜访进行过滤和改写。
3. 响应式是惰性的。
在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它外部深层次的变动,就须要递归遍历这个对象,执行 Object.defineProperty 把每一层对象数据都变成响应式的,这无疑会有很大的性能耗费。
在 Vue.js 3.0 中,应用 Proxy API 并不能监听到对象外部深层次的属性变动,因而它的解决形式是在 getter 中去递归响应式,这样的益处是真正拜访到的外部属性才会变成响应式,简略的能够说是按需实现响应式,缩小性能耗费。

Proxy 与 Object.defineProperty 优劣比照
1.Proxy 能够间接监听对象而非属性;
2.Proxy 能够间接监听数组的变动;
3.Proxy 有多达 13 种拦挡办法, 不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
4.Proxy 返回的是一个新对象, 咱们能够只操作新的对象达到目标, 而 Object.defineProperty 只能遍历对象属性间接批改;
5.Proxy 作为新规范将受到浏览器厂商重点继续的性能优化,也就是传说中的新规范的性能红利;
6.Object.defineProperty 的劣势如下:
兼容性好,反对 IE9,而 Proxy 的存在浏览器兼容性问题, 而且无奈用 polyfill 磨平,因而 Vue 的作者才申明须要等到下个大版本 (3.0) 能力用 Proxy 重写。

vue 中组件的 data 为什么是一个函数?而 new Vue 实例里,data 能够间接是一个对象
咱们晓得,Vue 组件其实就是一个 Vue 实例。

JS 中的实例是通过构造函数来创立的,每个构造函数能够 new 出很多个实例,那么每个实例都会继承原型上的办法或属性。

Vue 的 data 数据其实是 Vue 原型上的属性,数据存在于内存当中。Vue 为了保障每个实例上的 data 数据的独立性,规定了必须应用函数,而不是对象。

因为应用对象的话,每个实例(组件)上应用的 data 数据是相互影响的,这当然就不是咱们想要的了。对象是对于内存地址的援用,间接定义个对象的话组件之间都会应用这个对象,这样会造成组件之间数据相互影响。

应用函数后,应用的是 data()函数,data()函数中的 this 指向的是以后实例自身,就不会相互影响了。

而 new Vue 的实例,是不会被复用的,因而不存在援用对象的问题。

vue 中 data 的属性能够和 methods 中办法同名吗,为什么?
能够同名,methods 的办法名会被 data 的属性笼罩;调试台也会呈现报错信息,然而不影响执行;
起因:源码定义的 initState 函数外部执行的程序:props>methods>data>computed>watch

//initState 局部源码
export function initState (vm: Component) {vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {initData(vm)
} else {observe(vm._data = {}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {initWatch(vm, opts.watch)
}
}

vue 中 created 与 mounted 区别
在 created 阶段,实例曾经被初始化,然而还没有挂载至 el 上,所以咱们无奈获取到对应的节点,然而此时咱们是能够获取到 vue 中 data 与 methods 中的数据的;
在 mounted 阶段,vue 的 template 胜利挂载在 $el 中,此时一个残缺的页面曾经可能显示在浏览器中,所以在这个阶段,能够调用节点了;

// 以下为测试 vue 局部生命函数,便于了解
beforeCreate(){ // 创立前
console.log('beforecreate:',document.getElementById('first'))//null
console.log('data:',this.text);//undefined
this.sayHello();//error:not a function},
created(){ // 创立后
console.log('create:',document.getElementById('first'))//null
console.log('data:',this.text);//this.text
this.sayHello();//this.sayHello()
},
beforeMount(){ // 挂载前
console.log('beforeMount:',document.getElementById('first'))//null
console.log('data:',this.text);//this.text
this.sayHello();//this.sayHello()
},
mounted(){ // 挂载后
console.log('mounted:',document.getElementById('first'))//<p></p>
console.log('data:',this.text);//this.text
this.sayHello();//this.sayHello()
}

Vue 中 computed 与 method 的区别
相同点:
如果作为模板的数据显示,二者能实现响应的性能,惟一不同的是 methods 定义的办法须要执行
不同点:
1.computed 会基于响应数据缓存,methods 不会缓存;
2.diff 之前先看 data 里的数据是否发生变化,如果没有变动 computed 的办法不会执行,但 methods 里的办法会执行
3.computed 是属性调用,而 methods 是函数调用

虚构 DOM 中 key 的作用
简略的说:key 是虚构 DOM 对象的标识,在更新显示时 key 起着极其重要的作用。
简单的说:当状态中的数据产生了变动时,react 会依据【新数据】生成【新的虚构 DOM】,随后 React 进行【新虚构 DOM】与【旧虚构 DOM】的 diff 比拟,比拟规定如下:

旧虚构 DOM 中找到了与新虚构 DOM 雷同的 key
1. 若虚构 DOM 中的内容没有变,间接应用之前的真是 DOM
2. 若虚构 DOM 中内容变了,则生成新的实在 DOM,随后替换掉页面中之前的实在 DOM
旧虚构 DOM 中未找到与新虚构 DOM 雷同的 key
1. 依据数据创立新的实在 DOM,随后渲染到页面
用 index 作为 key 可能会引发的问题
若对数据进行:逆序增加 / 逆序删除等毁坏程序的操作,会产生没有必要的实在 DOM 更新,界面成果尽管没有问题,然而数据过多的话,会效率过低;
如果构造中还蕴含输出类的 DOM,会产生谬误 DOM 更新,界面有问题;
留神!如果不存在对数据的逆序操作,仅用于渲染表用于展现,应用 index 作为 key 是没有问题的。
Vue 中 watch 用法详解
在 vue 中,应用 watch 来监听数据的变动;
1. 监听的数据前面能够写成对象模式,蕴含 handler 办法,immediate 和 deep。
2.immediate 示意在 watch 中首次绑定的时候,是否执行 handler,值为 true 则示意在 watch 中申明的时候,就立刻执行 handler 办法,值为 false,则和个别应用 watch 一样,在数据发生变化的时候才执行 handler。
3. 当须要监听一个对象的扭转时,一般的 watch 办法无奈监听到对象外部属性的扭转,只有 data 中的数据才可能监听到变动,此时就须要 deep 属性对对象进行深度监听。

watch: {
name: {handler(newName, oldName) {

},
deep: true,
immediate: true
}
}

vue 中对 mixins 的了解和应用
mixins 是一种散发 Vue 组件中可复用性能的非常灵活的形式。混合对象能够蕴含任意组件选项。当组件应用混合对象时,所有混合对象的选项将被混入该组件自身的选项。
而 mixins 引入组件之后,则是将组件外部的内容如 data 等办法、method 等属性与父组件相应内容进行合并。相当于在引入后,父组件的各种属性办法都被裁减了。
可点击 vue 中对 mixins 的了解和应用的介绍作为参考

vue 中的插槽

或者点击 Vue 中组件神兵利器,插槽 Slot!查看详解!

为什么 vue 采纳异步渲染
vue 是组件级更新,以后组件里的数据变了,它就会去更新这个组件。当数据更改一次组件就要从新渲染一次,性能不高,为了避免数据一更新就更新组件,所以做了个异步更新渲染。(外围的办法就是 nextTick)

源码实现原理:
当数据变动后会调用 notify 办法,将 watcher 遍历,调用 update 办法告诉 watcher 进行更新,这时候 watcher 并不会立刻去执行,在 update 中会调用 queueWatcher 办法将 watcher 放到了一个队列里,在 queueWatcher 会依据 watcher 的进行去重,多个属性依赖一个 watcher,如果队列中没有该 watcher 就会将该 watcher 增加到队列中,而后通过 nextTick 异步执行 flushSchedulerQueue 办法刷新 watcher 队列。flushSchedulerQueue 中开始会触发一个 before 的办法,其实就是 beforeUpdate,而后 watcher.run() 才开始真正执行 watcher,执行完页面就渲染实现啦,更新实现后会调用 updated 钩子。
在这里插入图片形容

Vue 的异步更新机制是如何实现的?
Vue 的异步更新机制的外围是利用了浏览器的异步工作队列来实现的,首选微工作队列,宏工作队列次之。

当响应式数据更新后,会调用 dep.notify 办法,告诉 dep 中收集的 watcher 去执行 update 办法,watcher.update 将 watcher 本人放入一个 watcher 队列(全局的 queue 数组)。

而后通过 nextTick 办法将一个刷新 watcher 队列的办法(flushSchedulerQueue)放入一个全局的 callbacks 数组中。

如果此时浏览器的异步工作队列中没有一个叫 flushCallbacks 的函数,则执行 timerFunc 函数,将 flushCallbacks 函数放入异步工作队列。如果异步工作队列中曾经存在 flushCallbacks 函数,期待其执行实现当前再放入下一个 flushCallbacks 函数。

flushCallbacks 函数负责执行 callbacks 数组中的所有 flushSchedulerQueue 函数。

flushSchedulerQueue 函数负责刷新 watcher 队列,即执行 queue 数组中每一个 watcher 的 run 办法,从而进入更新阶段,比方执行组件更新函数或者执行用户 watch 的回调函数。

$nextTick 的了解
用法:
在下次 DOM 更新循环完结之后执行提早回调。在批改数据之后立刻应用这个办法,获取更新后的 DOM。
为什么?
Vue 实现响应式并不是数据发生变化之后 DOM 立刻变动,而是按肯定的策略进行 DOM 的更新。Vue 在更新 DOM 时是异步执行的。只有侦听到数据变动,Vue 将开启一个队列,并缓冲在同一事件循环中产生的所有数据变更。如果同一个 watcher 被屡次触发,只会被推入到队列中一次。这种在缓冲时去除反复数据对于防止不必要的计算和 DOM 操作是十分重要的。而后,在下一个的事件循环“tick”中,Vue 刷新队列并执行理论 (已去重的) 工作。
所以为了在数据变动之后期待 Vue 实现更新 DOM,能够在数据变动之后立刻应用 Vue.nextTick(callback)。这样回调函数将在 DOM 更新实现后被调用。
应用场景
在你更新完数据后,须要及时操作渲染好的 DOM 时

Vue 中罕用的一些指令
1.v-model 指令:用于表单输出,实现表单控件和数据的双向绑定。
2.v-on:简写为 @,根底事件绑定
3.v-bind:简写为:,动静绑定一些元素的属性,类型能够是:字符串、对象或数组。
4.v-if 指令:取值为 true/false,管制元素是否须要被渲染
5.v-else 指令:和 v -if 指令搭配应用,没有对应的值。当 v -if 的值 false,v-else 才会被渲染进去。
6.v-show 指令:指令的取值为 true/false,别离对应着显示 / 暗藏。
7.v-for 指令:遍历 data 中寄存的数组数据,实现列表的渲染。
8.v-once:通过应用 v-once 指令,你也能执行一次性地插值,当数据扭转时,插值处的内容不会更新

vue 的自定义指令
Vue 除了外围性能默认内置的指令,Vue 也容许注册自定义指令。
自定义指令是用来操作 DOM 的。只管 Vue 推崇数据驱动视图的理念,但并非所有状况都适宜数据驱动。自定义指令就是一种无效的补充和扩大,不仅可用于定义任何的 DOM 操作,并且是可复用的。

增加自定义指令的两种形式:

全局指令:通过 Vue.directive() 函数注册一个全局的指令。
部分指令:通过组件的 directives 属性,对该组件增加一个部分的指令。
能够参考如何写一个 Vue 自定义指令或 Vue.js 官网对于自定义指令的具体解说学习

你有写过自定义指令吗?自定义指令的利用场景有哪些?
能够参考如何写一个 Vue 自定义指令

v-show 和 v -if 指令的共同点和不同点
相同点:
v-show 和 v -if 都能管制元素的显示和暗藏。
不同点:
1. 实现实质办法不同:v-show 实质就是通过设置 css 中的 display 设置为 none; 管制暗藏 v -if 是动静的向 DOM 树内增加或者删除 DOM 元素;
2.v-show 都会编译,初始值为 false,只是将 display 设为 none,但它也编译了;v-if 初始值为 false,就不会编译了
总结:v-show 只编译一次,前面其实就是管制 css,而 v -if 不停的销毁和创立,如果要频繁切换某节点时,故 v -show 性能更好一点。

为什么防止 v -if 和 v -for 一起应用
vue2.x 版本中,当 v-if 与 v-for 一起应用时,v-for 具备比 v-if 更高的优先级;
vue3.x 版本中,当 v-if 与 v-for 一起应用时,v-if 具备比 v-for 更高的优先级。
官网明确指出:防止 v-if 和 v-for 一起应用,永远不要在一个元素上同时应用 v-if 和 v-for。

能够先对数据在计算数据中进行过滤,而后再进行遍历渲染;
操作和实现起来都没有什么问题,页面也会失常展现。然而会带来不必要的性能耗费;

vue 为什么在 HTML 中监听事件?
你可能留神到这种事件监听的形式违反了关注点拆散 (separation of concern) 这个长期以来的优良传统。但不用放心,因为所有的 Vue.js 事件处理办法和表达式都严格绑定在以后视图的 ViewModel 上,它不会导致任何保护上的艰难。实际上,应用 v-on 或 @ 有几个益处:

扫一眼 HTML 模板便能轻松定位在 JavaScript 代码里对应的办法。
因为你毋庸在 JavaScript 里手动绑定事件,你的 ViewModel 代码能够是十分纯正的逻辑,和 DOM 齐全解耦,更易于测试。
当一个 ViewModel 被销毁时,所有的事件处理器都会主动被删除。你毋庸放心如何清理它们。
Vue.set 扭转数组和对象中的属性
在一个组件实例中,只有在 data 里初始化的数据才是响应的,Vue 不能检测到对象属性的增加或删除,没有在 data 里申明的属性不是响应的, 所以数据扭转了然而不会在页面渲染;
解决办法:
应用 Vue.set(object, key, value) 办法将响应属性增加到嵌套的对象上

vm.$set(obj, key, val) 做了什么?
因为 Vue 无奈探测对象新增属性或者通过索引为数组新增一个元素,所以这才有了 vm.s e t,它 是 V u e . s e t 的 别 名。v m . set,它是 Vue.set 的别名。vm.set,它是 Vue.set 的别名。vm.set 用于向响应式对象增加一个新的 property,并确保这个新的 property 同样是响应式的,并触发视图更新。

为对象增加一个新的响应式数据:调用 defineReactive 办法为对象减少响应式数据,而后执行 dep.notify 进行依赖告诉,更新视图
为数组增加一个新的响应式数据:通过 splice 办法实现
说说 vue 的生命周期的了解
生命周期艰深说就是 Vue 实例从创立到销毁的过程,就是生命周期。
beforecreate(初始化界背后)
created(初始化界面后)
beforemount(渲染界背后)
mounted(渲染界面后)
beforeUpdate(更新数据前)
updated(更新数据后)
beforedestory(卸载组件前)
destroyed(卸载组件后)
留神:面试官想听到的不只是你说出了以上八个钩子名称,而是每个阶段做了什么?能够珍藏下图!
在这里插入图片形容

第一次页面加载会触发哪几个钩子?
第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子

Vue 组件通信有哪些形式
1. 父传子:props
父组件通过 props 向下传递数据给子组件。注:组件中的数据共有三种模式:data、props、computed

2. 父传子孙:provide 和 inject
父组件定义 provide 办法 return 须要分享给子孙组件的属性,子孙组件应用 inject 选项来接管指定的咱们想要增加在这个实例上的 属性;

3. 子传父:通过事件模式
子组件通过 $emit()给父组件发送音讯,父组件通过 v -on 绑定事件接收数据。

4. 父子、兄弟、跨级:eventBus.js
这种办法通过一个空的 Vue 实例作为地方事件总线(事件核心), 用它来(e m i t)触 发 事 件 和(emit)触发事件和(emit)触发事件和(on)监听事件,奇妙而轻量地实现了任何组件间的通信。

5. 通信插件:PubSub.js

6.vuex
vuex 是 vue 的状态管理器,存储的数据是响应式的。只须要把共享的值放到 vuex 中,其余须要的组件间接获取应用即可;

router 和 route 的区别
router 为 VueRouter 的实例,相当于一个全局的路由器对象,外面含有很多属性和子对象,例如 history 对象。。。常常用的跳转链接就能够用 this.$router.push,和 router-link 跳转一样。

route 相当于以后正在跳转的路由对象。。能够从外面获取 name,path,params,query 等

vue-router 有几种钩子函数?
1. 全局路由
全局导航钩子次要有两种钩子:前置守卫(beforeEach)、后置钩子(afterEach)

  1. 路由独享的钩子
    单个路由独享的导航钩子,它是在路由配置上间接进行定义的
routes: [
{
path: '/file',
component: File,
beforeEnter: (to, from ,next) => {//do something}
}
]

组件内的导航钩子
组件内的导航钩子次要有这三种:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他们是间接在路由组件外部间接进行定义的。
ps: 具体知识点能够点击路由导航守卫查看;
vue-router 路由跳转形式
申明式(标签跳转)

<router-link :to="{name:'home'}"></router-link>
<router-link :to="{path:'/home'}"></router-link>

编程式(js 跳转)

this.$router.push('/home')
this.$router.push({name:'home'})
this.$router.push({path:'/home'})

vue-router 路由传参
router-link 进行页面按钮式路由跳转传参
this.$router.push 进行编程式路由跳转传参

keep-alive 理解吗
< keep-alive > 是 Vue 的内置组件,能在组件切换过程中将状态保留在内存中,避免反复渲染 DOM。

< keep-alive > 包裹动静组件时,会缓存不流动的组件实例,而不是销毁它们。

Vuex 是什么?怎么应用?
Vuex 是实现组件全局状态(数据)治理的一种机制,能够不便实现组件数据之间的共享;Vuex 集中管理共享的数据,易于开发和前期保护;可能高效的实现组件之间的数据共享,进步开发效率;存储在 Vuex 的数据是响应式的,可能实时放弃页面和数据的同步;
Vuex 重要外围属性包含:state,mutations,action,getters,modules.

state
Vuex 应用繁多状态树, 即每个利用将仅仅蕴含一个 store 实例,但繁多状态树和模块化并不抵触。寄存的数据状态,不能够间接批改外面的数据。

mutations
mutations 定义的办法动静批改 Vuex 的 store 中的状态或数据。

action
actions 能够了解为通过将 mutations 外面处里数据的办法变成可异步的解决数据的办法,简略的说就是异步操作数据。view 层通过 store.dispath 来散发 action。

getters
相似 vue 的计算属性,次要用来过滤一些数据。

modules
我的项目特地简单的时候,能够让每一个模块领有本人的 state、mutation、action、getters, 使得构造十分清晰,方便管理。
ps: 具体应用和对其各属性的了解能够参考以下文章!
意识 vuex 和应用
外围概念 State 和 Mutation 的了解和应用
外围概念 Action 和 Getter 的了解和应用

什么状况下应用 Vuex?
如果利用够简略,最好不要应用 Vuex,一个简略的 store 模式即可;
须要构建一个中大型单页利用时,应用 Vuex 能更好地在组件内部治理状态;

Vuex 和单纯的全局对象有什么区别?
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地失去高效更新。
不能间接扭转 store 中的状态。扭转 store 中的状态的惟一路径就是显式地提交 (commit) mutation。这样使得咱们能够不便地跟踪每一个状态的变动,从而让咱们可能实现一些工具帮忙咱们更好地理解咱们的利用。

为什么 Vuex 的 mutation 中不能做异步操作?
每个 mutation 执行实现后都会对应到一个新的状态变更,这样 devtools 就能够打个快照存下来,而后就能够实现 time-travel 了。如果 mutation 反对异步操作,就没有方法晓得状态是何时更新的,无奈很好的进行状态的追踪,给调试带来艰难。

**axios 是什么,其特点和罕用语法
是什么?**

Axios 是一个基于 promise 的 HTTP 库,能够用在浏览器和 node.js 中。前端最风行的 ajax 申请库,
react/vue 官网都举荐应用 axios 发 ajax 申请
特点:

基于 promise 的异步 ajax 申请库,反对 promise 所有的 API
浏览器端 /node 端都能够应用,浏览器中创立 XMLHttpRequests
反对申请/响应拦截器
反对申请勾销
能够转换申请数据和响应数据,并对响应回来的内容主动转换成 JSON 类型的数据
批量发送多个申请
安全性更高,客户端反对进攻 XSRF,就是让你的每个申请都带一个从 cookie 中拿到的 key, 依据浏览器同源策略,混充的网站是拿不到你 cookie 中得 key 的,这样,后盾就能够轻松分别出这个申请是否是用户在混充网站上的误导输出,从而采取正确的策略。
罕用语法:
axios(config): 通用 / 最实质的发任意类型申请的形式
axios(url[, config]): 能够只指定 url 发 get 申请
axios.request(config): 等同于 axios(config)
axios.get(url[, config]): 发 get 申请
axios.delete(url[, config]): 发 delete 申请
axios.post(url[, data, config]): 发 post 申请
axios.put(url[, data, config]): 发 put 申请
axios.defaults.xxx: 申请的默认全局配置
axios.interceptors.request.use(): 增加申请拦截器
axios.interceptors.response.use(): 增加响应拦截器
axios.create([config]): 创立一个新的 axios(它没有上面的性能)
axios.Cancel(): 用于创立勾销申请的谬误对象
axios.CancelToken(): 用于创立勾销申请的 token 对象
axios.isCancel(): 是否是一个勾销申请的谬误
axios.all(promises): 用于批量执行多个异步申请
axios.spread(): 用来指定接管所有胜利数据的回调函数的办法

对 SSR 有理解吗,它次要解决什么问题?
Server-Side Rendering 咱们称其为 SSR,意为服务端渲染指由服务侧实现页面的 HTML 构造拼接的页面解决技术,发送到浏览器,而后为其绑定状态与事件,成为齐全可交互页面的过程;

解决了以下两个问题:

seo:搜索引擎优先爬取页面 HTML 构造,应用 ssr 时,服务端曾经生成了和业务想关联的 HTML,有利于 seo
首屏出现渲染:用户无需期待页面所有 js 加载实现就能够看到页面视图(压力来到了服务器,所以须要衡量哪些用服务端渲染,哪些交给客户端)
毛病

复杂度:整个我的项目的复杂度
性能会受到影响
服务器负载变大,绝对于前后端拆散务器只须要提供动态资源来说,服务器负载更大,所以要谨慎应用
Vue 要做权限治理该怎么做?管制到按钮级别的权限怎么做?
具体详解查看 Vue 要做权限治理该怎么做?管制到按钮级别的权限怎么做

Vue 我的项目前端开发环境申请服务器接口跨域问题
对于 vue-cli 2.x 版本在 config 文件夹配置服务器代理;
对于 vue-cli 3.x 版本前端配置服务器代理在 vue.config.js 中设置服务器代理;如下图:
在这里插入图片形容

target 对应的属性值为你筹备向后端服务器发送申请的主机 + 端口,含意为:相当于把前端发送申请的主机 + 端口主动替换成挂载的主机和端口,这样前后端的主机端口都一一就不会存在跨域问题;
ws: 示意 WebSocket 协定;
changeOrigin:true; 示意是否扭转原域名;这个肯定要抉择为 true;
这样发送申请的时候就不会呈现跨域问题了。

做过哪些 Vue 的性能优化?
编码阶段

尽量减少 data 中的数据,data 中的数据都会减少 getter 和 setter,会收集对应的 watcher
v-if 和 v -for 不能连用
如果须要应用 v -for 给每项元素绑定事件时应用事件代理
SPA 页面采纳 keep-alive 缓存组件
在更多的状况下,应用 v -if 代替 v -show
key 保障惟一
应用路由懒加载、异步组件
防抖、节流
第三方模块按需导入
长列表滚动到可视区域动静加载
图片懒加载
SEO 优化

服务端渲染 SSR
预渲染
打包优化

压缩代码
Tree Shaking/Scope Hoisting
应用 cdn 加载第三方模块
多线程打包 happypack
splitChunks 抽离公共文件
sourceMap 优化
Vue3 有理解过吗?能说说跟 Vue2 的区别吗?
具体详解请点击 Vue3 有理解过吗?能说说跟 Vue2 的区别吗?

Vue 3.0 所采纳的 Composition Api 与 Vue 2.x 应用的 Options Api 有什么区别?
Options Api

蕴含一个形容组件选项(data、methods、props 等)的对象 options;
API 开发简单组件,同一个性能逻辑的代码被拆分到不同选项;
应用 mixin 重用专用代码,也有问题:命名抵触,数据起源不清晰;

Composition Api

vue3 新增的一组 api,它是基于函数的 api,能够更灵便的组织组件的逻辑。
解决 options api 在大型项目中,options api 不好拆分和重用的问题。

element-ui 中遇到的问题
1.el-cascader 多选在 IE 中款式不失常
在这里插入图片形容
2. 级联选择器高度问题
3.Table 固定列下呈现线条

正文完
 0