记录生活
简单不先于复杂

Vue重点知识总结—理论篇(四)

1. Vue 的 computed (计算属性)的原理

https://zhuanlan.zhihu.com/p/357250216

2. 介绍下vue单页⾯(SPA)和多页⾯区别

  • 单页应⽤ 页⾯跳转—->js渲染,整个项目只有一个Html文件,优点:页⾯切换快 缺点:⾸屏加载稍慢,seo差
  • 多页应⽤ 页⾯跳转—->返回html 优点:⾸屏时间快,seo效果好 缺点:页⾯切换慢

3. Vue 等单页⾯SPA应⽤的优缺点

优点

  1. 单页应⽤的内容的改变不需要重新加载整个页⾯,单页应⽤没有页⾯之间的切换,就不会出现“⽩屏现象”,也不会出现假死并有“闪烁”现象,用户体验及交互比较流畅。
  2. 组件化开发,有利于复用和维护。
  3. 只有一个Html,前端js承担了页面所有切换和渲染,相对服务器压⼒⼩,服务器只⽤出数据就可以,不⽤管展⽰逻辑和页⾯合成,吞吐能⼒会提⾼⼏倍。
  4. 良好的前后端分离。后端不再负责模板渲染、输出页⾯⼯作,后端API通⽤化,即同⼀套后端程序代码,不⽤修改就可以⽤于Web界⾯、⼿机、平板等多种客户端。

缺点

  1. ⾸次加载耗时⽐较多。要加载几乎所有js。不过现在已经可以进行按需加载。
  2. SEO问题,不利于搜索引擎爬取关键字收录。(页面是js渲染的)
  3. 容易造成Css命名冲突。
  4. 前进、后退、地址栏、书签等,都需要程序进⾏管理,页⾯的复杂度很⾼,需要⼀定的技能⽔平和开发成本⾼。

4. defineProperty数据劫持后如何通知数据和视图更新的

vue的双向绑定是由数据劫持结合发布者-订阅者模式实现的,那么什么是数据劫持?vue是如何进⾏数据劫持的?说⽩了就是通过Object.defineProperty()来劫持对象属性的setter和getter操作,在数据变动时做你想要做的事情。

我们已经知道实现数据的双向绑定,⾸先要对数据进⾏劫持监听,所以我们需要设置⼀个监听器Observer,⽤来监听所有属性。如果属性发⽣变化了,就需要告诉订阅者Watcher看是否需要更新。

因为订阅者是有很多个,所以我们需要有⼀个消息订阅器Dep来专门收集这些订阅者,然后在监听器Observer和订阅者Watcher之间进⾏统⼀管理的。

接着,我们还需要有⼀个指令解析器Compile,对每个节点元素进⾏扫描和解析,将相关指令(如v-model,v-on)对应初始化成⼀个订阅者Watcher,并替换模板数据或者绑定相应的函数,此时当订阅者Watcher接收到相应属性的变化,就会执⾏对应的更新函数,从⽽更新视图。因此接下去我们执⾏以下3个步骤,实现数据的双向绑定:

  1. 实现⼀个监听器Observer,⽤来劫持并监听所有属性,如果有变动的,就通知订阅者。
  2. 实现⼀个订阅者Watcher,每⼀个Watcher都绑定⼀个更新函数,watcher可以收到属性的变化通知并执⾏相应的函数,从⽽更新视图。
  3. 实现⼀个解析器Compile,可以扫描和解析每个节点的相关指令(v-model,v-on等指令),如果节点存在v-model,v-on等指令,则解析器Compile初始化这类节点的模板数据,使之可以显⽰在视图上,然后初始化相应的订阅者(Watcher)。

5. Vue proxy的原理

Proxy 可以理解成,在⽬标对象之前架设⼀层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了⼀种机制,可以对外界的访问进⾏过滤和改写。

主要通过Proxy对对象进⾏绑定监听处理,通过new Map对对象的属性操作进⾏处理,将要执⾏的函数匹配到存到对应的prop上⾯,通过每次的访问触发get⽅法,进⾏订阅操作,通过修改触发set⽅法,此时通过回调函数通知订阅者,触发他的update⽅法,对视图进⾏更新,达到修改数据和视图的 。

6. key的作用

  • key是为Vue中的vnode标记的唯⼀id,通过这个key,我们的diff操作可以更准确、更快速
  • diff算法的过程中,先会进⾏新旧节点的⾸尾交叉对⽐,当⽆法匹配的时候会⽤新节点的key与旧节点进⾏⽐对,然后超出差异.、

diff程可以概括为:

oldCh和newCh各有两个头尾的变量StartIdx和EndIdx,它们的2个变量相互⽐较,⼀共有4种⽐较⽅式。如果4种⽐较都没匹配,如果设置了key,就会⽤key进⾏⽐较,在⽐较的过程中,变量会往中间靠,⼀旦StartIdx>EndIdx表明oldCh和newCh⾄少有⼀个已经遍历完了,就会结束⽐较,这四种⽐较⽅式就是⾸、尾、旧尾新头、旧头新尾.

准确: 如果不加key,那么vue会选择复⽤节点(Vue的就地更新策略),导致之前节点的状态被保留下来,会产⽣⼀系列的bug.。

快速: key的唯⼀性可以被Map数据结构充分利⽤,相⽐于遍历查找的时间复杂度O(n),Map的时间复杂度仅仅为O(1)

7. Vue-loader 解释⼀下

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。本质上,webpack loader 将所有类型的文件,转换为应用程序可以直接引用的模块。所以 loader 就是个搞预处理工作的。

Vue-loader 可以解析和转换 .vue ⽂件,提取出其中的逻辑代码 script 、样式代码 style 、以及模版 template ,再分别把它们交给对应的 Loader 去处理。

8. 对⽐ jQuery,Vue 有什么不同

jQuery 专注视图层,通过直接操作DOM 去实现页⾯的⼀些逻辑渲染;Vue 专注于数据层,也就是MVVM模型的ViewModel层,它通过双向数据绑定把view和Model层连接起来,通过对数据的操作完成对页面视图的渲染,减少了DOM 操作。

  1. jquery是使用选择器()选取DOM对象,对其进行赋值、取值、事件绑定等操作,和原生的HTML的区别只在于可以更方便的选取和操作DOM对象,而数据和界面是在一起的。jquery侧重样式操作,动画效果等;可以应用于一些html5的动画页面,一些需要js来操作页面样式的应用。
  2. Vue 则是通过Vue对象将数据和View完全分离开来了。对数据进行操作不再需要引用相应的 DOM 对象,他们通过 Vue 对象这个 vm 实现相互的绑定。这就是传说中的 MVVM。vue侧重数据绑定,可以应用于复杂数据操作的后台页面。

9.Vue内部是怎么把template模板编译成虚拟DOM,从而渲染出真实DOM

1)什么是模板编译?

把写在<template></template>标签中的类似于原生HTML的内容称之为模板。

在<template></template>标签中除了写一些原生HTML的标签,我们还会写一些变量插值,或者写一些Vue指令,这些东西都是在原生HTML语法中不存在的,不被接受的。render函数会将模板内容生成对应的VNode,VNode经过patch过程从而得到将要渲染的视图中的VNode,最后根据VNode创建真实的DOM节点并插入到视图中, 最终完成视图的渲染更新——模板编译过程。

2)整体渲染过程

f2b1ff38d000515

3)模板编译内部流程

借助抽象语法树解析<template></template>标签中写的模板。

4)抽象语法树AST

抽象语法树(AbstractSyntaxTree,AST),或简称语法树(Syntax tree),是源代码语法结构的一种抽象表示。

将一堆字符串模板解析成抽象语法树AST后,我们就可以对其进行各种操作处理了,处理完后用处理后的AST来生成render函数。

  1. 模板解析阶段:将一堆模板字符串用正则等方式解析成抽象语法树AST;
  2. 优化阶段:遍历AST,找出其中的静态节点,并打上标记;
  3. 代码生成阶段:将AST转换成渲染函数;

赞(0)
未经允许不得转载:爱安普 » Vue重点知识总结—理论篇(四)