vue中methods中的方法闭包缓存问题
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;
};
})(),
- 操作:
- 刷新页面, 第一次函数立即执行

- 页面生成完成后: 我们再次通过按钮触发事件: 此时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中的方法闭包缓存问题的更多相关文章
- vue 在methods中调用mounted中的方法?
首先可以在data中先声明一个变量 比如 isShow=' ' mounted 中 ---> methods 中 ---> this.sureDelBox(item) 直接this调用 ...
- vue给methods中的方法传入当前点击行的值
<template> <!-- 在template中,只能存在一个根组件 --> <div class="event"> <ul> ...
- Vue在一个函数中调用另外一个函数
如:在vue的methods中一个函数调用另外一个函数 this.$options.methods.函数名字(); (这样的话要注意,this的指向已经指向了这个实例而不是指向全局,所以可能会报错说b ...
- vue methods 中方法的相互调用
vue在同一个组件内:方法之间经常需要互相调用. methods中的一个方法如何调用methods中的另外一个方法呢? 可以在调用的时候使用 this.$options.methods.test2( ...
- vue中methods一个方法调用另外一个方法
转自http://blog.csdn.net/zhangjing1019/article/details/77942923 vue在同一个组件内: methods中的一个方法调用methods中的另外 ...
- vue中methods,computed,filters,watch的总结
08.28自我总结 vue中methods,computed,filters,watch的总结 一.methods methods属性里面的方法会在数据发生变化的时候你,只要引用了此里面分方法,方法就 ...
- vue中methods、computed、watch区别
vue中methods.computed.watch区别methods:事件调用的钩子 computed:{ // 计算属性是根据他依赖的值计算的,当依赖值发生变化,其跟着改变 // 计算属性是依赖缓 ...
- 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 ...
- vue中mixins的使用方法和注意点(详)
mixins基础概况 vue中的解释是这样的,如果觉得语言枯燥的可以自行跳过嘿~ 混入 (mixins): 是一种分发 Vue 组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使 ...
随机推荐
- Android版DesiredCapabilities参数配置
前言 每一个App测试都应指定是在什么平台下,那个设备中运行那个App,而在Appium中主要是通过DesiredCapabilities来配置的. DesiredCapabilities的作用,负责 ...
- VC 无边框对话框的任务栏右键菜单
MFC ,基于对话框的程序,属性为:Border : none. 程序运行后,在任务栏里面点右键,不会弹出类似下面的菜单: 在对话框的OnInitDialog里面添加如下语句即可: ModifySty ...
- 字符串函数---strcat()与strncat具体解释及实现
一.strcat()与strncat() strcat():strcat(dest,src); strcat把src所指向的字符加入到dest结尾处(覆盖原dest结尾处的'\0').并 ...
- 第一讲:使用html5——canvas绘制奥运五环
<html> <head> <title>初识canvas</title> </head> <body> <canvas ...
- windows下在eclipse上远程连接hadoop集群调试mapreduce错误记录
第一次跑mapreduce,记录遇到的几个问题,hadoop集群是CDH版本的,但我windows本地的jar包是直接用hadoop2.6.0的版本,并没有特意找CDH版本的 1.Exception ...
- 使用Apache Ant合并多个jar
Apache Ant下载地址 下载解压后进入bin目录,并在此目录打开cmd 在cmd中运行ant,运行结果为: Buildfile: build.xml does not exist! Build ...
- iOS webView的常见属性和方法
一.初始化与三种加载方式 UIWebView继承与UIView,因此,其初始化方法和一般的view一样,通过alloc和init进行初始化,其加载数据的方式有三种: 第一种: - (void)load ...
- HTTP服务器用什么组件或者方式比较好
我目前用Indy的HttpServer组件来编写,但遇到一个暂时没有办法解决的问题,就是上传文件到这个HTTPServer,如果文件名包含中文,则会出现乱码.网上查了一下,这是个indy的遗留问题,据 ...
- 类的加载、时机、反射、模板设计、jdk7/jdk8新特性(二十六)
1.类的加载概述和加载时机 * A:类的加载概述 * 当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过加载,连接,初始化三步来实现对这个类进行初始化. * 加载 * 就是指将class文 ...
- Javascript中两种最通用的定义类的方法
在Javascript中,一切都是对象,包括函数.在Javascript中并没有真正的类,不能像C#,PHP等语言中用 class xxx来定义.但Javascript中提供了一种折中的方案:把对象定 ...