项目开发思想
- MVC
- MVVM
双向绑定的原理
基本概念:
-
当视图上的数据发生改变时, data 中的数据也发生改变
-
当 data 中的数据发生改变时,视图中的数据也发生改变
原理: -
主流使用的版本 2.x:
- 关键字:
Object.defineProperty
- 关键字:
<script>
// 关键点: Object.defineProperty
// 作用: 可以给一个对象中的一个属性在赋值&取值 的时候触发的方法
// var data = {}
// // 给对象添加一个属性
// data.name = "你好鸭"
// // 从对象中取出属性
// console.log(data.name)
// 需求:将来给 data 中 name 属性时,要触发一个方法
// 将来从 data 中取出 name 属性时,也要触发一个方法
var obj = {}
// 给obj对象中的name属性添加自定义事件
Object.defineProperty(obj, 'name', {
// 给obj中的name属性赋值时会触发set方法
set: function() {
console.log('set')
},
// 给obj中取出来name属性时,会触发的方法
get: function() {
console.log('get')
}
})
</script>
- 2.0双向数据绑定
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 视图层 -->
<div>
<div id="box"></div>
<input type="text" id="ipt">
</div>
<script>
// 双向绑定:当数据发生改变时,视图也会跟着改变
// 当视图发生改变时,数据也会发生改变
// 数据层
var data = {}
// 给data中的name属性添加自定义事件
Object.defineProperty(data, 'name', {
set: function (value) {
//console.log(value) //这里的value就是给data中name属性赋的值
// 将修改的值赋给id名为box的div
document.querySelector('#box').innerHTML = value
// 将外界给name赋的值保存起来
// console.log(this)//这里的this指的是data这个空对象
this._name = value
},
get: function () {
return this._name
}
})
// 监听输入框的数据的变化
document.querySelector('#ipt').oninput = function(e){
// 当视图发生改变时,数据层也跟着改变
data.name = e.target.value
}
</script>
</body>
</html>
-
最新的版本 3.x
- 关键字:
Proxy
<script> // proxy: 可以将一个对象的属性操作委托一个proxy对象 // 需求: 将来给data中name属性赋值时,会触发一个方法set // 将来从data中取出name属性时,也会触发一个方法get var data = {} // 将data中的属性操作委托给一个proxy对象 var p = new Proxy(data, { set: function(data, prop, value) { console.log('set') // console.log(data) // 做委托的对象data //console.log(prop) // 做委托对象data所操作的属性 //console.log(value) // 给属性中赋的值:你好鸭 // 将数据保存到做委托对象data属性中 data[prop] = value }, // 只要从data中得到属性,就会触发get方法 get: function(data, prop){ console.log('get') // data:做委托的对象 prop:操作的属性 // 将属性取出 return data[prop] } }) </script>
- 3.0双向数据绑定
- 关键字:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<div>
<div class="box"></div>
<input type="text">
</div>
</head>
<body>
<script>
// 双向数据绑定
// 当数据发生改变时,视图也会跟着改变
// 当视图发生改变时,数据也会跟着改变
var data = {}
// 设置一个代理
var p = new Proxy(data, {
set: function(data, prop, value){
data[prop] = value
// 模型影响视图层
document.querySelector('.box').innerHTML = value
} ,
get: function(data, prop){
return data[prop]
}
})
// 视图影响模型
document.querySelector('[type=text]').oninput = function(e){
p.name = e.target.value
}
</script>
</body>
</html>
-
注意点:
- 我们这里讲的实现原理是实现的方法,其实在 vue 底层实现这玩意儿的时候用到一种模式:观察者模式。