# Vue中的数据绑定

Vue3.0 中将会通过 Proxy 来替换原本的 Object.defineProperty 来实现数据响应式

# vue2.x版本

使用Object.defineProperty 来实现数据响应式

# 简单使用

    <h1 id="test1">0</h1>
    <button id="add">add</button>
1
2
let obj = {
    value: 0
}
let v = obj.value;
let test1 = document.getElementById('test1')
Object.defineProperty(obj, 'value', {
    get: function () {
        return v
    },
    set: function (value) {
        v = value
        test1.textContent = value
    }
})
document.querySelector('#add').addEventListener('click', function () {
    obj.value++;
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 封装一个通用一点的watch函数

function watch(obj, key, callback) {
    let v = obj[key]
    Object.defineProperty(obj, key, {
        get: function () {
            return v
        },
        set: function (newValue) {
            v = newValue
            callback(v)
        }
    })
}
1
2
3
4
5
6
7
8
9
10
11
12
    <h1 id="test1">0</h1>
    <h1 id="test2">0</h1>
    <button id="add">add</button>
1
2
3
let obj = {
    value1: 0,
    value2: 2
}
let test1 = document.getElementById('test1')
let test2 = document.getElementById('test2')
watch(obj, 'value1', (res) => {
    test1.textContent = res
})
watch(obj, 'value2', (res) => {
    test2.textContent = res
})
document.querySelector('#add').addEventListener('click', function () {
    obj.value1++;
    obj.value2 *= 2;
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# vue3.x

使用defineProperty只能定义属性的getset等行为

es6提供了proxy(代理),可以自定义更多的行为(13种),可以参考es6相关电子书籍

# 简单使用

 <h1 id="title1">0</h1>
<button id="add">add</button>
1
2
let obj = {
    num: 0
}
let p = new Proxy(obj, {
    set(target, property, value) {
        target[property] = value;
        if (property === 'num') {
            document.getElementById('title1').textContent = value
        }
    }
})

document.getElementById('add').addEventListener('click', function () {
    p.num++;
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 封装成通用的watch

function watch(obj, callback) {
    return new Proxy(obj, {
        set(target, key, value) {
            target[key] = value
            callback(key, value)
        },
        get(target, key) {
            return target[key]
        }
    })
}
1
2
3
4
5
6
7
8
9
10
11
<h1 id="title1">0</h1>
<button id="add">add</button>
1
2
let obj = {
    num: 0
}
let p = watch(obj, (key, value) => {
    if (key === 'num') {
        document.getElementById('title1').textContent = value
    }
})
document.getElementById('add').addEventListener('click', function () {
    p.num++;
})
1
2
3
4
5
6
7
8
9
10
11