Vue响应式主要包含:
Object.defineProperty实现数据劫持Proxy实现数据劫持{
{}}v-bind, v-on, v-model, v-for,v-ifvdom,把vdom渲染为普通dom
数据变化时能自动更新视图,就是数据响应式
Vue2使用Object.defineProperty实现数据变化的检测
new Vue()⾸先执⾏初始化,对data执⾏响应化处理,这个过程发⽣在Observer中data中获取并初始化视图,这个过程发⽣在 Compile中Watcher实例,将来对应数据变化时,Watcher会调⽤更新函数data的某个key在⼀个视图中可能出现多次,所以每个key都需要⼀个管家Dep来管理多个 Watcherdata中数据⼀旦发⽣变化,会⾸先找到对应的Dep,通知所有Watcher执⾏更新函数
CVue:自定义Vue类 Observer:执⾏数据响应化(分辨数据是对象还是数组) Compile:编译模板,初始化视图,收集依赖(更新函数、 watcher创建) Watcher:执⾏更新函数(更新dom) Dep:管理多个Watcher实例,批量更新
参考 前端手写面试题详细解答
observe: 遍历vm.data的所有属性,对其所有属性做响应式,会做简易判断,创建Observer实例进行真正响应式处理
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>cvuetitle>
<script src="./cvue.js">script>
head>
<body>
<div id="app">
<p>{
{ count }}p>
div>
<script>
const app = new CVue({
el: '#app', data: {
count: 0
} }) setInterval(() => {
app.count +=1
}, 1000); script>
body>
html>
data执⾏响应化处理// 自定义Vue类
class CVue {
constructor(options) {
this.$options = options
this.$data = options.data
// 响应化处理
observe(this.$data)
}
}
// 数据响应式, 修改对象的getter,setter
function defineReactive(obj, key, val) {
// 递归处理,处理val是嵌套对象情况
observe(val)
Object.defineProperty(obj, key, {
get() {
return val
},
set(newVal) {
if(val !== newVal) {
console.log(`set ${
key}:${
newVal}, old is ${
val}`)
val = newVal
// 继续进行响应式处理,处理newVal是对象情况
observe(val)
}
}
})
}
// 遍历obj,对其所有属性做响应式
function observe(obj) {
// 只处理对象类型的
if(typeof obj !== 'object' || obj == null) {
return
}
// 实例化Observe实例
new Observe(obj)
}
// 根据传入value的类型做相应的响应式处理
class Observe {
constructor(obj) {
if(Array.isArray(obj