Vue正式篇(四)理解Vue设计思想(一)

理解Vue的设计思想
MVVM模式
MVVM框架的三要素:数据响应式、模板引擎及其渲染

数据响应式: 监听数据变化并在视图中更新

  • Object.defineProperty()
  • Proxy

模板引擎: 提供描述视图的模板语法

  • 插值:{{}}
  • 指令:v-bind, v-on, v-model, v-for, v-if

渲染: 如何将模板转换为html

  • 模板=> vdom => dom

数据响应式原理
数据变更能够响应在视图中,就是数据响应式。vue2中利用Object.defineProperty()实现变更检测。

简单实现:

const obj = {}

function defineReactive(obj, key, val) {
	Object.defineProperty(obj, key, {
		get() {
			console.log(`get ${key}:${val}`)
			return val
		},
		set(newVal) {
			if(newVal !== val) {
				console.log(`set ${key}:${newVal}`)
				val = newVal
			}
		}
	})
}

defineReactive(obj, 'foo', 'foo')
obj.foo
obj.foo = 'fooooooooooooo'

结合视图查看效果:

<div id="app"></div>
<script>
    const obj = {}
    function defineReactive(obj, key, val) {
        Object.defineProperty(obj, key, {
            get() {
                console.log(`get ${key}:${val}`)
                return val
            },
            set(newVal) {
                if(newVal !== val) {
                    val = newVal
                    update()
                }
            }
        })
    }
    
    defineReactive(obj, 'foo', '')
    obj.foo = new Date().toLocaleTimeString()

    function update() {
        app.innerText = obj.foo
    }

    setInterval(() => {
        obj.foo = new Date().toLocaleTimeString()
    }, 1000)
</script>

遍历需要响应化的对象

// 对象响应化,遍历每个key,定义getter、setter
function observe(obj) {
	if(typeof obj !== 'object' || obj === null) {
		return
	}
	Object.keys(obj).forEach(key => {
		defineReactive(obj, key, obj[key])
	})
}
const obj = {foo: 'foo', bar: 'bar', baz: {a: 1}}

observe(obj)
obj.foo
obj.foo = 'fooooooo'
obj.bar
obj.bar = 'hhhhhhhhh'
obj.baz.a = 10	// 嵌套对象no ok

解决嵌套对象问题

function defineReactive(obj, key, val) {
    observe(val)
    Object.defineProperty(obj, key, {
        //...
    })
}

解决赋的值是对象的情况

obj.baz = {a:1}
obj.baz.a = 10    // no ok
set(newVal) {
    if(newVal !== val) {
        observe(newVal)    // 新值是对象的情况
        notifyUpdate()
    }
}

此时,如果添加/删除了新属性依旧无法检测

obj.dong = 'dong'
obj.dong	// 并没有get信息

function set(obj, key, val) {
	defineReactive(obj, key, val)
}

测试:

set(obj, 'dong', 'dong')
obj.dong
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值