我是靠谱客的博主 还单身口红,这篇文章主要介绍MVVM双向绑定简单实现,现在分享给大家,希望可以做个参考。

复制代码
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"> <style> </style> </head> <body> <div id='app'> <input type="text" v-model="hello"/> {{hello}} <div> <div>{{name}}</div> </div> </div> <script> //发布者 function Dep(){ this.subs=[] } Dep.prototype.addSub = function(_watcher){ this.subs.push(_watcher); } Dep.prototype.upDate = function(){ // console.log(this.subs) this.subs.map(_watcher=>{ console.log(_watcher) _watcher.upDate(); }) } //订阅者 function watcher(vm,node,name){ Dep.target = this; this.vm=vm; this.node=node; this.name=name; this.upDate(); Dep.target=null; } watcher.prototype.upDate=function(){ console.log('被调用啦???') this.node.nodeValue=this.vm[this.name]; } function MVVM(opt){ this.id = opt.el; this.data = opt.data; this.observe(this.data,this) this.dom = this.nodeToFragment(document.getElementById(this.id),this); document.getElementById(this.id).append(this.dom); } MVVM.prototype.nodeToFragment = function(dom,vm){ //把#app下的全部保存到文档碎片中 var frag = document.createDocumentFragment(); var child; while(child = dom.firstChild){ var _child = this.complie(child,vm) frag.append(_child); } return frag; } MVVM.prototype.complie = function(dom,vm){ // 这里主要是把#app 下的dom节点全部解析 var reg = /{{(.*)}}/; switch(dom.nodeType){ case 1://dom节点; var atte = dom.attributes; for(var i=0;i<atte.length;i++){ if(atte[i].nodeName == "v-model"){ var name = atte[i].nodeValue; dom.addEventListener('input',function(e){ vm[name]=e.target.value; }) dom.value = vm[name]; dom.removeAttribute("v-model"); } } dom.append(this.nodeToFragment(dom,vm)); break; case 3://文本节点 var value = dom.nodeValue; if(reg.test(value)){ var name = RegExp.$1; name = name.trim(); new watcher(vm,dom,name);//对每个文本节点,当做是一个订阅者 } break; } return dom; } MVVM.prototype.observe = function(obj,vm){ //将data下的数据全部进行get set监听,然后放置到根对象下 Object.keys(obj).map( key =>{ this.defineProperty(vm,key,obj[key]) }) } MVVM.prototype.defineProperty=function(obj,key,val){ var dep = new Dep(); Object.defineProperty(obj,key,{ get:function(){ //把该字段当做发布者 //把调用该字段的dom节点当做订阅者 if(Dep.target) dep.addSub(Dep.target); console.log('需要取数据',key,'<>',val) return val; }, set:function(newVal){ if(val !== newVal){ console.log('需要更新数据',val,"--->",newVal) val=newVal; dep.upDate(); //发布者进行全局更新 } } }) } var vue = new MVVM({ el:'app', data:{ hello:'hello world', name:'小明' } }) </script> </body> </html>

最后

以上就是还单身口红最近收集整理的关于MVVM双向绑定简单实现的全部内容,更多相关MVVM双向绑定简单实现内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部