# Vue的理解
# 一、是什么
Vue.js(/vjuː/,或简称为Vue)是一个用于创建用户界面的渐进式JavaScript框架,也是一个创建单页应用的Web应用框架。
PS: Vue作者尤雨溪是在为AngularJS工作之后开发出了这一框架。他声称自己的思路是提取Angular中为自己所喜欢的部分,构建出一款相当轻量的框架最早发布于2014年2月。
# 简单说下vue
- vue是渐变式框架,根据自己的需求添加功能
- vue数据驱动采用mvvm模式,m是数据层,v是视图层,vm是调度者
- SPA单页面应用,只有一个页面,加载速度快
- 组件化,复用性强
# 有什么缺点
- vue2底层基于Object.defineProperty实现响应式,这个api本身不支持IE8及以下浏览器
- 客户端渲染(CSR)的先天不足,首屏性能问题(白屏)
- 由于百度等搜索引擎爬虫无法爬取js中的内容,故spa先天就对seo优化心有余力不足(谷歌的puppeteer就挺牛逼的,实现预渲染底层也是用到了这个工具)
# 二、响应式原理
vue.js
是采用 数据劫持 + 发布者-订阅者模式 的方式,通过 Object.defineProperty()
来劫持各个属性的 setter
、getter
,在数据变动时发布消息给订阅者,触发响应的监听回调。在vue3.0中通过Proxy代理对象进行类似的操作。
Vue 数据双向绑定主要是指:数据变化更新视图,视图变化更新数据,如下图所示:
其中,View 变化更新 Data ,可以通过事件监听的方式来实现,所以 Vue 的数据双向绑定的工作主要是如何根据 Data 变化更新 View。
Vue 主要通过以下 4 个步骤来实现数据双向绑定的:
# 实现一个监听器 Observer
对数据对象进行遍历,包括子属性对象的属性,利用 Object.defineProperty() 对属性都加上 setter 和 getter。这样的话,给这个对象的某个值赋值,就会触发 setter,那么就能监听到了数据变化。
# 实现一个解析器 Compile
解析 Vue 模板指令,将模板中的变量都替换成数据,然后初始化渲染页面视图,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,调用更新函数进行数据更新。
# 实现一个订阅者 Watcher
Watcher 订阅者是 Observer 和 Compile 之间通信的桥梁 ,主要的任务是订阅 Observer 中的属性值变化的消息,当收到属性值变化的消息时,触发解析器 Compile 中对应的更新函数。
# 实现一个订阅器 Dep
订阅器采用 发布-订阅 设计模式,用来收集订阅者 Watcher,对监听器 Observer 和 订阅者 Watcher 进行统一管理。
# 三、核心特性
# 数据驱动(MVVM)
参考:MVVM 双向数据绑定
# 组件化
# 1. 什么是组件化
一句话来说就是把图形、非图形的各种逻辑均抽象为一个统一的概念(组件)来实现开发的模式,在Vue
中每一个.vue
文件都可以视为一个组件
# 2. 组件化的优势
- 降低整个系统的耦合度,在保持接口不变的情况下,我们可以替换不同的组件快速完成需求,例如输入框,可以替换为日历、时间、范围等组件作具体的实现
- 调试方便,由于整个系统是通过组件组合起来的,在出现问题的时候,可以用排除法直接移除组件,或者根据报错的组件快速定位问题,之所以能够快速定位,是因为每个组件之间低耦合,职责单一,所以逻辑会比分析整个系统要简单
- 提高可维护性,由于每个组件的职责单一,并且组件在系统中是被复用的,所以对代码进行优化可获得系统的整体升级
# 指令系统
指令 (Directives) 是带有 v- 前缀的特殊属性作用:当表达式的值改变时,将其产生的连带影响,响应式地作用于 DOM
常用的指令
- 条件渲染指令
v-if
- 列表渲染指令
v-for
- 属性绑定指令
v-bind
- 事件绑定指令
v-on
- 双向数据绑定指令
v-model
- 条件渲染指令
没有指令之前我们是怎么做的?是不是先要获取到DOM然后在....干点啥
# 四、Proxy 与 Object.defineProperty 的区别
面试官: 实现双向绑定Proxy比defineproperty优劣如何? (opens new window)
Proxy 的优势如下:
- Proxy 可以直接监听对象而非属性;
- Proxy 可以直接监听数组的变化;
- Proxy 有多达 13 种拦截方法,不限于 apply、ownKeys、deleteProperty、has 等等是 Object.defineProperty 不具备的;
- Proxy 返回的是一个新对象,我们可以只操作新的对象达到目的,而 Object.defineProperty 只能遍历对象属性直接修改;
- Proxy 作为新标准将受到浏览器厂商重点持续的性能优化,也就是传说中的新标准的性能红利;
Object.defineProperty :
- 无法监听数组变化
- 只能劫持对象的属性
- 兼容性好,支持IE9。而 Proxy 的存在浏览器兼容性问题,而且无法用 polyfill 磨平,因此 Vue 的作者才声明需要等到下个大版本( 3.0 )才能用 Proxy 重写。
# 五、Vue 和 React 区别
石川-智能社:
Vue 和React 没有本质区别:
- Vue 更注重视图的自动同步,使用习惯偏向前端人员
- React 更注重组件及其状态的管理,使用习惯偏向程序人员,如后台转前端人员
相对于Vue,React更加透明,没有过多的隐含逻辑(比如Vue的指令就是一种隐含逻辑),更便于程序员理解程序的执行过程;当然,也更加复杂、强大。
这里就做几个简单的类比吧,当然没有好坏之分,只是使用场景不同
# 相同点
- 都有组件化思想
- 都支持服务器端渲染
- 都有Virtual DOM(虚拟dom)
- 数据驱动视图
- 都有支持native的方案:
Vue
的weex
、React
的React native
- 都有自己的构建工具:
Vue
的vue-cli
、React
的Create React App
# 区别
- 数据流向的不同。
react
从诞生开始就推崇单向数据流,而Vue
是双向数据流 - 数据变化的实现原理不同。
react
使用的是不可变数据,而Vue
使用的是可变的数据 - 组件化通信的不同。
react
中我们通过使用回调函数来进行通信的,而Vue
中子组件向父组件传递消息有两种方式:事件和回调函数 - diff算法不同。
react
主要使用diff队列保存需要更新哪些DOM,得到patch树,再统一操作批量更新DOM。Vue
使用双向指针,边对比,边更新DOM
# 如何选择?⭐
都行。
你觉得从用户角度,能感觉到这两个的性能差异吗?不会