数据的双向绑定
之前我们已经实现数据影响视图,即数据更新调用setter()方法里绑定的方法,通过Dev通知Watcher更新视图。
然后我们需要实现视图影响数据进而再影响视图。
通过为input节点利用Object.addEventListener()绑定事件监听,再调用数据更新方法更新数据。
数据更改后由于之前已经实现了数据更改后页面的自动更新,由此数据自然驱动视图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| const compileUtil = { model(node, expr, vm) { const value = this.getValue(expr, vm); new Watcher(expr, vm, (newVal)=>{ this.updater.modelUpdater(node, newVal); }); node.addEventListener('input', (e)=>{ this.setVal(expr, vm, e.target.value); }) this.updater.modelUpdater(node, value); } }
|
this.$data的代理
我们可以通过在vm对象中使用this.person.name直接修改数据,而不是通过this.$data.person.name实现。
利用this.$data的代理实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| <script> let vm = new MVue({ el: '#app', data: { person: { name: '海贼——王路飞', age: 18, fav: 'film' }, msg: '最简单的插值', htmlStr: '<h3>这是v-html</h3>' }, methods:{ handleClick: function(){ console.log('这是一个处理点击事件的方法'); this.person.name = '海贼王——路飞' } } }); </script>
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class MVue { constructor(options) { this.$el = options.el; this.$data = options.data; this.$options = options; if (this.$el) { this.proxyData(this.$data); } } proxyData(data){ for(let key in data){ Object.defineProperty(this,key,{ get(){ return data[key]; }, set(newVal){ data[key] = newVal; } }) } } }
|
项目地址
https://github.com/SUNYunZeng/ImitateVue