Vue的双向数据绑定原理?
Vue是根据数据劫持结合发布者-订阅者模式来实现双向数据绑定的,利用object.defaultProperty()方法来获取每个属性 的setter,getter,在数据变动的时候分布消息给订阅者,触发响应的监听回调。
Object.defaultProperty()方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty;
使用Object.defaultProperty实现双向数据绑定:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>v-model的实现原理</title> </head> <body> <input type="text"> <p></p> <script src="./js/vue.js"></script> <script> //获取dom元素 var oP = document.querySelector("p"); var oInput = document.querySelector("input"); //创建一个值 let obj = { _msg: "hello" } //使用方法给obj新添加一个属性,用于设置msg Object.defineProperty(obj, "msg", { get() { return this._msg; }, set(newValue) { this._msg = newValue; oP.innerHTML = newValue; oInput.value = newValue; } }) //给obj的属性赋值 obj.msg = "hello world"; //如果发送了输入事件,就将输入的值赋值给obj oInput.oninput = function(e) { obj.msg = e.target.value; } </script> </body> </html>
利用v-on(绑定方法) 和v-bind(绑定属性)来实现v-model:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>v-model的实现原理</title> </head> <body> <div id="app"> {{msg}} <div> <!-- v-model绑定的原理:使用v-bind绑定属性,使用v-on绑定事件 --> <input type="text" v-bind:value="msg" v-on:input="msg=$event.target.value"> <input type="text" v-bind:value="msg" v-on:input="changeValue"> <input type="text" v-model="msg"> </div> </div> <script src="./js/vue.js"> </script> <script> //创建一个vue实例 var vm = new Vue({ el: "#app", data: { msg: "hello world" }, methods: { changeValue: function(event) { this.msg = event.target.value; } } }) </script> </body> </html>