精华内容
下载资源
问答
  • 2020 Vue经典面试题

    2021-01-03 13:57:54
    (一)VUE经典基础(1)  1.mvvm 框架是什么?  2.vue的优点是什么?(为什么大部分公司选择vue)  3.vue的两个核心点是什么?  4. 三大框架的优缺点?(vue、Angular、React)  5.vue和jQuery的区别?  6.渐...
  • 经典面试题: 2021Vue经典面试题总结(含答案).pdf
  • 面试必备:2019Vue经典面试题总结(含答案) 一、什么是MVVM? MVVM是Model-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件...

    面试必备:2021 Vue经典面试题总结(含答案)


    一、什么是 MVVM ?

    MVVMModel-View-ViewModel的缩写。MVVM是一种设计思想。Model 层代表数据模型,也可以在Model中定义数据修改和操作的业务逻辑;View 代表UI 组件,它负责将数据模型转化成UI 展现出来,ViewModel 是一个同步ViewModel的对象。

    MVVM架构下,ViewModel 之间并没有直接的联系,而是通过ViewModel进行交互,ModelViewModel 之间的交互是双向的, 因此View 数据的变化会同步到Model中,而Model 数据的变化也会立即反应到View 上。

    ViewModel 通过双向数据绑定把 View 层和 Model 层连接起来,而ViewModel 之间的同步工作完全是自动的,无需人为干涉,因此开发者只需关注业务逻辑,不需要手动操作DOM, 不需要关注数据状态的同步问题,复杂的数据状态维护完全由 MVVM 来统一管理。

    二、mvvm 与 mvc 区别?它和其它框架(jquery)的区别是什么?哪些场景适用?

    mvcmvvm其实区别并不大,都是一种设计思想。主要就是mvcController演变成mvvm中的viewModelmvvm主要解决了mvc中大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。

    区别:vue数据驱动,通过数据来显示视图层而不是节点操作。

    场景:数据操作比较多、频繁的场景,更加便捷。

    三、vue 优点?

    • 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。

    • 可重用性。可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。

    • 独立开发开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计。

    • 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

    四、 组件之间的传值?

    • 父组件通过标签上:data=data方式定义传值

    • 子组件通过props方法接受数据

    • 子组件通过$emit方法传递参数

    详参博文:

    五、路由之间跳转

    • 声明式(标签跳转

    • 编程式( js跳转

    详参博文:

    六、vue.cli 中怎样使用自定义组件?遇到过哪些问题?

    第一步:在components目录新建组件文件(indexPage.vue),script一定要export default {}

    第二步:在需要用的页面(组件)中导入:import indexPage from '@/components/indexPage.vue'

    第三步:注入到vue子组件的components属性上面,components:{indexPage}

    第四步:在template视图view中使用,例如有indexPage命名,使用的时候则index-page
    在这里插入图片描述

    七、vue 如何实现按需加载配合 webpack 设置

    webpack中提供了require.ensure()来实现按需加载。以前引入路由是通过import 这样的方式引入,改为const定义的方式进行引入。

    页面不按需加载引入方式:import home from '../../common/home.vue'

    页面按需加载引入方式:

    const home = r => require.ensure( [], () => r (require('../../common/home.vue')))
    

    八、vuex 面试相关

    (1)vuex是什么?怎么使用?哪种功能场景使用它?

    vue框架中状态管理。在main.js引入store注入。新建一个目录store 。场景有:单页应用中,组件之间的状态,音乐播放、登录状态、加入购物车等。

    (2)vuex有哪几种属性?

    有五种,分别是 StateGetterMutationActionModule

    (3) vuexState特性

    • Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data

    • state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新。

    • 通过mapState把全局 stategetters 映射到当前组件的 computed 计算属性中。

    (4)vuexGetter特性

    • getters 可以对State进行计算操作,它就是Store的计算属性。

    • 虽然在组件内也可以做计算属性,但是getters 可以在多组件之间复用。

    • 如果一个状态只在一个组件内使用,可以不用getters

    (5)vuexMutation特性

    Action 类似于 mutation,不同在于:Action 提交的是 mutation,而不是直接变更状态;Action 可以包含任意异步操作。

    (6)不用Vuex会带来什么问题?

    • 可维护性会下降,想修改数据要维护三个地方;

    • 可读性会下降,因为一个组件里的数据,根本就看不出来是从哪来的;

    • 增加耦合,大量的上传派发,会让耦合性大大增加,VueComponent本意就是为了减少耦合,现在这么用,和组件化的初衷相背。

    详参博文:

    九、 v-show 与 v-if 的区别?

    • v-show指令是通过修改元素的displayCSS属性让其显示或者隐藏;

    • v-if指令是直接销毁重建DOM达到让元素显示和隐藏的效果;

    • 使用v-show会更加节省性能上的开销;当只需要一次显示或隐藏时,使用v-if更加合理。
      在这里插入图片描述

    十、 如何让 CSS 只在当前组件中起作用?

    将当前组件的<style>修改为<style scoped>

    十一、keep-alive 的作用是什么?

    包裹动态组件时,会缓存不活动的组件实例,主要用于保留组件状态避免重新渲染

    详参博文:

    十二、Vue 组件引入步骤?

    1. 采用ES6import ... from ...语法或CommonJSrequire()方法引入组件;

    2. 对组件进行注册,代码如下

      // 注册
      Vue.component('my-component', { template:'
      	A custom component!
      '})
      
    3. 使用组件<my-component> </my-component>

    详参博文:

    十三、v-el 作用是什么?

    提供一个在页面上已存在的 DOM 元素作为 Vue 实例的挂载目标。可以是 CSS 选择器,也可以是一个 HTMLElement 实例。
    在这里插入图片描述

    十四、Vue 插件使用步骤

    1. 采用ES6import ... from ...语法或CommonJSrequire()方法引入插件。

    2. 使用全局方法Vue.use( plugin )使用插件,可以传入一个选项对象Vue.use(MyPlugin, { someOption: true })

    十五、列举出3个 Vue 中常用的生命周期钩子函数

    • created: 实例创建完成之后调用,在这一步,实例已经完成数据观测、 属性和方法的运算、watch/event事件回调。然而,挂载阶段还没有开始, $el属性目前还不可见。

    • mounted: el被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子。如果 root 实例挂载了一个文档内元素,当 mounted 被调用时 vm.$el 也在文档内。

    • activated: keep-alive组件激活时调用。

    详参博文:

    十六、active-class 是哪个组件的属性?

    vue-router模块的router-link组件。

    十七、如何定义 vue-router 动态路由以及如何获取传过来的动态参数?

    详参博文:

    十八、vue-router 有哪几种导航钩子?

    共分三种。

    第一种:全局导航钩子router.beforeEach(to,from,next),作用:跳转前进行判断拦截。

    第二种:组件内钩子

    第三种:单独路由独享组件

    详参博文:

    十九、生命周期相关面试题

    在这里插入图片描述
    总共分为8个阶段:创建前/后载入前/后更新前/后销毁前/后

    • 创建前/后: 在beforeCreate阶段,由于还未初始化,vue实例的挂载元素el和数据对象data都为undefined。在created阶段,vue实例的数据对象data有了,el还没有。

    • 载入前/后:在beforeMount阶段,vue实例的$eldata都初始化了,但挂载之前还是为虚拟的dom节点,data.message还未替换。在mounted阶段,vue实例挂载完成,data.message成功渲染。

    • 更新前/后:当data变化时,会触发beforeUpdateupdated方法。

    • 销毁前/后:在执行destroy方法后,对data的改变不会再触发周期函数,说明此时vue实例已经解除了事件监听以及和dom的绑定,但是dom结构依然存在。

    (1)什么是vue生命周期?

    Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建初始化数据编译模板挂载Dom渲染、更新渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。

    (2)vue生命周期的作用是什么?

    Vue生命周期中有多个事件钩子,让我们在控制整个Vue实例过程时更容易形成好的逻辑。

    (3)vue生命周期总共有几个阶段?

    可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/后

    (4)第一次页面加载会触发哪几个钩子?

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

    (5)DOM 渲染在 哪个周期中就已经完成?

    DOM 渲染在 mounted 中就已经完成了。

    (6)简单描述每个周期具体适合哪些场景?

    生命周期钩子的一些使用方法:

    • beforecreate : 可以在此阶段加loading事件,在加载实例时触发;

    • created : 初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用;

    • mounted : 挂载元素,获取到DOM节点;

    • updated : 如果对数据统一处理,在这里写上相应函数;

    • beforeDestroy : 可以做一个确认停止事件的确认框;

    • nextTick : 更新数据后立即操作dom

    详参博文:

    二十、说出至少4种vue指令和它的用法?

    • v-if:判断是否隐藏;
    • v-for:数据循环;
    • v-bind:class:绑定一个属性;
    • v-model:实现双向绑定;

    Vue如何创建自定义指令?

    详参博文:

    二十一、vue-loader是什么?用途有哪些?

    解析.vue文件的一个加载器。

    用途:js可以写es6style样式可以scsslesstemplate可以加jade等。
    在这里插入图片描述

    二十二、scss 是什么?在 vue.cli 中的安装使用步骤?有哪几大特性?

    css的预编译语言。

    使用步骤:

    第一步:先装css-loadernode-loadersass-loader等加载器模块;

    第二步:在build目录找到webpack.base.config.js,在extends属性中加一个拓展.scss

    第三步:在同一个文件,配置一个module属性;

    第四步:然后在组件的style标签加上lang属性 ,例如:lang=”scss”

    特性:

    • 可以用变量,例如($变量名称=值);

    • 可以用混合器;

    • 可以嵌套;

    详参博文:

    二十三、页面渲染为什么使用 key?

    当有相同标签名的元素切换时,为避免渲染问题,需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们,否则 Vue 为了效率只会替换相同标签内部的内容。

    详参博文:

    二十四、为什么避免 v-if 和 v-for 一起用?

    Vue 处理指令时,v-forv-if 具有更高的优先级,通过v-if 移动到容器元素,不会再重复遍历列表中的每个值。取而代之的是,只检查它一次,且不会在 v-if 为否的时候运算 v-for

    二十五、VNode 是什么?虚拟 DOM 是什么?

    Vue在页面上渲染的节点,及其子节点称为“虚拟节点 (Virtual Node)”,简写为“VNode”。“虚拟 DOM”是由 Vue 组件树建立起来的整个 VNode 树的称呼。

    详参博文:

    二十六、动态绑定 Class 有几种方式?

    详参博文:

    二十七、Vue 插槽

    详参博文:

    二十八、场景面试题:异步更新队列 - $nextTick()

    详参博文:

    二十九、场景面试题:mixins异步请求处理

    详参博文:

    三十、场景面试题:父子组件传值-生命周期

    详参博文:

    三十一、拓展阅读

    展开全文
  • Vue经典面试题

    2020-11-14 17:27:15
    Vue 经典面试题 一,vue是什么 vue是一套用于构建用户界面的渐进式框架,它的很大的特点是,vue被设计为自底向上逐层应用,vue的核心库只关注视图层,不仅易于上手,还便于与第三方库和已有项目整合 二,对于MVVM的...

    Vue 经典面试题

    一,vue是什么

    vue是一套用于构建用户界面的渐进式框架,它的很大的特点是,vue被设计为自底向上逐层应用,vue的核心库只关注视图层,不仅易于上手,还便于与第三方库和已有项目整合

    二,对于MVVM的理解

    mvvm 是model-view-viewModel 的简写

    model代表数据模型, 也可以在model中定义数据修改和操作的业务逻辑

    view代表视图 它动态的将数据结合页面展示给用户

    viewModel监听数据的变化,控制页面的渲染,在view和model搭建联系实现数据的双向绑定,解放了开发者的生产力,开发者可以专注开发逻辑,操作dom的任务交予vm处理。
    ie

    三,vue的生命周期钩子

    1. beforeCreate : 创建前,在数据观测和初始化事件以前
    2. created : 创建后,完成数据初始化,属性和方法的运算,初始化事件,el挂载还没有显示
    3. beforeMount:载入前,在挂载开始以前调用,相关的渲染函数首次被调用,vue实例完成了 编译模板、把data数据和模板生成html,但是还没有将html挂载到页面上
    4. mounted : 载入后 将渲染成功的页面挂载到实例上 ,同时进行ajax交互
    5. beforeUpdate : 更新前 在数据更新前调用,发生在虚拟dom重新渲染和打补丁之前,不会触发附加的重渲染
    6. updated: 更新后 由于数据的更改导致虚拟的dom重新渲染和打补丁之后调用,调用时dom已经更新,所以可以执行有关dom的操作, 该钩子在服务器渲染过程中不被调用
    7. beforeDestroy : 销毁前 ,在实例销毁之前调用,实例仍然可用
    8. destroyed 销毁后,在实例销毁后调用,调用后所有的事件监听器会被移除,所欲子实例被销毁,该钩子在服务器端渲染器不仅调用

    四,Vue实现数据双向绑定的原理

    vue实现双向绑定的原理 主要是 采用数据劫持 结合发布订阅着模式,通过Object.defineProperty()

    来劫持各个属性的setter 和getter ,在数据发生变化时,发布者将消息传给订阅者,并且执行相应的函数,实现视图的更新

    五,vue组件的参数传递

    1.父组件传值给子组件

    父组件 传递给子组件 通过props方法接受数据

    子组件传递给父组件,通过$emit方法传递参数

    2.非父子组件的数据传递

    项目小: 创建一个bus对象,当做事件中心,即中转站 用来传递事件和接受事件

    项目大: 用vuex的stroe存储数据

    六, 请求数据的方式

    1.axios: vue中的ajax 用于向后台发起请求,其特点有从浏览器中创建XMLHttpRequests 、从node.js创建http请求 、支持Promise API ,

    2.fetch : 属于w3c标准 需要舒勇两次then函数获取数据

    七.vue的路由实现,hash模式和history模式

    hash模式,标志在路径中有# #后面的字符称之为hash 用window.location.hash读取

    ​ 特点: hash虽然在url中但是不被包括在http请求中,用来指导服务器动作,但对服务器安全没用 hash不会重载页面

    **history模式:**history采用了html5的新特性,并且提供了两个方法pushState() 和replace()

    可以对浏览器历史记录栈修改,在此模式下前端的url必须和实际向后端请求的url地址一样

    八、vuex

    是一个专门为vue,js应用程序开发的状态管理模式,可以帮助管理全局的数据

    主要有五个核心特性

    1.state :

    放置项目所需的数据 在组件上调用命令 $store.state

    2.mutation

    放置操作state数据方法的的集合 在组件上调用 命令 $store.commit(‘方法名’)

    3.action

    害怕异步进行操作出错,将state中的数据搞乱。所以使用action来进行异步操作。

    4.getters

    可以对state中的数据复杂化传递给外界

    5.module

    当项目比较大,状态非常多时,采用模块化管理模式,vuex允许我们将store分成module 每个模块又有其自己的state,mutation action getterske

    九,keep-alive的作用

    当用keep-alive包裹动态组件时,会缓冲组件实例,可以保留组件状态,不用销毁,也就节省资源,当再次切换到该组件时,直接从缓冲中加载。

    十、导航钩子有哪些?以及导航过程

    1全局导航钩子

    全局前置钩子:beforeEach((to,from,next)=>{})

    to,:router 代表进入的目标路由

    from: router 代表从哪个路由来

    next :离开本路由必须调用的方法,执行需要使用next的参数

    全局后置钩子afterEach((to,from)=>{})

    没有next

    2.单个路由专享

    beforeEnter

    3、组件级导航

    beforeRouterEnter 、 beforeRouterUpdate、 beforeRouterLeave

    导航过程
    1. 导航被触发
    2. 在失活的组件里调用离开守卫
    3. 调用全局的beforeEach守卫
    4. 在重用的组件里调用beforeRouterUpdate
    5. 在路由配置中调用beforeEnter
    6. 解析异步路由组件
    7. 在被激活的组件中调用beforeRouterEnter
    8. 调用全局的beforeResolve 守卫
    9. 导航被确认
    10. 调用全局afterEach钩子
    11. 触发dom更新
    12. 在创建好的实例调用beforeRouterEnter守卫中传给next回调函数

    十一、vue.js和angular 以及react的区别

    1.与angularJS的区别
    相同点:
    1. 都支持指令: 内置指令和自定义指令
    2. 都支持过滤器: 内置过滤器和自定义过滤器
    3. 都支持双向数据绑定
    4. 都不支持低端浏览器
    不同点:
    1. AngularJS的学习成本高,比如增加了Dependency ,Injection 的特性,而 Vue.js本身提供的API都比较直观,简单
    2. 在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢 vue是基于依赖对数据追踪的观察并且只用异步队列更新,所有的数据都是独立触发的 。 对于庞大的应用来说,这个优化差异还是比较明显的
    2.与React的区别
    相同点:
    1. react采用特殊的JSX语法,Vue在组件开发中也推崇编写vue特殊文件格式,对文件内容有一定的约定,要编译后使用
    2. 中心思想相同,一切都是组件,组件实例之间可以嵌套
    3. 都提供合理的钩子函数,可以让开发者定制化地去处理请求
    4. 都不内置列数AJAX Route 等功能核心包,而是以插件的方式加载
    5. 在组件开发中都支持mixins的特性
    不同点:

    react 依赖Virtual DOM 而vue使用的是dom模板,react采用的VirtualDOM 会对渲染出来的结果做脏检查,vue在模板中提供了指令,过滤器,非常方便的操作DOM

    十二、关于vue 的 render 谈谈你的理解

    Vue一般使用template来创建html,然而我们也会用到原生js来创建dom,这时候我们就需要render函数,render函数会返回一个createElement 组件中的子元素存储在组件实例中$solts.default 中在createElement中包含的信息会告诉vue页面怎么渲染节点 这些节点也就是虚拟DOM

    展开全文
  • 2022vue经典面试题.pdf

    2021-12-14 17:32:34
    2022vue经典面试题.pdf
  • 2021 Vue经典面试题.pdf

    2021-12-14 15:13:54
    2021 Vue经典面试题.pdf
  • 整理的vue20道经典面试题,由初级到中高级,高级部分可以忽略
  • 面试必备: 2021 Vue经典面试题总结.pdf
  • Vue经典面试题_227题(部分题没答案).pdf_前端面试题
  • vue经典面试题

    2020-08-05 10:50:24
    这里写自定义目录标题欢迎使用Markdown编辑器1、讲一下什么是MVVM1、简单说一下Vue2.x响应式数据原理2、简单说一下Vue3.x响应数据原理3、vue2.x中如何监听数组的变化4、nextTick知道吗?实现原理是什么生成一个适合...

    0、讲一下什么是MVVM

    MVVM是Model-View-ViewModel缩写,也就是把MVC中的Controller演变成ViewModel。Model层代表数据模型,View代表UI组件,ViewModel是View和Model层的桥梁,数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。

    1、简单说一下Vue2.x响应式数据原理

    Vue在初始化数据时,会使用Object.defineProperty重新定义data中的所有属性,当页面使用对应属性时,首先会进行依赖收集(收集当前组件的watcher)如果属性发生变化会通知相关依赖进行更新操作(发布订阅)。

    2、简单说一下Vue3.x响应数据原理

    Vue3.x改用Proxy替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。

    Proxy只会代理对象的第一层,那么Vue3又是怎样处理这个问题的呢?

    判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。

    监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?

    可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一,才有可能执行trigger。

    3、vue2.x中如何监听数组的变化

    使用函数劫持的方式,重写了数组方法,vue将data中的数组进行了原型链的重写,指向自己定义的数组原型方法,这样当调用数组api时,可以通知依赖更新,如果数组中包含着引用类型,会对数组中的引用类型再次递归遍历进行监控,这样就实现了监测数组变化。

    4、nextTick知道吗?实现原理是什么

    在下次DOM更新循环结束之后执行延迟回调,nextTick主要使用了宏任务和微任务,根据执行环境分别常尝试采用。

    • Promise
    • MutationObserver
    • setImmediate
    • 如果以上均不行就采用setTimeout
      定义了一部方法,多次调用nextTick会将方法存到队列中,通过异步方法清空当前队列。

    5、谈谈Vue的生命周期

    beforeCreate是new Vue()之后触发的第一个钩子,在当前阶段data、methods、computed以及watch上的数据和方法都不能被访问。

    created在实例创建完成后发生,当前阶段已经完成了数据观测,也就是可以使用数据,更改数据,在这里更改数据不会触发updated函数。可以做一些初始数据的获取,在当前阶段无法与Dom进行交互,如果非要想,可以通过vm.$nextTick来访问Dom。

    beforeMount发生在挂载之前,在这之前template模板已导入渲染函数编译。而当前阶段虚拟Dom已经创建完成,即将开始渲染。在此时也可以对数据进行更改,不会触发updated。

    mounted在挂载完成后发生,在当前阶段,真实的Dom挂载完毕,数据完成双向绑定,可以访问到Dom节点,使用$refs属性对Dom进行操作。

    beforeUpdate发生在更新之前,也就是响应式数据发生更新,虚拟dom重新渲染之前被触发,你可以在当前阶段进行更改数据,不会造成重渲染。

    updated发生在更新完成之后,当前阶段组件Dom已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新。

    beforeDestroy发生在实例销毁之前,在当前阶段实例完全可以被使用,我们可以在这时进行善后收尾工作,比如清除计时器。

    destroyed发生在实例销毁之后,这个时候只剩下了dom空壳。组件已被拆解,数据绑定被卸除,监听被移出,子实例也统统被销毁。

    6、对接口的请求一般放在哪个生命周期中?

    接口请求一般放在mounted中,但是要注意的是服务端渲染时不支持mounted,需要放到crested中。

    7、说一下Computed和watch

    computed: {
          ...mapGetters(['userType'])
        },
    
    computed: {
            scopedRules() {
              let validatePin = (rule,value,callback)=> {
                  if(value != this.pinForm.newPin){
                    callback(new Error('两次口令不一致'));
                  }
                  else{
                    callback();
                  }
              };
              let validatePwd = (rule,value,callback)=> {
                if(value != this.pwdForm.newPwd){
                  callback(new Error('两次密码不一致'));
                }
                else{
                  callback();
                }
              };
              return Object.assign({
                oldPin:[
                  {required:true,message:'不能为空',trigger:'blur'},
                  {pattern:/^[0-9]{6,16}$/,message:'安全口令为6到16位的数字',trigger:'blur'},
                ]
              },this.myRules)
            }
          },
    

    Computed本质是具备缓存的watcher依赖的属性发生变化就会更新视图,适用于计算比较消耗性能的计算场景,当表达式过于复杂时候,在模板中放入过多的逻辑会使模板难以维护,可以将复杂的逻辑放入计算属性中处理,

    watch****没有缓存性,更多的是观察作用,可以监听到某些数据执行回调,当我们需要深入监听对象的属性时,可以打开deep:true选项,这样便会对对象中的每一项进行监听,这样hi带来性能问题,优化的话,可以使用字符串形式监听,如果没写写到组件中,不要忘记使用unWatch手动注销。

    例子: 是监听newWarn对象的alertType属性。

     watch:{
          newWarn:{
            handler:function(val, oldVal){
              if(this.newWarn.alertType == 305){
                this.warnTypeChoose = 2;
               }else{
                this.warnTypeChoose = 3;
              }
            },
            deep: true
          },
        },
    

    8、说一下v-if与v-show的区别

    当条件不成立时,v-if不会渲染DOM元素,v-show操作的是样式,切换当前的DOM是显示还是隐藏。

    9、数组中的data为什么是个函数

    data(){
          return{
            RSUInfo:{},
            handActive:true,
          }
    

    一个数组被多次复用的话,也就会创建多个实例,实质上,这些实例用的都是同一个构造函数,如果data是对象的话,对象属于引用类型,会影响到所有的实例
    为了保证组件不同的实例之间data不冲突,data必须是一个函数。

    10、说一下v-model的原理

    v-model本质是一个语法糖,可以看成value_input方法的语法糖,可以通过model属性的prop和event属性来进行定义,原生的v-model,会根据标签的不同生成不同的事件和属性。

    11、vue事件绑定原理说一下。

    原生事件绑定是 通过addEventListener绑定给真是元素的,组件事件绑定是通过Vue自定义的$on实现的。

    <span @click="handout()" class="tabInfo" :class="{'active':handActive}">平台下发预警</span>
    

    12、vue模板编译原理

    简单的说,vue的编译过程就是将template转化为render函数的过程,会经历以下阶段。

    • 生成AST树
    • 优化
    • codegen

    首先解析模板,生成AST语法树(一种用Javascript对象的形式来描述整个模板)使用大量的正则表达式对模板进行解析,遇到标签,文本的时候都会执行对应的钩子进行相关处理。
    vue的数据是响应的,但其实模板中并不是所有的数据都是响应的,有些数据首次渲染后就不会再变化,对应的dom也不会变化,那么优化过程就是深度遍历AST树,按照相关条件对树节点进行标记,这些被标记的节点我们就可以跳过它们的对比,对运行时的模板起到很大的优化作用。
    编译的最后一步是 将优化后的AST树转换为可执行的代码。

    13、vue2.x和vue3.x渲染器的diff算法分别说一下

    简单来讲,diff算法有以下过程

    1. 同级比较,再比较子节点
    2. 先判断一方有子节点一方没有子节点的情况
    3. 比较都有子节点的情况(核心diff)
    4. 递归比较子节点

    正常Diff两个树的时间复杂度是O(n^3), 但实际情况下我们很少会进行跨层级的移动DOM,所以Vue将Diff进行了优化,从O(n^3) -> O(n),只有当新旧children都为多个子节点时才需要用核心的Diff算法进行同层级比较。
    Vue2的核心Diff算法采用了双端比较的算法,同时从新旧children的两端开始进行比较,借助key值找到可复用的节点,再进行相关操作。相比React的Diff算法,同样情况下可以减少移动节点次数,减少不必要的性能损耗,更加的优雅。
    Vue3.x借鉴了ivi算法inferno算法在创建VNode时就确定其类型,以及在mount/patch的过程中采用位运算来判断一个VNode的类型,在这个基础之上再配合核心的Diff算法,使得性能上较Vue2.x有了提升。(实际的实现可以结合Vue3.x源码看。)
    该算法中还运用了动态规划的思想求解最长递归子序列。
    (看到这你还会发现,框架内无处不蕴藏着数据结构和算法的魅力)

    14、说一下虚拟Dom以及key属性的作用

    由于在浏览器中操作DOM是很昂贵的,频繁的操作DOM会产生一定的性能问题,这是虚拟DOM产生的原因。

    Vue2的 Virtual DOM借鉴了开源snabbdom的实现。

    Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点,是对真是的DOM的一层抽象。

    VirtualDOM映射到真实的DOM要经理VNode的create,diff,patch等阶段。

    key的作用是尽可能的复用DOM元素

    新旧children中的节点只有顺序是不同的时候,最佳的操作应该是通过移动元素的位置来达到更新的目的

    需要在新旧children的节点中保存映射关系,以便能够在旧children得节点中找到可复用的节点,key业绩居士children中节点的唯一标识。

    15、keep-alive了解吗?

    keep-alive可以实现组件缓存,当组件切换时候不会对当前组件进行卸载。
    常用的两个属性 include/exclude,允许组件有条件的进行缓存。

    两个生命周期activated/deactivated,用来得知当前组件是否处于活跃状态。

    keep-alive的中还运用了LRU(Least Recently Used)算法。

    <template>
        <el-container>
            <el-header/>
            <el-container>
                <Aside></Aside>
                <el-main>
                    <transition>
                        <keep-alive>
                            <router-view></router-view>
                        </keep-alive>
                    </transition>
                </el-main>
            </el-container>
        </el-container>
    </template>
    

    这里就运用到了keep-alive 用来防止组件重复加载,浪费资源。用于切换数据不怎么变化的页面,这样使用mounted中的接口请求不会在切换页面的时候触发。

    16.Vue中组件生命周期调用顺序说一下

    组件的调用顺序都是先父后子,渲染完成的顺序是先子后父。
    组件的销毁操作是先父后子,销毁完成的顺序是先子后父。
    加载渲染过程

    父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount- >子mounted->父mounted

    子组件更新过程

    父beforeUpdate->子beforeUpdate->子updated->父updated

    父组件更新过程

    父 beforeUpdate -> 父 updated

    销毁过程

    父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

    17、vue2.x组件通信有哪些方式

    父子组件通信

    父->子props,子->父 o n 、 on、 onemit

    获取父子组件实例 p a r e n t 、 parent、 parentchildren

    Ref 获取实例的方式调用组件的属性或者方法

    Provide、inject 官方不推荐使用,但是写组件库时很常用

    兄弟组件通信

    Event Bus 实现跨组件通信 Vue.prototype.$bus = new Vue

    Vuex

    跨级组件通信

    Vuex

    a t t r s 、 attrs、 attrslisteners

    Provide、inject

    18、了解SSR吗?

    SSR也是服务端渲染,也就是讲Vue在客户端把标签渲染成HTML的工作放在服务端完成,然后再把HTML直接返回给客户端。

    SSR有着更好的SEO,并且首屏加载速度更快等优点,不过也有一些缺点,比如我们开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子,当我们需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境,还有就是服务器会有更大的负载要求。

    19、vue的性能优化包含哪些

    编码阶段

    1. 尽量减少data中的数据,data中的数据会增加getter和setter,会收集对应的watcher
    2. v-if 和 v-for不能连用
    3. 如果需要使用v-for给每项元素绑定事件时使用事件代理
    4. SPA使用keep-alive缓存组件
    5. 在更多情况下,使用v-if代替v-show
    6. key保证唯一
    7. 使用路由懒加载、异步组件
    8. 防抖、节流
    9. 第三方模块按需导入
    10. 长列表滚动到可视区域动态加载
    11. 图片懒加载

    SEO优化

    1. 预渲染
    2. 服务端渲染SSR

    打包优化

    1. 压缩代码
    2. Tree Shaking/Scope Hoisting
    3. 使用Cdn加载第三方模块
    4. 多线程打包happypack
    5. splitChunks抽离公共文件
    6. sourceMap优化

    用户体验

    1. 骨架屏
    2. pwa
      
    3. 还可以使用缓存优化,服务端开启gzip压缩等

    20、hash路由和history路由原理

    location.hash的值实际就是URL中#后面的东西。

    history实际采用了HTML5中提供的API来实现,主要有history.pushState()和history.replaceState()

    参考

    之前再掘金上看到童欧巴的这篇文章,看了很多遍,感觉语言通俗易懂,对于准备Vue面试的同学很有帮助,结合自己的代码,整理了这个原文摘自 https://juejin.im/post/6844904084374290446#heading-14

    展开全文
  • 2021年 Vue经典面试题 -- 必问知识点 --(包含答案)

    千次阅读 多人点赞 2021-05-17 10:44:21
    1.说说你对MVVM的理解 Model–View–ViewModel (MVVM) 是一个软件架构设计模式,由微软 WPF 和 ...MVVM 源自于经典的 Model–View–Controller(MVC)模式 ,MVVM 的出现促进了前端开发与后端业务逻辑的分离,极

    敬请关注公众 :包含免费的全套 Vue 最新面试题  最新js 以及等输入技术知识点,底层原理等

    1.说说你对MVVM的理解

    Model–View–ViewModel (MVVM) 是一个软件架构设计模式,由微软 WPF 和 Silverlight 的架构师 Ken Cooper 和 Ted Peters 开发,是一种简化用户界面的事件驱动编程方式。由 John Gossman(同样也是 WPF 和 Silverlight 的架构师)于2005年在他的博客上发表

    MVVM 源自于经典的 Model–View–Controller(MVC)模式 ,MVVM 的出现促进了前端开发与后端业务逻辑的分离,极大地提高了前端开发效率,MVVM 的核心是 ViewModel 层,它就像是一个中转站(value converter),负责转换 Model 中的数据对象来让数据变得更容易管理和使用,该层向上与视图层进行双向数据绑定,向下与 Model 层通过接口请求进行数据交互,起呈上启下作用。如下图所示:

     

    (1)View 层

    View 是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建 。

    (2)Model 层

    Model 是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。

    (3)ViewModel 层

    ViewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,比如页面的这一块展示什么,而页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互),视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。

    MVVM 框架实现了双向绑定,这样 ViewModel 的内容会实时展现在 View 层,前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图,MVVM 框架已经把最脏最累的一块做好了,我们开发者只需要处理和维护 ViewModel,更新数据视图就会自动得到相应更新。这样 View 层展现的不是 Model 层的数据,而是 ViewModel 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。

    我们以下通过一个 Vue 实例来说明 MVVM 的具体实现,有 Vue 开发经验的同学应该一目了然:

    (1)View 层

    <div id="app">

        <p>{{message}}</p>

        <button v-on:click="showMessage()">Click me</button>

    </div>复制代码

    (2)ViewModel 层

    var app = new Vue({

        el: '#app',

        data: {  // 用于描述视图状态   

            message: 'Hello Vue!',

        },

        methods: {  // 用于描述视图行为  

            showMessage(){

                let vm = this;

                alert(vm.message);

            }

        },

        created(){

            let vm = this;

            // Ajax 获取 Model 层的数据

            ajax({

                url: '/your/server/data/api',

                success(res){

                    vm.message = res;

                }

            });

        }

    })复制代码

    (3) Model 层

    {

        "url": "/your/server/data/api",

        "res": {

            "success": true,

            "name": "IoveC",

            "domain": "www.cnblogs.com"

        }

    }

     

    2.Vuex响应式数据/双向绑定原理

    Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据。其中,View变化更新Data,可以通过事件监听的方式来实现,所以 Vue数据双向绑定的工作主要是如何根据Data变化更新View

    简述

    当你把一个普通的 JavaScript 对象传入 Vue 实例作为 data 选项,Vue 将遍历此对象所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setter。

    这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。

    每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

     

    深入理解:

    监听器 Observer:对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。

    解析器 Compile:解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。

    订阅者 Watcher:Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。每个组件实例都有相应的 watcher 实例对象,它会在组件渲染的过程中把属性记录为依赖,之后当依赖项的 setter 被调用时,会通知 watcher 重新计算,从而致使它关联的组件得以更新——这是一个典型的观察者模式

    订阅器 Dep:订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。

    Vue 双向数据绑定原理

    数据的双向绑定是通过数据劫持结合发布订阅实现的。利用Object.defineproperty()方法将各个属性的getter和setter方法改写。当数据发生改变的时候,通知订阅者,并触发对应的回调函数,重新渲染数据。主要是实现以下几点:

    (1) 数据观察者Observer,观察每个属性,当发生变化的时候,得到最新值并通知订阅者。

    (2) 指令编译器Compile,对每个元素的节点进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。

    (3) 监听者Watcher,是数据观察者Observer和编译器Compile的桥梁。能订阅每个数据属性变化,当收到变化通知后,执行指令绑定的相应回调,从而更新视图。

    vue会遍历data中的所有属性,利用Object.definedProperty这个方法给data中每一个属性增加监听者,即给每一个属性增加get方法和set方法,当数据发生变化时,会触发set方法,当获取数据时,会触发get方法;

     

    数据劫持

    Object.defineProperty()

    控制一个对象属性的一些特有操作,比如读写权、是否可以枚举

    通过get和set方法对data里的每个属性进行劫持

     

    发布者-订阅者模式

    监听器Observer 用来劫持并监听所有属性,如果有变动的,就通知订阅者。

    订阅者Watcher 可以收到属性的变化通知并执行相应的函数,从而更新视图

    解析器Compile 可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器

    订阅器Dep 订阅者(watcher)是有很多个,所以我们需要有一个消息订阅器Dep来专门收集这些订阅者

    每一个对象属性中存储了一个 Dep,Dep 中收集了该对象对应的 watcher,当该属性值发生变化,会触发的 Dep 中保存的 watcher 进行遍历(notify),进而更新视图。

     

    3.你知道Vue3.x响应式数据原理吗?

    • Vue3.x改用Proxy替代Object.defineProperty
    • 因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。
    • Proxy只会代理对象的第一层,Vue3是怎样处理这个问题的呢?
      • 判断当前Reflect.get的返回值是否为Object,如果是则再通过reactive方法做代理, 这样就实现了深度观测。
      • 监测数组的时候可能触发多次get/set,那么如何防止触发多次呢?我们可以判断key是否为当前被代理对象target自身属性,也可以判断旧值与新值是否相等,只有满足以上两个条件之一时,才有可能执行trigger。

    Proxy 与 Object.defineProperty 优劣对比

    Proxy 的优势如下:

    Proxy 可以直接监听对象而非属性;

    Proxy 可以直接监听数组的变化;

    Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;

    Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;

    Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;

    Object.defineProperty 的优势如下:

    兼容性好,支持 IE9,而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。

    4.Vuex 是什么?

    运用到了js设计模式中的单例模式,单例模式想要做到的是,不管我们尝试去创建多少次,它都只给你返回第一次所创建的那唯一的一个实例。

    • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。每一个 Vuex 应用的核心就是 store(仓库)。“store” 基本上就是一个容器,它包含着你的应用中大部分的状态 ( state )。
      • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
      • 改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化。

    Vuex 使用单一状态树,用一个对象就包含了全部的应用层级状态。至此它便作为一个“唯一数据源 (SSOT)”而存在。这也意味着,每个应用将仅仅包含一个 store 实例。单一状态树让我们能够直接地定位任一特定的状态片段,在调试的过程中也能轻易地取得整个当前应用状态的快照。 ——Vuex官方文档

    主要包括以下几个模块:

    State:定义了应用状态的数据结构,可以在这里设置默认的初始状态。

    Getter:允许组件从 Store 中获取数据,mapGetters 辅助函数仅仅是将 store 中的 getter 映射到局部计算属性。

    Mutation:是唯一更改 store 中状态的方法,且必须是同步函数。

    Action:用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。

    Module:允许将单一的 Store 拆分为多个 store 且同时保存在单一的状态树中。

    5. 什么情况下使用 Vuex?

    • 如果应用够简单,最好不要使用 Vuex,一个简单的 store 模式即可
    • 需要构建一个中大型单页应用时,使用Vuex能更好地在组件外部管理状态

    6.Vuex和单纯的全局对象有什么区别?

    • Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
    • 不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。

    7.为什么 Vuex 的 mutation 中不能做异步操作?

    • Vuex中所有的状态更新的唯一途径都是mutation,异步操作通过 Action 来提交 mutation实现,这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
    • 每个mutation执行完成后都会对应到一个新的状态变更,这样devtools就可以打个快照存下来,然后就可以实现 time-travel 了。如果mutation支持异步操作,就没有办法知道状态是何时更新的,无法很好的进行状态的追踪,给调试带来困难。

     

    8.computed 和 watch 的区别和运用的场景?

    computed:是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;

    watch没有缓存性,更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;当我们需要深度监听对象中的属性时,可以打开deep:true选项,这样便会对对象中的每一项进行监听

    运用场景

    当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;

    当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用watch选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

    9. Vue2.x组件通信有哪些方式?

    父子组件通信

    • 事件机制(**父->子props,子->父 $on、$emit)
    • 获取父子组件实例 $parent、$children
    • Ref 获取实例的方式调用组件的属性或者方法
    • Provide、inject (不推荐使用,组件库时很常用)

    兄弟组件通信

    eventBus 这种方法通过一个空的 Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,从而实现任何组件间的通信,包括父子、隔代、兄弟组件

    Vue.prototype.$bus = new Vue

    Vuex

    跨级组件通信

    Vuex

    $attrs、$listeners

    Provide、inject

    10.说一下v-if和v-show的区别

    • 当条件不成立时,v-if不会渲染DOM元素,v-show操作的是样式(display),切换当前DOM的显示和隐藏。
    • v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;
    • v-show 则适用于需要非常频繁切换条件的场景。

    11.为什么 v-for 和 v-if 不建议用在一起

    • 当 v-for 和 v-if 处于同一个节点时,v-for 的优先级比 v-if 更高,这意味着 v-if 将分别重复运行于每个 v-for 循环中。如果要遍历的数组很大,而真正要展示的数据很少时,这将造成很大的性能浪费
    • 这种场景建议使用 computed,先对数据进行过滤

    12. 组件中的data为什么是一个函数?

    • 一个组件被复用多次的话,也就会创建多个实例。本质上,这些实例用的都是同一个构造函数。
    • 如果data是对象的话,对象属于引用类型,会影响到所有的实例。所以为了保证组件不同的实例之间data不冲突,data必须是一个函数。

     

    13.子组件为什么不可以修改父组件传递的Prop?/怎么理解vue的单向数据流?

    • Vue提倡单向数据流,即父级props的更新会流向子组件,但是反过来则不行。
    • 这是为了防止意外的改变父组件状态,使得应用的数据流变得难以理解。
    • 如果破坏了单向数据流,当应用复杂时,debug 的成本会非常高。


    14. v-model是如何实现双向绑定的?

    • v-model是用来在表单控件或者组件上创建双向绑定的
    • 他的本质是v-bind和v-on的语法糖
    • 在一个组件上使用v-model,默认会为组件绑定名为value的prop和名为input的事件

    15. nextTick的实现原理是什么?

    • 在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后立即使用 nextTick 来获取更新后的 DOM。
    • nextTick主要使用了宏任务微任务
    • 根据执行环境分别尝试采用Promise、MutationObserver、setImmediate,如果以上都不行则采用setTimeout定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列。

    在下次 DOM 更新循环结束之后执行延迟回调,在修改数据之后立即使用 nextTick 来获取更新后的 DOM。

    nextTick主要使用了宏任务和微任务。根据执行环境分别尝试采用Promise、MutationObserver、setImmediate,如果以上都不行则采用setTimeout定义了一个异步方法,多次调用nextTick会将方法存入队列中,通过这个异步方法清空当前队列。

    理解:(宏任务和微任务) 异步方法

    nextTick 方法主要是使用了宏任务和微任务,定义了一个异步方法.多次调用 nextTick 会将方法存入 队列中,通过这个异步方法清空当前队列。 所以这个 nextTick 方法就是异步方法

     

     

    16.Vue不能检测数组的哪些变动?Vue 怎么用 vm.$set() 解决对象新增属性不能响应的问题 ?

    Vue 不能检测以下数组的变动:

    当你利用索引直接设置一个数组项时,例如:vm.items[indexOfItem] = newValue

    当你修改数组的长度时,例如:vm.items.length = newLength

    解决办法:

    第一类问题

    // 法一:Vue.set

    Vue.set(vm.items, indexOfItem, newValue)

    // 法二:Array.prototype.splice

    vm.items.splice(indexOfItem, 1, newValue)复制代码 修改原数组

    第二类问题,可使用 splice:

    vm.items.splice(newLength)复制代码

    vm.$set 的实现原理是:

    如果目标是数组,直接使用数组的 splice 方法触发相应式;

    如果目标是对象,会先判读属性是否存在、对象是否是响应式,最终如果要对属性进行响应式处理,则是通过调用 defineReactive 方法进行响应式处理( defineReactive 方法就是 Vue 在初始化对象时,给对象属性采用 Object.defineProperty 动态添加 getter 和 setter 的功能所调用的方法)

    17.Vue事件绑定原理是什么?

    原生事件绑定是通过addEventListener绑定给真实元素的,组件事件绑定是通过Vue自定义的$on实现的。

    18.说一下虚拟Dom以及key属性的作用

    • 由于在浏览器中操作DOM是很昂贵的。频繁的操作DOM,会产生一定的性能问题。这就是虚拟Dom的产生原因。
    • Virtual DOM本质就是用一个原生的JS对象去描述一个DOM节点。是对真实DOM的一层抽象。(也就是源码中的VNode类,它定义在src/core/vdom/vnode.js中。)
    • 虚拟 DOM 的实现原理主要包括以下 3 部分:
      • 用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
      • diff 算法 — 比较两棵虚拟 DOM 树的差异;
      • pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。
    • key 是为 Vue 中 vnode 的唯一标记,通过这个 key,我们的 diff 操作可以更准确、更快速
      • 更准确:因为带 key 就不是就地复用了,在 sameNode 函数a.key === b.key对比中可以避免就地复用的情况。所以会更加准确。
      • 更快速:利用 key 的唯一性生成 map 对象来获取对应节点,比遍历方式更快

    19.为什么不建议用index作为key?

    • 不建议 用index 作为 key,和没写基本上没区别,因为不管你数组的顺序怎么颠倒,index 都是 0, 1, 2 这样排列,导致 Vue 会复用错误的旧子节点,做很多额外的工作

    20.怎样理解 Vue 的单向数据流?

    所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。

    额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。

    有两种常见的试图改变一个 prop 的情形 :

    • 这个 prop 用来传递一个初始值;这个子组件接下来希望将其作为一个本地的 prop 数据来使用。 在这种情况下,最好定义一个本地的 data 属性并将这个 prop 用作其初始值:

    props: ['initialCounter'],data: function () {

      return {

        counter: this.initialCounter

      }

    }复制代码

    • 这个 prop 以一种原始的值传入且需要进行转换。 在这种情况下,最好使用这个 prop 的值来定义一个计算属性

    props: ['size'],computed: {

      normalizedSize: function () {

        return this.size.trim().toLowerCase()

      }

    }

    目前Vue面试题 已更新到60题,想获取更多资源:请关注公众号 查看更多资源

    展开全文
  • vue 经典面试题 

    2020-10-26 12:55:46
    vue常见面试题 9.14 上午 1.同源策略 端口(如果有指定)和域名都相同,则两个页面具有相同的源。 2.nodejs 解决跨域问题 cors app.all 3.typeof 查看数据类型 4instanceOf 用于测试构造函数的prototype属性,...
  • Vue经典面试题合集

    2020-08-02 19:29:30
    前端必看Vue面试经典合集
  • Vue经典面试题2020

    千次阅读 2020-05-09 12:18:20
    (一)VUE经典基础(1) 1.mvvm 框架是什么? 2.vue的优点是什么?(为什么大部分公司选择vue) 3.vue的两个核心点是什么? 4. 三大框架的优缺点?(vue、Angular、React) 5.vue和jQuery的区别? 6.渐...
  • 页面不按需加载引入方式:import home from '../../common/home.vue' 页面按需加载引入方式: const home = r => require.ensure( [], () => r (require('../../common/home.vue'))) 五、vuex面试相关 (1)vuex是...
  • 一、vue常见面试题二、生命周期函数面试题三、vue路由面试题四、vuex常见面试题 一、vue常见面试题 1.vue优点? 答:轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb; 简单易学:国人开发,...
  • 渲染组件时,会通过 Vue.extend 方法构建子组件的构造函数,并进行实例化。最终手动调用 $mount() 进行挂载。更新组件时会进行 patchVnode 流程.核心就是diff算法 2、组件中的 data为什么是一个函数? 同一个组件被...
  • vue 常见面试题整理

    2021-04-07 15:11:50
    vue的数据双向绑定将MVVM作为数据绑定的入口,整合Observer,Compile和Watcher三者,通过Observer来监听自己的model的数据变化,通过Compile来解析编译模板指令(vue中是用来解析 {{}}),最终利用watcher搭起...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,240
精华内容 1,296
关键字:

vue经典面试题

vue 订阅
友情链接: nxgea.rar