vue响应式简单实现

x33g5p2x  于2022-03-05 转载在 Vue.js  
字(2.8k)|赞(0)|评价(0)|浏览(660)

一、写在前面
关于MVVM开发模式,不得不说其响应式原理。响应式是MVVM架构和MVP之间最为显著的区别。在以前使用MVP架构进行前端开发时,其中间层p需要处理的逻辑特别多,导致比较臃肿。随着MVVM架构的出现,大大减少了中间层处理的业务逻辑。原因是其响应式原理,视图可以触发其中的某一个指令来改变数据,当数据改变时,视图也会随之刷新。下面我们将简单实现一个响应式。
二、vue2和vue3的响应式的区别
vue2中我们对响应式数据进行监听时,使用的是Object.defineProperty方法来实现的,在vue3中使用的是Proxy来实现响应式的。vue3相比于vue2来说可以监听更多类型的数据改变。
三、vue2的响应式实现

  1. let activeFns = null
  2. function reactive(obj) {
  3. Object.keys(obj).forEach(key => {
  4. let value = obj[key]
  5. Object.defineProperty(obj, key, {
  6. get() {
  7. let depend = getDepend(obj, key)
  8. depend.depend()
  9. return value
  10. },
  11. set(newValue) {
  12. let depend = getDepend(obj,key)
  13. value = newValue
  14. depend.notify()
  15. }
  16. })
  17. })
  18. return obj
  19. }
  20. class Depend {
  21. constructor() {
  22. this.deps = new Set()
  23. }
  24. depend() {
  25. if(activeFns) {
  26. this.deps.add(activeFns)
  27. }
  28. }
  29. notify() {
  30. this.deps.forEach(fn => fn())
  31. }
  32. }
  33. let wmap = new WeakMap()
  34. function getDepend(target, key) {
  35. let targetMap = wmap.get(target)
  36. if(!targetMap) {
  37. targetMap = new Map()
  38. wmap.set(target, targetMap)
  39. }
  40. let depend = targetMap.get(key)
  41. if(!depend) {
  42. depend = new Depend()
  43. targetMap.set(key, depend)
  44. }
  45. return depend
  46. }
  47. function watchFn(fn) {
  48. activeFns = fn
  49. fn()
  50. activeFns = null
  51. }
  52. let info = reactive({
  53. name: "dmc",
  54. age: 20
  55. })
  56. watchFn(function() {
  57. console.log("------------" + info.name + "++++++++++++++++")
  58. })
  59. watchFn(function() {
  60. console.log("------------" + info.age + "++++++++++++++++")
  61. })
  62. watchFn(function() {
  63. console.log("------------" + info.name + "---------------")
  64. })
  65. info.name = "dl"
  66. //打印结果
  67. /*
  68. ------------dmc++++++++++++++++
  69. ------------20++++++++++++++++
  70. ------------dmc---------------
  71. ------------dl++++++++++++++++
  72. ------------dl---------------
  73. */

四、vue3的响应式实现

  1. let activeFn = null
  2. function reactive(obj) {
  3. return new Proxy(obj, {
  4. get(target, key, receiver) {
  5. let depend = getDepend(target, key)
  6. depend.depend()
  7. return Reflect.get(target, key, receiver)
  8. },
  9. set(target, key, newValue, receiver) {
  10. let depend = getDepend(target, key)
  11. Reflect.set(target, key, newValue, receiver)
  12. depend.notify()
  13. }
  14. })
  15. }
  16. let wmap = new WeakMap()
  17. function getDepend(target, key) {
  18. let targetMap = wmap.get(target)
  19. if(!targetMap) {
  20. targetMap = new Map()
  21. wmap.set(target, targetMap)
  22. }
  23. let depend = targetMap.get(key)
  24. if(!depend) {
  25. depend = new Depend()
  26. targetMap.set(key, depend)
  27. }
  28. return depend
  29. }
  30. class Depend {
  31. constructor() {
  32. this.deps = new Set()
  33. }
  34. depend() {
  35. if(activeFn) {
  36. this.deps.add(activeFn)
  37. }
  38. }
  39. notify() {
  40. this.deps.forEach(fn => fn())
  41. }
  42. }
  43. function watchFn(fn) {
  44. activeFn = fn
  45. fn()
  46. activeFn = null
  47. }
  48. let info = reactive({
  49. name: "dmc",
  50. age: 20
  51. })
  52. watchFn(function() {
  53. console.log("--------" + info.name + "++++++++")
  54. })
  55. watchFn(function() {
  56. console.log("********" + info.name + "0000000000")
  57. })
  58. watchFn(function() {
  59. console.log("********" + info.age + "0000000000")
  60. })
  61. console.log("??????????????????????????????")
  62. info.name = "sscls"
  63. /*
  64. --------dmc++++++++
  65. ********dmc0000000000
  66. ********200000000000
  67. ??????????????????????????????
  68. --------sscls++++++++
  69. ********sscls0000000000
  70. */

相关文章

最新文章

更多