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 组件中可复用功能的非常灵活的方式.混入对象可以包含任意组件选项.当组件使 ...
随机推荐
- MUI-折叠面板效果accordion
在做开发的过程中我们经经常使用到折叠面板. 那我们来看下折叠面板到底是怎么使用. 废话不多说. 代码粘下来: <!DOCTYPE html> <html> <head&g ...
- 全局钩子 实例(不使用DLL和使用DLL两种)
大家应该都知道,全局消息钩子要依赖于一个DLL才能够正常工作.于是呢,我也就理所当在地认为全局钩子都要依赖于一个DLL才能正常工作的,我想大部分人肯定和我一样也这么认为的. 但实际上不是这样的.有某些 ...
- 【bzoj1433】[ZJOI2009]假期的宿舍
按要求连边,跑匈牙利 #include<algorithm> #include<iostream> #include<cstdlib> #include<cs ...
- 使用 fetch 代替 ajax(在不支持的浏览器上使用 XHR); This kind of functionality was previously achieved using XMLHttpRequest.
原生 JS Ajax,GET和POST 请求实例代码_javascript技巧_脚本之家 https://www.jb51.net/article/86157.htm 更新时间:2016年06月08日 ...
- URAL 1731. Dill(数学啊 )
题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1731 1731. Dill Time limit: 0.5 second Memory ...
- extjs4.0 treepanel节点的选中、展开! 数据的重新加载
1.extjs4.0API较3.0有非常大变化2.多级子父节点的选中和展开.3.数据的重新加载.tree.getStore().load4.节点的移除,从树中根据ID获取节点 tree.getStor ...
- linux 解决 Device eth0 does not seem to be present
在虚拟机中安装cent os系统,然后配置网络 执行命令ifconfig 没有看到eth0的信息: 重启网卡报错: service network restart Shutting down loop ...
- java 获取路径
1.利用System.getProperty()函数获取当前路径:System.out.println(System.getProperty("user.dir"));//user ...
- js中return的作用
1.终止函数的继续运行. 当遇到if…… else是.若出现return,就会出现终止运行,不会继续做出判断 <html> <head> <title>return ...
- mybatis使用序列批量插入数据
mybatis只提供了单条数据的插入,要批量插入数据我们可以使用循环一条条的插入,但是这样做的效率太低下,每插入一条数据就需要提交一次,如果数据量几百上千甚至更多,插入性能往往不是我们能接受的,如下例 ...