前言
学Vue的应该都知道Vue最大的特点的数据驱动视图,那么你是否了解Vue数据变化是如何侦测到的呢?能否手写实现响应式原理呢?这一块是面试中经常会问到的地方,也是我们学号vue必须要了解的一个点,这篇就通过小例子带大家理解这个内容
数据驱动视图
刚刚说了Vue最大的特点的数据驱动视图。
这里我们可以把数据理解为状态,视图就是用户可以直接看到的页面。
UI = render(state)
这个公式理解为:state是输入,UI是输出,状态变化也变随之变化,这种特性就要数据驱动视图。
如果说想要知道数据在什么时候被读取或者被改写,很简单,JS为我们提供了一个Object.difineProperty方法。具体如何实现和使用,继续往下看
Object.difineProperty
我先来写个简单的对象
<script>
let home = {
'brand': 'BGY',
'price': 5000
}
</script>
运行打开,我们可以在控制台输入,取到hone对象和它的属性值都没有问题
那么我们在读取或者是修改时,如何让hone对象告诉我们发生了操作呢?这里就需要用到了Object.difineProperty,我们来修改一下代码:
get就是拿数据,set就是修改数据
<script>
// let home = {
// 'brand': 'BGY',
// 'price': 5000
// }
let home = {}
let val = 5000
Object.defineProperty(home, 'price', {
get() {
console.log('price属性被读取了')
return val
},
set(newVal) {
console.log('peice属性被修改了')
return newVal
}
})
</script>
我们再来运行试一下,此时hone已经变为可观测的了
手写实现Vue响应式
上面我们已经了解了Object.difineProperty方法的使用,能够将变量变为可观测,下面一起来手写一个Vue响应式
- 我们先来写一个输入框,并且将输入框内容展示到下方p标签里。先把对象里的内容变为可观测形式
<input type="text" id="inp">
<p id="text"></p>
<script>
let obj = {}
Object.defineProperty(obj, 'val', {
get() {
console.log('val属性被读取了')
return val
},
set(newVal) {
console.log('val属性被修改了')
return newVal
}
})
</script>
- 下面我们要把set中最新的值newVal赋值进行,然后监听input的键盘事件,把对应的目标值赋给对象的val.
这里使用addEventListener的方法,读取到它的target属性,并将它赋值给obj.val,并在set方法中对新的值赋值进去
<input type="text" id="inp">
<p id="text"></p>
<script>
let obj = {}
Object.defineProperty(obj, 'val', {
get() {
console.log('val属性被读取了')
return val
},
set(newVal) {
console.log('val属性被修改了')
val = newVal
document.getElementById('text').innerHTML = newVal
}
})
document.addEventListener('keyup', function(e) {
console.log(e.target.value)
obj.val = e.target.value
})
</script>
下面一起来看看效果,实现了响应式的简易版