综合开发

面试专题总结:Vue 知识总结

微信扫一扫,分享到朋友圈

面试专题总结:Vue 知识总结

希望读者依此构建自己的知识树(思维导图)

偷懒一下:可参考我自己总结思维导图 : 点这里

附带:高频面试题积累文档。 来自于(学长、牛客网等平台)

自己开发的博客地址: zxinc520.com

github地址: 点击

此篇 js – 【vue 知识总结】 知识点: 全部弄懂了,面试很容易。

我的博客【MVVM 和 vue】参考地址: 地址

我的博客【虚拟 DOM】参考地址: 地址

一、虚拟 dom

1、虚拟 dom是什么

  • virtual dom,虚拟 DOM
  • 用 JS 模拟 DOM 结构
  • DOM 变化的对比,放在 JS 层来做 ( 图灵完备语言 )
  • 优点:提高重绘性能

2、虚拟 dom存在的意义

  • DOM 操作非常 “昂贵”
  • 将 DOM 对比操作放在 JS 层,提高效率
  • 项目越复杂 ,影响就越严重

3、vdom 的如何应用,核心 API 是什么?

  • 介绍 snabbdom
    • snabbdom :一个 vdom 实现库。
  • 核心 API
    • h 函数
    • h 函数是生成虚拟 DOM 的函数
    • h('<标签名>’,{ … 属性 … },[… 子元素 …])
    • h('<标签名>’,{ … 属性 … },[ ‘….’])
    • patch 函数
      • 使用 diff 算法来比较旧 VNode 及新的 VNode 之间的差异然后执行 Patch Operation 或者叫 Patch 函数来高效更新 Dom 节点。
      • patch(container,vnode)
      • patch(vnode,newVnode)

4、介绍 一下 diff 算法

  • 简介

    • diff 算法 一直在我们身边,并不是 Vue 和 React 创造出来的概念
  • vdom 为何用diff 算法

    • DOM 操作是 “昂贵”的,因此尽量减少DOM 操作
    • 找出本次 DOM 必须更新的节点来更新,其它的 不更新
    • 这个 “ 找出 ” 的过程,就需要 diff 算法
  • diff 实现过程

    • patch (container,vnode)

      • 核心 逻辑createElment

        function createElement(vnode) {
        let tag = vnode.tag
        let attrs = vnode.attr || {}
        let children = vnode.children || []
        let elem = document.createElement(tag)
        for (let attrName in attrs) {
        if (attr.hasOwnProperty(attrName)) {
        elem.setAttribute(attrName, attrs[attrName])
        }
        }
        children.forEach((childVnode) => {
        elem.append(createElement(childVnode))
        })
        return elem
        }
        复制代码
    • patch (vnode,newVnode)

      • 核心 逻辑updataChildren

        function updateChildren(vnode, newVnode) {
        let children = vnode.children || []
        let newChildren = newVnode.children || []
        children.forEach((child, index) => {
        let newChild = newChildren[index]
        if (newChild == null) {
        return
        }
        if (child.tag === newChild.tag) {
        updateChildren(child, newChild)
        } else {
        replaceNode(child, newChild)
        }
        })
        }
        复制代码
  • 介绍一下 diff 算法?

    • 知道什么是 diff 算法,是linux 的基础命令
    • vdom 中 应用 diff算法目的: 是为了 找出需要更新的节点
    • diff 实现:patch (container,vnode)和 patch (vnode,newVnode)
    • 核心 逻辑 , createElment 和 updataChildren

二、Vue 知识总结

5、框架和库的区别

  • ibrary(库)
    • 小而巧的库,只提供特定的API;优点就是 船小好调头。可以很方便的从一个库切换到另外的库;但是代码几乎不会改变。
  • Framework(框架)
    • 大而全的是框架;框架提供了一整套的解决方案;所以,如果在项目中间,想切换到另外的框架,是比较困难的。
  • 说一下 使用 jQuery 和 使用框架的区别
    1. 数据 和 视图 的分离,解耦( 开放封闭原则 )
    2. VUE 以数据驱动视图,只关心数据变化,DOM 操作被封装

6、Vue与Angular以及React的区别

  • vue与angular
    • AngularJS的学习成本高,比如增加了Dependency Injection特性,而Vue.js本身提供的API都比较简单、直观;在性能上,AngularJS依赖对数据做脏检查,所以Watcher越多越慢;Vue.js使用基于依赖追踪的观察并且使用异步队列更新,所有的数据都是独立触发的。
  • vue 与React
    • React采用的Virtual DOM会对渲染出来的结果做脏检查;Vue.js在模板中提供了指令,过滤器等,可以非常方便,快捷地操作Virtual DOM。

7、Vue概述

  • Vue是什么
    • 是一个渐进式的构建用户界面的js框架
  • where
    • 小到的简单的表单处理,大到复杂的数据操作比较频繁的单页面应用程序
  • 为什么用VUE
    • 数据驱动
    • 组件化
  • 工作方式
    • 可以通过丰富的指令扩展模板,可以通过各种各样的插件来增强功能

8、MVVM框架模式

  • 概念
    • MVVM是Model-View-ViewModel的简写。是一个软件架构设计模式,是一种简化用户界面的事件驱动编程方式。
  • 每个字母解析
    • Model 代表数据模型
    • View 代表视图,它负责将数据模型转化成UI 展现出来
    • 连接 Model 和 View,简单理解就是一个同步View 和 Model的对象,连接Model和View

9、Vue 三要素 *

9.1、响应式:vue 如何监听到 data 的每个属性变化?

响应式中observe还有dep 还有wather 各自都分担什么任务

【observe类】【dep对象】【wather 执行者】— 弄清楚

  • Vue 响应式是什么

    • data 属性被代理到 vm 上
  • Object.defineProperty(双向数据绑定)

    • 定义
      • Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
    • 缺点 【为什么Vue3.x 升级使用 Proxy 取代 Object.defineProperty】
      • Object.defineProperty无法监控到数组下标的变化,导致通过数组下标添加元素,不能实时响应;
      • Object.defineProperty只能劫持对象的属性,从而需要对每个对象,每个属性进行遍历,如果,属性值是对象,还需要深度遍历。Proxy可以劫持整个对象,并返回一个新的对象。
      • Proxy不仅可以代理对象,还可以代理数组。还可以代理动态增加的属性。
  • data 属性变化过程

    1. 修改属性,被响应式 的 set 监听到
    2. set 中执行 updataComponent ( 异步 )
    3. updataComponent 重新执行 vm.render()
    4. 生成的 vnode 和 prevVnode,通过 patch 进行比较
    5. 渲染到 html 中
  • 模拟实现 Vue 如何监听data

    let vm={}
    let data={
    name:'zc',
    age:'12'
    }
    for(let key in data){
    if(data.hasOwnProperty(key)){
    Object.defineProperty(vm,key,{
    get:function () {
    return data[key]
    },
    set:function (newValue) {
    data[key] = newValue
    }
    })
    }
    }
    复制代码

9.2、模板引擎:vue 的模板如何被解析,指令如何处理?

  • 模板是什么?
    • 本质:字符串
    • 有逻辑,如 v-if 、v-for 等
    • 与 html 格式很像,但有很大区别
    • 最终还要转换为 html 来显示
  • 模板最终必须转化成 JS 代码,因为
    • 有逻辑(v-if、v-for),必须用 JS 才能实现 ( 图灵完备 )
    • 转换成 html 渲染页面,必须用 JS 才能实现
    • 因此,模板最重要转换成 一个 JS 函数 (render 函数)
  • vue 中如何解析 模板
    • 概述
      • 模板必须转换成 render 函数 (编译的第一步是将模板通过 parse 函数解析成 AST(抽象语法树),第二步优化AST(检测出不需要更改的DOM的纯静态子树),第三步根据优化后的抽象语法树生成包含渲染函数字符串的对象。)
      • 具体
        1. 第一步是将模板通过 parse 函数解析成 AST(抽象语法树)
          • 解析成AST:parse 函数【源码】
          • 在解析模版的过程中,不断触发各种钩子函数,将节点信息通过 start, end 和 chars ,comment方法传递给 Vue.js 的 ast 构建程序,边解析边同时构建模版的 ast。
        2. 第二步优化AST(检测出不需要更改的DOM的纯静态子树)
          • 优化AST:optimize 函数【源码】
        3. 第三步根据优化后的抽象语法树生成包含渲染函数字符串的对象。
          • 生成渲染函数:generate 函数【源码】

9.3、渲染:vue的模板如何被渲染成html?以及渲染过程

  • render 函数 与 vdom

    • updataComponent 中实现了生成 vdom 的 patch

    • 页面首次渲染执行 updataComponent

    • render 函数 – with 的用法

      • 总结

        • 模板中所有信息都包含在了 render 函数中
        • this 即 vm
        • price 即 this.price 即 vm.price ,即 data 中的 price
        • _c 即 this. _c 即 vm. _c
      • 使用

        // 使用 with
        function fn1() {
        with (obj) {
        console.log(name)
        console.log(age)
        getAddress()
        }
        }
        复制代码
    • data 中每次修改属性,执行 updataComponent

10、vue 的整个实现流程?

  • 第一步:解析模板成 render 函数
  • 第二步:响应式开始监听
  • 第三步:首次渲染,显示页面,且绑定依赖
  • 第四步:data 属性变化,触发 rerender

11、Vue 生命周期

  • 生命周期是什么
    • Vue 实例从创建到销毁的过程,就是生命周期。也就是从开始创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
  • 作用
    • 它的生命周期中有多个事件钩子,让我们在控制整个Vue实例的过程时更容易形成好的逻辑。
  • vue生命周期总共有几个阶段?
    • 它可以总共分为8个阶段:创建前/后, 载入前/后,更新前/后,销毁前/销毁后
  • 第一次页面加载会触发哪几个钩子?
    • 第一次页面加载时会触发 beforeCreate, created, beforeMount, mounted 这几个钩子
  • 简单描述每个周期具体适合哪些场景?
    • beforecreate:可以在这加个loading事件,在加载实例时触发
    • created:初始化完成时的事件写在这里,如在这结束loading事件,异步请求也适宜在这里调用
    • mounted:挂载元素,获取到DOM节点
    • updated:如果对数据统一处理,在这里写上相应函数
    • beforeDestroy:可以做一个确认停止事件的确认框 nextTick : 更新数据后立即操作dom
  • 钩子函数
    1. beforeCreate :组件实例刚创建,data和methods 中的数据未被初始化
    2. created:组件实例创建完成,data 和 methods 都已经被初始化好了!但DOM还未生成
    3. beforeMount:模板编译/挂载之前
    4. mounted:模板编译/挂载之后
    5. beforeUpdate:组件更新之前
    6. updated:组件更新之后
    7. beforeDestroy:组件销毁前调用
    8. destroyed:组件销毁后调用

12、Vue 组件间的通信(父亲,兄弟,爷孙 等等)

六种方式

  1. props/$emit

    • 父组件A通过props的方式向子组件B传递,B to A 通过在 B 组件中 $emit, A 组件中 v-on 的方式实现。
    • 适用范围:父子组件中
  2. on

    • 这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

    • 具体实现方式

      var Event=new Vue();
      Event.$emit(事件名,数据);
      Event.$on(事件名,data => {});
      复制代码
    • 适用范围:包括父子、兄弟、跨级

  3. vuex

    • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  4. listeners

    • 多级组件嵌套需要传递数据时,通常使用的方法是通过vuex。但如果仅仅是传递数据,而不做中间处理,使用 vuex 处理,未免有点大材小用。为此Vue2.4 版本提供了另一种方法—- listeners
  5. provide/inject

    • 以允许一个祖先组件向其所有子孙后代注入一个依赖,不论组件层次有多深,并在起上下游关系成立的时间里始终生效。
  6. children与 ref

    • 弊端:两种方法的弊端是,无法在跨级或兄弟间通信。

常见使用场景可以分为三类

  • 父子通信
    • 父向子传递数据是通过 props,子向父是通过 events( parent / attrs/$listeners
  • 兄弟通信
    • Bus;Vuex
  • 跨级通信
    • Bus;Vuex;provide / inject API、 listeners

13、Vuex

  • 定义

    • Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
  • Vuex 背后的基本思想

    • 把组件的共享状态抽取出来,以一个全局单例模式管理,在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
  • Vuex 和单纯的全局对象有以下两点不同

    1. Vuex 的状态存储是响应式的。
    2. 你不能直接改变 store 中的状态。该变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。是因为我们想要更明确地追踪到状态的变化。
  • vuex的组成

    1. state

      • Vuex 使用 state来存储应用中需要共享的状态。为了能让 Vue 组件在 state更改后也随着更改,需要基于state创建计算属性。
    2. getters

      • 可以认为是 store 的计算属性,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算
    3. mutations(同步)

      • 是改变状态的执行者,mutations用于同步地更改状态

        store.commit({
        type: 'increment',
        amount: 10   //这是额外的参数
        })
        复制代码
    4. actions(异步)

      • 异步地更改状态,action并不直接改变state,而是发起mutation

        // 以对象形式分发
        store.dispatch({
        type: 'incrementAsync',
        amount: 10
        })
        复制代码
        // 以载荷形式分发
        store.dispatch('incrementAsync', {
        amount: 10
        })
        复制代码
    5. Module: 模块化store

      • 出现的问题
        • 由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
      • 解决方案
        • Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块

vuex的工作流程

  1. 数据从state中渲染到页面
  2. 在页面通过dispatch来触发action
  3. action通过调用commit,来触发mutation
  4. mutation来更改数据,数据变更之后会触发dep对象的notify,通知所有Watcher对象去修改对应视图(vue的双向数据绑定原理)

应用场景

  • 多个视图依赖于同一状态
  • 来自不同视图的行为需要改变同一个状态

14、Vue的路由(vue-router)

Vue的路由的实现原理 【必须得很清楚】

  • vue-router

    • vue-router是什么

      • Vue Router 是 Vue.js 官方的路由管理器
    • 哪些组件

      1. < router-link >

      2. < router-view >

      3. < keep-alive >

        • 定义

          • keepalive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染 。也就是所谓的—–组件缓存
        • 组件缓存

          • 使用 include/exclude

            • include
            • exclude
          • 增加 router.meta 属性

            meta: {
            keepAlive: true // 需要被缓存
            }
            复制代码
        • activated 当 keepalive 包含的组件再次渲染的时候触发

        • deactivated 当 keepalive 包含的组件销毁的时候触发

  • 动态路由

    • 创建:主要是使用path属性过程中,使用动态路径参数,以冒号开头

    • 响应路由参数的变化

      1. this.$route.params

      2. watch (监测变化) $route 对象

        watch: {
        $route(to, from){
        console.log(to.path)
        // 对路由变化做出响应
        }
        }
        复制代码
      3. 使用 2.2 中引入的 beforeRouteUpdate 导航守卫

  • 嵌套路由

    • 需要在 VueRouter 的参数中使用 children 配置
  • 导航

    • 声明式

      <router-link :to="...
      复制代码
    • 编程式

      router.push(...)
      复制代码
  • 重定向和别名

    • 重定向

      routes: [
      { path: '/a', redirect: '/b' }
      ]
      复制代码
    • 别名

      routes: [
      { path: '/a', component: A, alias: '/b' }
      ]
      复制代码
  • vue-router的两种模式

    • hash模式(默认)
      • 原理:原理是onhashchage事件,可以在window对象上监听这个事件
      • 描述:即通过在链接后添加 # + 路由名字,根据匹配这个字段的变化,触发 hashchange 事件,动态的渲染出页面。
    • history模式
      • 描述:利用了HTML5 History Interface 中新增的pushState()和replaceState()方法。
      • 缺点
        1. 需要后台配置支持
        2. 如果刷新时,服务器没有响应响应的资源,会刷出404
  • 导航钩子函数(导航守卫)

    • “导航”表示路由正在发生改变。
    • 作用
      • vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件级的
    • 导航守卫有哪些
      1. 全局前置守卫
        • router.beforeEach
      2. 全局解析守卫(2.5.0 新增)
        • router.beforeResolve
      3. 全局后置钩子
        • afterEach
        • 和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身:
      4. 路由独享的守卫
        • beforeEnter 守卫
      5. 组件内的守卫
        1. beforeRouteEnter :在渲染该组件的对应路由被 confirm 前调用
        2. beforeRouteUpdate:在当前路由改变,但是该组件被复用时调用
        3. beforeRouteLeave:导航离开该组件的对应路由时调用
    • 相关题目
      1. vue-router是什么?有哪些组件?
      2. active-class 是哪个组件的属性?
        • active-class是router-link终端属性,用来做选中样式的切换,当router-link标签被点击时将会应用这个样式
      3. 怎么定义vue-router的动态路由?怎么获取传过来的值?
      4. vue-router有哪几种导航钩子?
      5. router的区别是什么?
        • router为VueRouter的实例,是一个全局路由对象,包含了路由跳转的方法、钩子函数等
        • route 是路由信息对象||跳转的路由对象,每一个路由都会有一个route对象,是一个局部对象,包含path,params,hash,query,fullPath,matched,name等路由信息参数。
        • 传参是this.router,接收参数是this.route
      6. vue-router响应路由参数的变化
      7. vue-router 传参
      8. vue-router的两种模式
      9. vue-router实现路由懒加载(动态加载路由)
        • 把不同路由对应的组件分割成不同的代码块,然后当路由被访问时才加载对应的组件即为路由的懒加载,可以加快项目的加载速度,提高效率

15、Mixin

  • Mixin是什么
    • 一种分发Vue组件中可复用功能的非常灵活的一种方式。
  • 什么时候使用Mixins
    • 页面的风格不用,但是执行的方法和需要的数据类似、

16、vue指令

  • 自定义指令
    • Vue.directive
  • 自定义一个过滤器
    • Vue.filter(‘过滤器的名称’,function(){})

编程式动态AOP实践

上一篇

1.3http的配置详解-1-编译安装,持久连接,MPM,DSO,修改根等

下一篇

你也可能喜欢

评论已经被关闭。

插入图片

热门栏目

面试专题总结:Vue 知识总结

长按储存图像,分享给朋友