{"id":689,"date":"2017-08-08T15:51:25","date_gmt":"2017-08-08T07:51:25","guid":{"rendered":"http:\/\/loveuhouse.cn\/wordpress\/?p=689"},"modified":"2017-08-08T15:51:25","modified_gmt":"2017-08-08T07:51:25","slug":"vue1-0-observer-watcher-%e5%8f%8c%e5%90%91%e7%bb%91%e5%ae%9a%e7%ae%80%e5%8d%95js%e5%ae%9e%e7%8e%b0","status":"publish","type":"post","link":"https:\/\/loveuhouse.cn\/wordpress\/?p=689","title":{"rendered":"vue1.0 Observer watcher \u53cc\u5411\u7ed1\u5b9a\u7b80\u5355js\u5b9e\u73b0"},"content":{"rendered":"<p>\u6765\u6e90\uff1a<a href=\"https:\/\/segmentfault.com\/a\/1190000004384515\">https:\/\/segmentfault.com\/a\/1190000004384515<\/a><\/p>\n<pre class=\"lang:js decode:true\">\n(function(){\n    \/\/Observer\n    var Observer = cc.Class.extend({\n        ctor: function(value){\n            this.value = value;\n            this.walk(value);\n        },\n        walk: function(value){\n            Object.keys(value).forEach(function(key, ind, arr){\n                this.convert(key,value[key]);\n            },this);\n        },\n        convert: function(key, val){\n            defineReactive(this.value, key, val);\n        }\n    });\n    var defineReactive = function(obj, key, val){\n        var dep = new Dep();\n        var childOb = observer(val);\n        Object.defineProperty(obj, key, {\n            enumberable: true,\n            configurable: true,\n            get: function(){\n                console.log(\"get\");\n                if(Dep.target){\n                    dep.addSub(Dep.target);\n                }\n                return val;\n            },\n            set: function(newValue){\n                console.log(\"set\",newValue);\n                var value = val;\n                if(newValue === value){\n                    return;\n                }\n                childOb = observer(newValue);\n                dep.notify();\n            }\n        })\n    };\n    var observer = function(value, vm){\n        if (!value || typeof value !== 'object') {\n            return;\n        }\n        return new Observer(value);\n    };\n    \/\/\u8ba2\u9605\u5668\n    var Dep = cc.Class.extend({\n        ctor: function(){\n            this.subs = [];\n        },\n        addSub:function(sub){\n            this.subs.push(sub);\n        },\n        notify:function(){\n            this.subs.forEach(function(sub, ind, arr){\n                sub.update();\n            })\n        },\n    });\n    Dep.target = null\n    \/\/watcher\n    var Watcher = cc.Class.extend({\n        ctor: function(vm, expOrFn, cb){\n            this.cb = cb;\n            this.vm = vm;\n            \/\/\u6682\u65f6\u53ea\u8003\u8651expression\u7684\u60c5\u51b5\n            this.expOrFn = expOrFn;\n            this.value = this.get();\n        },\n        update: function(){\n            this.run();\n        },\n        run: function(){\n            var value = this.get();\n            if(value !== this.value){\n                this.value = value ;\n                this.cb.call(this.vm);\n            }\n        },\n        get: function(){\n            Dep.target = this;\n            \/\/\u6682\u65f6\u53ea\u8003\u8651expression\u7684\u60c5\u51b5\n            var value = this.vm._data[this.expOrFn];\n            Dep.target = null;\n            return value;\n        }\n    });\n    \/\/Vue\n    var vue = cc.Class.extend({\n        ctor: function(options){\n           this.$options = options || {};\n           var data = this._data = this.$options.data;\n           Object.keys(data).forEach(function(key, ind, arr){\n               this._proxy(key);\n           },this);\n           observer(data, this);\n        },\n        $watcher: function(expOrFn, cb, options){\n            new Watcher(this, expOrFn, cb);\n        },\n        _proxy: function(key){\n            var self = this;\n            Object.defineProperty(self, key, {\n                configurable: true,\n                enumberalbe: true,\n                get:function proxyGetter(){\n                    return self._data[key];\n                },\n                set: function proxySetter(val){\n                    self._data[key] = val;\n                }\n            });\n        }\n    });\n\n    mj.vue = vue;\n})();\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u6765\u6e90\uff1ahttps:\/\/segmentfault.com\/a\/1190000004384515 (functio &hellip; <a href=\"https:\/\/loveuhouse.cn\/wordpress\/?p=689\" class=\"more-link\">\u7ee7\u7eed\u9605\u8bfb<span class=\"screen-reader-text\">vue1.0 Observer watcher \u53cc\u5411\u7ed1\u5b9a\u7b80\u5355js\u5b9e\u73b0<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/689"}],"collection":[{"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=689"}],"version-history":[{"count":1,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions"}],"predecessor-version":[{"id":690,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/689\/revisions\/690"}],"wp:attachment":[{"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=689"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=689"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/loveuhouse.cn\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=689"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}