We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Vue实现数据双向绑定主要利用的就是: 数据劫持和发布订阅模式。
index.html代码
index.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <!-- 数据的双向绑定:逻辑 -> 数据 <-> 视图 vue中体现为v-model --> <div id="app"> <input type="text" v-model="name" placeholder="姓名" /> <input type="text" v-model="age" placeholder="年龄" /> <input type="text" v-model="email" placeholder="邮箱" /> <input type="text" v-model="phone" placeholder="电话" /> <p>姓名:<span>{{ name }}</span></p> <p>年龄:<span>{{ age }}</span></p> <p>邮箱:<span>{{ email }}</span></p> <p> <p> 电话:<span>{{ phone }}</span> </p> </p> </div> <button class="btn">点击</button> </body> <script src="MVVM.js"></script> <script> const app = new MVVM('#app', { name: '', age: '', email: '', phone: '' }) // 通过修改数据来修改对应的dom // { // name: dom // } document.querySelector(".btn").addEventListener("click", function(){ app.setData({ name: "啊哈" }) }) </script> </html>
MVVM.js代码
MVVM.js
function MVVM(el, data){ this.el = document.querySelector(el); this._data = data; this.domPool = {}; this.init(); } MVVM.prototype.init = function(){ this.initData(); // 处理拦截器 this.initDom(); // 处理发布订阅模式 } MVVM.prototype.initData = function(){ const _this = this; this.data = {}; for(let key in this._data){ Object.defineProperty(this.data, key, { get(){ return _this._data[key]; }, set(newVal){ _this._data[key] = newVal; _this.domPool[key].innerText = newVal; } }) } } MVVM.prototype.initDom = function(){ this.bindDom(this.el); this.bindInput(this.el); } MVVM.prototype.bindInput = function(el){ const _allInputs = document.querySelectorAll('input'); _allInputs.forEach(input => { const _vModel = input.getAttribute('v-model'); if(_vModel){ input.addEventListener('keyup', this.handleInput.bind(this, _vModel, input)); } }) } MVVM.prototype.handleInput = function(_vModel, input){ this.data[_vModel] = input.value; } MVVM.prototype.bindDom = function(el){ const childNodes = el.childNodes; childNodes.forEach(child => { // nodeType == 3 表示文本节点 if(child.nodeType == 3){ const value = child.nodeValue; if(value.trim().length){ const isValid = /\{\{(.+?)\}\}/.test(value); if(isValid){ const key = value.match(/\{\{(.+?)\}\}/)[1].trim(); this.domPool[key] = child.parentNode; child.parentNode.innerText = this.data[key] || undefined; // 刚开始初始化时候设置默认值 } } } child.childNodes && this.bindDom(child); // 递归遍历所有嵌套的子元素 }) } MVVM.prototype.setData = function(obj){ for(let key in obj){ this.data[key] = obj[key]; } }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
原理
Vue实现数据双向绑定主要利用的就是: 数据劫持和发布订阅模式。
实现v-model
index.html
代码MVVM.js
代码参考文献
The text was updated successfully, but these errors were encountered: