目录
vue之数据双向绑定原理
-
它的核心是通过 Object.defineProperty(),在数据初始化时,把js对象作为vue实例对象,Object.defineProperty()劫持后,转化为getter/setter属性
- 注意点:Object.defineProperty()已经实现双向绑定,但是效率低!
-
观察者模式:
- 让双向绑定效率提升
- 原理:观察者模式是一对多的一种模式;
- eg:在vue里的“一”就是data之中的某一个数据,“多”指的是当前data某个数据被多次使用到;
因此使用了观察者模式后,一旦监听到当前data数据的变化,同时更新多次使用当前data的这个数据的地方;
-
Object.defineProperty()的参数:
- 第一个是属性所在的对象
- 第二个是你要操作的属性
- 第三个是被操作的属性的特性,这个参数的格式是,{} -> 里面一般为get(读写属性时触发)和set(写入属性时触发)
Object.defineProperty的读写机制
<template>
<div>Home</div>
</template>
<script>
export default {
name: 'Home',
components: {},
data() {
return {}
},
created() {
this.init()
},
methods: {
init() {
let _testObj = {}
Object.defineProperty(_testObj, 'testA', {
get() {
console.log('读取时触发')
return 1
},
set() {
console.log('写入时触发')
}
})
_testObj.testA = '123' // 写入时触发
console.log('_testObj.testA', _testObj.testA) // 读取时触发 _testObj.testA 1
}
}
}
</script>
极简的数据双向绑定实现
- 原生js结合
Object.defineProperty
实现一个简单的数据双向绑定事件
<template>
<div>
Home
<input type="text" id="txt_id" />
<p id="p_id"></p>
</div>
</template>
<script>
export default {
name: 'Home',
components: {},
data() {
return {}
},
mounted() {
this.init()
},
methods: {
init() {
// Vue数据双向绑定原理
let _testObj = {}
Object.defineProperty(_testObj, 'testA', {
get() {
console.log('读取时触发')
return 1
},
set(newV) {
console.log('写入时触发')
// 这种方式直接操作dom节点,若是操作dom节点过多,影响性能,因此需要观察者模式协助!
document.getElementById('txt_id').value = newV
document.getElementById('p_id').innerHTML = newV
}
})
document.getElementById('txt_id').addEventListener('keyup', function (e) {
_testObj.testA = e.target.value
// console.log('e.target', e.target.value)
})
}
}
}
</script>
观察者模式的概念
- 由于直接使用
Object.defineProperty
操作时,性能不佳,需要借组观察者等模式! - 订阅者和发布者模式
- vue的数据双向绑定,是将MVVM这个数据入口整合起来,划分为
Observer观察者
、Compile编译
、Watcher监听者
这三个方面 - 首先先通过
Observer观察者
来监听自身数据的变化 - 若是发生变化,则通过
Compile编译
来解析模板指令(Vue之中使用插值表达式来解析{{}}
) - 最后使用
Watcher监听者
搭建的Observer和Compile的通讯桥梁
,达到数据的变化更新;- view的更新 -> 视图的更新(input) -> 数据的更新
- vue的数据双向绑定,是将MVVM这个数据入口整合起来,划分为
MVVM模式的简述
- 其中MVVM划分为三部分
- M : 数据层 (data数据)
- V :视图层(View)
- VM :中间控制器桥梁(也就是Observer和Compile构建的桥梁)
- v-model的原理
- 双向数据绑定—需要添加v-model指令
- v-model这个指令是由两个指令组成的,分别为v-bind(绑定表单的值),@input(绑定oninput事件)
- 原理:
- v-bind:attr — 就是给属性绑定数据(单项),用于显示数据
- v-on:input=“事件处理函数” —就是给表单添加一个事件,并且处理数据
一个简单的 view -> model
<template>
<div>
Home
<input type="text" v-bind:value="msg" v-on:input="msgChange" />
msg {{ msg }} <br />
</div>
</template>
<script>
export default {
name: 'Home',
components: {},
data() {
return {
msg: '1111'
}
},
methods: {
// 一个简单的 view 改变 影响 model 的案例
msgChange(e) {
console.log('magChange', e.target.value)
this.msg = e.target.value
}
}
}
</script>
model -> view
<template>
<div>
Home
<input type="text" v-bind:value="msg" v-on:input="msgChange" />
msg {{ msg }} <br />
<el-button @click="btn">按钮</el-button>
</div>
</template>
<script>
export default {
name: 'Home',
components: {},
data() {
return {
msg: '1111'
}
},
created() {
this.init()
},
methods: {
init() {},
// 一个简单的 view 改变 影响 model 的案例
msgChange(e) {
console.log('magChange', e.target.value)
this.msg = e.target.value
},
// 点击按钮 直接修改data数据,然后model -> view
btn() {
this.msg = 'btn_msg消息'
}
}
}
</script>