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

问题背景

需求描述

  • 在路由的导航栏中需要, 判断是否为第一次点击
  • 需要一个标志位来记录是否点击过
  • 现状:
    • 这个标志位只在一个函数中用过.不希望存放全局
    • 希望在这个methods中形成闭包, 用来缓存这个函数
    • 做出如下尝试后, 发现可以实现.
  • 当前问题:
    • 不能在闭包调用时找到正确的this.

诡异点

  • 测试使用时: 返回的this找到了window
// 测试使用:
<div id="app">
<button @click="test">测试按钮</button>
</div>
<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进行返回函数的定义.

vue中methods中的方法闭包缓存问题的更多相关文章

  1. vue 在methods中调用mounted中的方法?

    首先可以在data中先声明一个变量 比如 isShow=' ' mounted 中 ---> methods 中 --->  this.sureDelBox(item) 直接this调用 ...

  2. vue给methods中的方法传入当前点击行的值

    <template> <!-- 在template中,只能存在一个根组件 --> <div class="event"> <ul> ...

  3. Vue在一个函数中调用另外一个函数

    如:在vue的methods中一个函数调用另外一个函数 this.$options.methods.函数名字(); (这样的话要注意,this的指向已经指向了这个实例而不是指向全局,所以可能会报错说b ...

  4. vue methods 中方法的相互调用

    vue在同一个组件内:方法之间经常需要互相调用. methods中的一个方法如何调用methods中的另外一个方法呢? 可以在调用的时候使用  this.$options.methods.test2( ...

  5. vue中methods一个方法调用另外一个方法

    转自http://blog.csdn.net/zhangjing1019/article/details/77942923 vue在同一个组件内: methods中的一个方法调用methods中的另外 ...

  6. vue中methods,computed,filters,watch的总结

    08.28自我总结 vue中methods,computed,filters,watch的总结 一.methods methods属性里面的方法会在数据发生变化的时候你,只要引用了此里面分方法,方法就 ...

  7. vue中methods、computed、watch区别

    vue中methods.computed.watch区别methods:事件调用的钩子 computed:{ // 计算属性是根据他依赖的值计算的,当依赖值发生变化,其跟着改变 // 计算属性是依赖缓 ...

  8. vue-learning:41 - Vuex - 第二篇:const store = new Vue.Store(option)中option选项、store实例对象的属性和方法

    vuex 第二篇:const store = new Vue.Store(option)中option选项.store实例对象的属性和方法 import Vuex from 'vuex' const ...

  9. vue中mixins的使用方法和注意点(详)

    mixins基础概况 vue中的解释是这样的,如果觉得语言枯燥的可以自行跳过嘿~ 混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使 ...

随机推荐

  1. Android 打造随意层级树形控件 考验你的数据结构和设计

    转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/40212367,本文出自:[张鸿洋的博客] 1.概述 大家在项目中或多或少的可能会 ...

  2. VUE 之 JS指令

    1.v-text的用法: 2.v-html 3.v-for 4.v-if , v-else if ,v-else v-if 每次生成都只有一个标签,即符合条件的标签. 5.v-show v-show ...

  3. Mac OS用minikube安装单节点kubernetes

    参考 https://kubernetes.io/docs/tasks/tools/install-minikube/ https://github.com/linianhui/code/blob/m ...

  4. Scaling with Microservices and Vertical Decomposition

    Scaling with Microservices and Vertical Decomposition – dev.otto.de https://dev.otto.de/2014/07/29/s ...

  5. bind_ip

    https://docs.mongodb.com/manual/reference/configuration-options/index.html 192.168.2.* --23T10:: I C ...

  6. 百度dureos CMake Error

    CMake Error: CMAKE_C_COMPILER not set, after EnableLanguage CMake Error: CMAKE_CXX_COMPILER not set, ...

  7. YTU 2866: 结构体---点坐标结构体

    2866: 结构体---点坐标结构体 时间限制: 1 Sec  内存限制: 128 MB 提交: 499  解决: 344 题目描述 定义一个表示点坐标的结构体,输入两个点的坐标,输出这两个点中点的坐 ...

  8. ios蓝牙开发(四)BabyBluetooth蓝牙库介绍

    BabyBluetooth 是一个最简单易用的蓝牙库,基于CoreBluetooth的封装,并兼容ios和mac osx. 特色: 基于原生CoreBluetooth框架封装的轻量级的开源库,可以帮你 ...

  9. BestCoder5 1001 Poor Hanamichi(hdu 4956) 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4956(它放在题库后面的格式有一点点问题啦,所以就把它粘下来,方便读者观看) 题目意思:给出一个范围 [ ...

  10. bleve搜索引擎源码分析之索引——mapping和lucene一样,也有_all

    例子: package main import ( "fmt" "github.com/blevesearch/bleve" ) func main() { / ...