视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
如何解决vue中methods中的方法闭包缓存的问题
2020-11-27 19:33:46 责编:小采
文档
 这篇文章主要介绍了关于如何解决vue中methods中的方法闭包缓存的问题,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下

vue中methods中的方法闭包缓存问题

问题背景

需求描述

  • 在路由的导航栏中需要, 判断是否为第一次点击

  • 需要一个标志位来记录是否点击过

  • 现状:

  • 这个标志位只在一个函数中用过.不希望存放全局

  • 希望在这个methods中形成闭包, 用来缓存这个函数

  • 做出如下尝试后, 发现可以实现.

  • 当前问题:

  • 不能在闭包调用时找到正确的this.

  • 诡异点

  • 测试使用时: 返回的this找到了window

  • // 测试使用:
     <p id="app">
     <button @click="test">测试按钮</button>
     </p>
     <script>
     var app = new Vue({
     el: '#app',
     methods: {
     test: (() => {
     `use strict`
     console.log(this) // Window
     var flag = true
     return () => {
     console.log(this) // Window
     flag = false
     }
     })()
     }
     })
     </script>
  • 实际项目中的this变成了undefined

  • 更加诡异的是debugger之后, 我们一步步来看

  • 当前代码:

  •  pointJump: (() => {
     let isFirstChanged = false;
     console.log(this);
     debugger;
     return entry => {
     console.log(this);
     console.log(isFirstChanged);
     debugger;
     isFirstChanged = true;
     };
     })(),
  • 操作:

    1. 刷新页面, 第一次函数立即执行

    2. 页面生成完成后: 我们再次通过按钮触发事件: 此时debugger显示内存中为Vue的顶级对象, 而在控制台打印出来的依旧是undefined


    执行过程分析

  • 第一次执行的时候为undefined是正常的, 因为第一次闭包执行, 没有找到this

  • 当我们再次执行的时候, 虽然调用起来的上下文, 也就是this已经改了, 但是因为在作用域中那个this所代表的空间还是undefined, 所以没有能改变过来.

  • 就造成了我们所看到的诡异的现象.

  • 与测试文件有差别的原因

  • 因为在测试环境下, 没有能开启严格模式.

  • 经过两次不同位置的的开启尝试, 都不对

  • 依旧可以找到window对象

  • 现在推测是在vue内部进行的实现, 因为引入的vue版本不同.需要再进行测试, 看来源码还是要好好过一遍

  •  <script>
     var app = new Vue({
     el: '#app',
     methods: {
     test: (() => {
     `use strict`
     console.log(this) // Window
     var flag = true
     return () => {
     console.log(this) // Window
     flag = false
     }
     })()
     }
     })
     </script>

    最后找到原因的测试

  • 因为箭头函数的this是不会改变, 拥有根据父级能够返回的this

  • 然后因为上面的闭包环境中的this, 指向的一直都是undefined

  • const test = (() => {
     let aaa = true;
     return function () {
     console.log(this);
     aaa = false;
     };
    })();
    mainJump(entry) {
     test.call(this);
    },

    解决方法

  • 形成闭包返回的函数中, 不要使用箭头函数, 使用function定义即可

  •  pointJump: (() => {
     let isFirstChanged = false;
     return function () {
     console.log(this); // Vue的顶级对象
     isFirstChanged = true;
     };
     })(),

    总结

  • 箭头函数不会被call, bind等方法改变this指向

  • 在闭包中返回函数, 缓存变量时, 使用function进行返回函数的定义.

  • 下载本文
    显示全文
    专题