observer.js 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. function Observer(data) {
  2. this.data = data;
  3. this.walk(data);
  4. }
  5. Observer.prototype = {
  6. walk: function(data) {
  7. var me = this;
  8. Object.keys(data).forEach(function(key) {
  9. me.convert(key, data[key]);
  10. });
  11. },
  12. convert: function(key, val) {
  13. this.defineReactive(this.data, key, val);
  14. },
  15. defineReactive: function(data, key, val) {
  16. var dep = new Dep();
  17. var childObj = observe(val);
  18. Object.defineProperty(data, key, {
  19. enumerable: true, // 可枚举
  20. configurable: true, // 不能再define
  21. get: function() {
  22. if (Dep.target) {
  23. dep.depend();
  24. }
  25. return val;
  26. },
  27. set: function(newVal) {
  28. if (newVal === val) {
  29. return ;
  30. }
  31. val = newVal;
  32. // 新的值是object的话,进行监听
  33. childObj = observe(newVal);
  34. // 通知订阅者
  35. dep.notify();
  36. }
  37. });
  38. }
  39. };
  40. function observe(value, vm) {
  41. if (!value || typeof value !== 'object') {
  42. return ;
  43. }
  44. return new Observer(value);
  45. };
  46. var uid = 0;
  47. function Dep() {
  48. this.id = uid++;
  49. this.subs = [];
  50. }
  51. Dep.prototype = {
  52. addSub: function(sub) {
  53. this.subs.push(sub);
  54. },
  55. depend: function() {
  56. Dep.target.addDep(this);
  57. },
  58. removeSub: function(sub) {
  59. var index = this.subs.indexOf(sub);
  60. if (index != -1) {
  61. this.subs.splice(index, 1);
  62. }
  63. },
  64. notify: function() {
  65. this.subs.forEach(function(sub){
  66. sub.update();
  67. });
  68. }
  69. };
  70. Dep.target = null;