当前位置:   article > 正文

Object.defineProperty实现vue双向绑定。小程序全局变量监听_微信小程序 object.defineproperty(obj

微信小程序 object.defineproperty(obj

1、众所周知,vue 双向数据绑定是通过 数据劫持 结合 发布订阅模式的方式来实现的, 也就是说数据和视图同步,数据发生变化,视图跟着变化,视图变化,数据也随之发生改变。这段话应该每个面试找工作的前端都背过。但是究竟是如何实现的,我个人按照个人理解,简单的梳理一下。

input触发input事件Object.defineProperty set() 赋值 回调直接传入值更新视图 或者 使用Object.defineProperty get()方法取值更新视图

我觉得还是直接看代码,打印,大家更能明白流程

2、这是使用了get取值,也可以不用get取值,直接回调传入值

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <div></div>
  9. <input type="text" id="Input" oninput="onInput()" />
  10. </body>
  11. <script>
  12. let myObj = {
  13. text: "",
  14. }
  15. function inputWatch(obj, name, cb) {
  16. let objName = obj[name];
  17. Object.defineProperty(obj, name, {
  18. // writable: true, // 是否可以修改属性的值
  19. configurable: true, //配置项(writable、enumerable)是否可以修改
  20. enumerable: true ,// 是否可以枚举
  21. get() {
  22. //获取属性值的时候进入
  23. console.log("get取值")
  24. return objName
  25. },
  26. set(val) {
  27. console.log("set赋值")
  28. // 触发setter给obj赋值
  29. objName = val
  30. //执行劫持后的操作
  31. setHtml();
  32. }
  33. })
  34. }
  35. // 回调赋值
  36. function setHtml() {
  37. console.log("回调更新视图")
  38. document.querySelector('div').innerHTML = myObj.text;
  39. document.querySelector('input').value = myObj.text;
  40. }
  41. // input变化赋值
  42. function onInput() {
  43. console.log("input变化")
  44. myObj.text = document.getElementById('Input').value
  45. }
  46. // 调用传入对象,对象属性,回调方法
  47. inputWatch(myObj, 'text', setHtml);
  48. </script>
  49. </html>

3、不使用get取值,直接回调传入值 

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <title></title>
  6. </head>
  7. <body>
  8. <div></div>
  9. <input type="text" id="Input" oninput="onInput()" />
  10. </body>
  11. <script>
  12. let myObj = {
  13. text: "",
  14. }
  15. function inputWatch(obj, name, cb) {
  16. let objName = obj[name];
  17. Object.defineProperty(obj, name, {
  18. // writable: true, // 是否可以修改属性的值
  19. configurable: true, //配置项(writable、enumerable)是否可以修改
  20. enumerable: true ,// 是否可以枚举
  21. get() {
  22. //获取属性值的时候进入
  23. console.log("get取值")
  24. return objName
  25. },
  26. set(val) {
  27. console.log("set赋值")
  28. // 触发setter给obj赋值
  29. objName = val
  30. //执行劫持后的操作
  31. setHtml(val);
  32. }
  33. })
  34. }
  35. // 回调赋值
  36. function setHtml(val) {
  37. console.log("回调更新视图值:",val)
  38. document.querySelector('div').innerHTML = val;
  39. document.querySelector('input').value = val
  40. }
  41. // input变化赋值
  42. function onInput() {
  43. console.log("input变化")
  44. myObj.text = document.getElementById('Input').value
  45. }
  46. // 调用传入对象,对象属性,回调方法
  47. inputWatch(myObj, 'text', setHtml);
  48. </script>
  49. </html>

总结:不要盲目的背答案,毕竟一段代码可以有千百种实现方式,没有最好只有更好。上面两种方式只是有一点小小的改动,都能实现双向绑定。但是个人觉得第二种直接调用方法传值,有点儿违背了模型驱动试图的逻辑,但是他的值都是同一个值。我甚至觉得不需要模型一样可以直接拿到值更改视图。(纯属个人想法, 大佬勿喷)

附加:此方法可衍生用于微信小程序,监听全局变量,实现全局监听器

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/123832
推荐阅读
相关标签
  

闽ICP备14008679号