• 如何准备好一场vue面试


    SSR的理解

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

    SSR的优势:

    • 更好的SEO
    • 首屏加载速度更快

    SSR的缺点:

    • 开发条件会受到限制,服务器端渲染只支持beforeCreate和created两个钩子;
    • 当需要一些外部扩展库时需要特殊处理,服务端渲染应用程序也需要处于Node.js的运行环境;
    • 更多的服务端负载。

    Vue的优点

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

    computed 的实现原理

    computed 本质是一个惰性求值的观察者。

    computed 内部实现了一个惰性的 watcher,也就是 computed watcher,computed watcher 不会立刻求值,同时持有一个 dep 实例。

    其内部通过 this.dirty 属性标记计算属性是否需要重新求值。

    当 computed 的依赖状态发生改变时,就会通知这个惰性的 watcher,

    computed watcher 通过 this.dep.subs.length 判断有没有订阅者,

    有的话,会重新计算,然后对比新旧值,如果变化了,会重新渲染。 (Vue 想确保不仅仅是计算属性依赖的值发生变化,而是当计算属性最终计算的值发生变化时才会触发渲染 watcher 重新渲染,本质上是一种优化。)

    没有的话,仅仅把 this.dirty = true。 (当计算属性依赖于其他数据时,属性并不会立即重新计算,只有之后其他地方需要读取属性的时候,它才会真正计算,即具备 lazy(懒计算)特性。)

    能说下 vue-router 中常用的 hash 和 history 路由模式实现原理吗?

    (1)hash 模式的实现原理

    早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL 中 # 后面的内容。比如下面这个网站,它的 location.hash 的值为 ‘#search’:

    https://www.word.com#search
    
    • 1

    hash 路由模式的实现主要是基于下面几个特性:

    • URL 中 hash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;

    hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制hash 的切换;

    • 可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URL 的 hash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URL 的 hash 值;
    • 我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)。

    (2)history 模式的实现原理

    HTML5 提供了 History API 来实现 URL 的变化。其中做最主要的 API 有以下两个:history.pushState() 和 history.repalceState()。这两个 API 可以在不进行刷新的情况下,操作浏览器的历史纪录。唯一不同的是,前者是新增一个历史记录,后者是直接替换当前的历史记录,如下所示:

    window.history.pushState(null, null, path);
    window.history.replaceState(null, null, path);
    
    • 1
    • 2

    history 路由模式的实现主要基于存在下面几个特性:

    • pushState 和 repalceState 两个 API 来操作实现 URL 的变化 ;
    • 我们可以使用 popstate 事件来监听 url 的变化,从而对页面进行跳转(渲染);
    • history.pushState() 或 history.replaceState() 不会触发 popstate 事件,这时我们需要手动触发页面跳转(渲染)。

    参考:前端vue面试题详细解答

    对 React 和 Vue 的理解,它们的异同

    相似之处:

    • 都将注意力集中保持在核心库,而将其他功能如路由和全局状态管理交给相关的库;
    • 都有自己的构建工具,能让你得到一个根据最佳实践设置的项目模板;
    • 都使用了Virtual DOM(虚拟DOM)提高重绘性能;
    • 都有props的概念,允许组件间的数据传递;
    • 都鼓励组件化应用,将应用分拆成一个个功能明确的模块,提高复用性。

    不同之处 :

    1)数据流

    Vue默认支持数据双向绑定,而React一直提倡单向数据流

    2)虚拟DOM

    Vue2.x开始引入"Virtual DOM",消除了和React在这方面的差异,但是在具体的细节还是有各自的特点。

    • Vue宣称可以更快地计算出Virtual DOM的差异,这是由于它在渲染过程中,会跟踪每一个组件的依赖关系,不需要重新渲染整个组件树。
    • 对于React而言,每当应用的状态被改变时,全部子组件都会重新渲染。当然,这可以通过 PureComponent/shouldComponentUpdate这个生命周期方法来进行控制,但Vue将此视为默认的优化。

    3)组件化

    React与Vue最大的不同是模板的编写。

    • Vue鼓励写近似常规HTML的模板。写起来很接近标准 HTML元素,只是多了一些属性。
    • React推荐你所有的模板通用JavaScript的语法扩展——JSX书写。

    具体来讲:React中render函数是支持闭包特性的,所以import的组件在render中可以直接调用。但是在Vue中,由于模板中使用的数据都必须挂在 this 上进行一次中转,所以 import 一个组件完了之后,还需要在 components 中再声明下。 4)监听数据变化的实现原理不同

    • Vue 通过 getter/setter 以及一些函数的劫持,能精确知道数据变化,不需要特别的优化就能达到很好的性能
    • React 默认是通过比较引用的方式进行的,如果不优化(PureComponent/shouldComponentUpdate)可能导致大量不必要的vDOM的重新渲染。这是因为 Vue 使用的是可变数据,而React更强调数据的不可变。

    5)高阶组件

    react可以通过高阶组件(HOC)来扩展,而Vue需要通过mixins来扩展。

    高阶组件就是高阶函数,而React的组件本身就是纯粹的函数,所以高阶函数对React来说易如反掌。相反Vue.js使用HTML模板创建视图组件,这时模板无法有效的编译,因此Vue不能采用HOC来实现。

    6)构建工具

    两者都有自己的构建工具:

    • React ==> Create React APP
    • Vue ==> vue-cli

    7)跨平台

    • React ==> React Native
    • Vue ==> Weex

    Vue 的生命周期方法有哪些 一般在哪一步发请求

    beforeCreate 在实例初始化之后,数据观测(data observer) 和 event/watcher 事件配置之前被调用。在当前阶段 data、methods、computed 以及 watch 上的数据和方法都不能被访问

    created 实例已经创建完成之后被调用。在这一步,实例已完成以下的配置:数据观测(data observer),属性和方法的运算, watch/event 事件回调。这里没有 e l , 如果非要想与 D o m 进行交互,可以通过 v m . el,如果非要想与 Dom 进行交互,可以通过 vm. el,如果非要想与Dom进行交互,可以通过vm.nextTick 来访问 Dom

    beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用。

    mounted 在挂载完成后发生,在当前阶段,真实的 Dom 挂载完毕,数据完成双向绑定,可以访问到 Dom 节点

    beforeUpdate 数据更新时调用,发生在虚拟 DOM 重新渲染和打补丁(patch)之前。可以在这个钩子中进一步地更改状态,这不会触发附加的重渲染过程

    updated 发生在更新完成之后,当前阶段组件 Dom 已完成更新。要注意的是避免在此期间更改数据,因为这可能会导致无限循环的更新,该钩子在服务器端渲染期间不被调用。

    beforeDestroy 实例销毁之前调用。在这一步,实例仍然完全可用。我们可以在这时进行善后收尾工作,比如清除计时器。

    destroyed Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁。 该钩子在服务器端渲染期间不被调用。

    activated keep-alive 专属,组件被激活时调用

    deactivated keep-alive 专属,组件被销毁时调用

    异步请求在哪一步发起?

    可以在钩子函数 created、beforeMount、mounted 中进行异步请求,因为在这三个钩子函数中,data 已经创建,可以将服务端端返回的数据进行赋值。

    如果异步请求不需要依赖 Dom 推荐在 created 钩子函数中调用异步请求,因为在 created 钩子函数中调用异步请求有以下优点:

    • 能更快获取到服务端数据,减少页面 loading 时间;
    • ssr 不支持 beforeMount 、mounted 钩子函数,所以放在 created 中有助于一致性;

    Vue路由hash模式和history模式

    1. hash模式

    早期的前端路由的实现就是基于 location.hash 来实现的。其实现原理很简单,location.hash 的值就是 URL# 后面的内容。比如下面这个网站,它的 location.hash 的值为 '#search'

    https://interview2.poetries.top#search
    
    • 1

    hash 路由模式的实现主要是基于下面几个特性

    • URLhash 值只是客户端的一种状态,也就是说当向服务器端发出请求时,hash 部分不会被发送;
    • hash 值的改变,都会在浏览器的访问历史中增加一个记录。因此我们能通过浏览器的回退、前进按钮控制 hash 的切换;
    • 可以通过 a 标签,并设置 href 属性,当用户点击这个标签后,URLhash 值会发生改变;或者使用 JavaScript 来对 loaction.hash 进行赋值,改变 URLhash 值;
    • 我们可以使用 hashchange 事件来监听 hash 值的变化,从而对页面进行跳转(渲染)
    window.addEventListener("hashchange", funcRef, false);
    
    • 1

    每一次改变 hashwindow.location.hash),都会在浏览器的访问历史中增加一个记录利用 hash 的以上特点,就可以来实现前端路由“更新视图但不重新请求页面”的功能了

    特点 :兼容性好但是不美观

    2. history模式

    history采用HTML5的新特性;且提供了两个新方法: pushState()replaceState()可以对浏览器历史记录栈进行修改,以及popState事件的监听到状态变更

    window.history.pushState(null, null, path);
    window.history.replaceState(
    • 1
  • 相关阅读:
    字符串函数----篇章(1)
    Kotlin笔记(二):标准函数,静态方法,延迟初始化,密封类
    tomcat基础介绍
    流量回放-The Big Picture
    Git学习笔记
    [前端]动态加载问题-按条件加载
    使用MVVM Swift UIKit RxSwift 写一个SpaceX 发射计划APP
    面试字节,过关斩将到 3 面,结果找了个架构师来吊打我?
    【前端指南】session和token
    MQ系列14:MQ如何做到消息延时处理
  • 原文地址:https://blog.csdn.net/bb_xiaxia1998/article/details/127729072