Vue理解
文章目录
一、是什么
理解:用于创建用户界面的开源js框架,用于创建单页应用的web框架
二、核心特征
1.数据驱动(MVVM)
数据驱动:数据驱动是指视图由数据驱动生成。我们修改数据,就能自动触发视图的更新。相比于传统的操作DOM,简化了代码量,只关心数据的修改让代码的逻辑更加清晰。DOM变成了数据的映射,所有的逻辑都是对数据的操作。
MVVM和MVC
-
MVC和MVVM都是设计思想,主要是MVC中的Controller演变为MVVM中的viewModel。MVVM主要解决MVC中大量操作DOM使页面渲染性能降低,加载变慢的问题
-
MVVM是将“数据模型数据双向绑定”的思想作为核心,关注Model的变化。让MVVM框架利用自己的机制自动更新DOM(即所说的View视图),也就是所谓的数据-视图分离。
-
MVVM实现了view和model自动同步,当model的属性变化的时候,我们不用手动操作DOM元素来改变view,他会自动变化。
-
MVVM强调数据绑定和视图模型,通过数据绑定实现试图和视图模型之间的自动同步。
-
MVC强调控制器作为视图和模型之间的中介,通过控制器进行通信。
-
注意:
MVVM并不是用ViewModel完全取代了Controller,mvvm只能算是mvc的升级版本,ViewModel存在目的在于抽离Controller中展示的业务逻辑,而不是替代Controller,其它视图操作业务等还是应该放在Controller中实现。
双向数据绑定和数据响应式
-
双向数据绑定:无论用户更新view还是model,另一个都能自动更新。双向绑定中数据和DOM是双向的关系。v-model和.sync
- 原理:
- 构成:数据层、视图层、业务逻辑层(viewModel,将数据和视图关联)
- viewModel职责:数据变化后更新视图,视图更新后变化数据
- viewModel组成:
- 监听器(observer):对所有数据属性进行监听
- 解析器(compiler):对每个元素节点的指令进行扫描解析,根据指令模板替换数据,绑定响应的更新函数
- 原理:
-
单向数据流(响应式):是双向绑定的其中一环,指数据驱动DOM视图的变化,是单向的过程,object.defineProperty
-
原理:
- new Vue() 执行初始化,对data执行响应化处理,这个过程发生在Observer中。data中的某个key对应的元素在视图中可能出现多次,所以每个key都需要一个管家Dep来管理多个watcher,data中数据一旦发生变化,会首先找到对应的Dep,通知所有Watcher执行更新函数
- 同时对模板指向编辑,找到其中动态绑定的数据,从data中获取并初始化视图,这个过程发生在Compiler中
- 定义一个更新函数和watcher,将来对应数据变化时watcher会调用更新函数
- data发生变化,vue内部通过Object.defineProperty监听对象属性变化。vue通过发布订阅模式通知需要发生变化的界面
let sex = "男" let person = { name: "佩奇", age: 23 } Object.defineProperty(person, "sex", { // value: "女", // writable: false, // 是否可重写,默认为false // configurable: false, // 是否可以删除 默认为false // enumerable: false, // 是否可以遍历 默认为false // 当使用set和get时,不可以使用value和writable set(value) { console.log('设置sex属性', value); sex = value }, get() { console.log('获取sex属性', sex); return sex } })
- 实现:
-
// data变化,vue内部监听data变化
let person = {
name: "佩奇",
age: 23
}
Object.keys.forEach(key => {
let value = person[key]
Object.defineProperty(person, key, {
get() {
console.log("获取", key, "值")
return value
},
set(newValue) {
console.log("监听", key, "变化")
value = newValue
}
})
})
// data变化,vue通知相关的视图更新
class Dep {
constructor() {
this.subs = []
}
addSub(sub) {
this.subs.push(sub)
}
notify() {
this.subs.forEach(sub => {
sub.update()
})
}
}
class Watcher {
constructor(value) {
this.value = value
}
update() {
console.log("视图更新")
}
}
const dep = new Dep()
const w1 = new Watcher("w1")
dep.addSub(w1)
const w2 = new Watcher("w2")
dep.addSub(w2)
dep.notify()
2.组件化
理解:把图形,非图形的各种逻辑抽象为一个统一的概念(template、js、css)来实现开发
- 优势
- 降低耦合度,接口不变的情况下,替换不同的组件快速完成需求
- 调试方便,能够快速明确是哪块出现问题
- 每个组件职责单一,并且可复用,有很强的可维护性
3.指令系统
当表达式值变化时,会产生连带影响,响应的作用于DOM
三、相关知识点
1.虚拟DOM
是什么?
- 本质:是一层对真实DOM的抽象,以JS对象作为基础的树,用对象的属性来描述节点,之后通过一系列操作使这棵树映射到真实环境,生成真实DOM。最少包含标签名(tag),属性(attrs)和子元素(children)三个属性。
- 为什么需要?
操作DOM很慢,DOM元素庞大,频繁操作会出现页面卡顿,影响用户体验。在一次操作中,需要更新10个DOM,浏览器会马上执行更新操作,最后操作10次DOM。通过VNode,同样更新10个DOM,虚拟DOM不会立即操作DOM,而是会将10次更新的内容和之前的进行diff比较,得出需要更新的内容,之后将需要更新的内容保存到本地js对象中,最终将这个js对象一次性attach到DOM树上,避免大量无谓计算
优点:
1.通过VNode(虚拟节点),vue等框架可以对这颗抽象树进行创建,删除,修改等操作,然后通过diff算法得出需要修改的最小单位,然后统一更新视图,减少DOM操作次数,提高性能。
2.实现了跨平台的能力,不仅仅局限于生成浏览器的DOM,也可以是安卓,ios的原生组件
缺点:
1.首次渲染大量DOM的时候,由于多了一层虚拟DOM的计算,会比innerHTML插入慢
2. 无法进行极致优化,在一些性能要求高的应用中虚拟DOM无法进行针对性极致优化