vue中$emit诡异的无法触发问题

今日无意间发现一个 关于 vue $emit的诡异问题: 就是 如果把 this.$emit('xx')放入到 定时器中 或者 放入到 $nextTick中就不会触发相关的父级时间 请问各位大神有没有遇到过类似大问题
网上也看了一些相关答案 都是说作用域啊 大小写相关的原因。首先我的定时器和$nextTick均是箭头函数 不存在作用域问题 即使在外面缓存this传入 依然无法触发 大小写问题已经试过了 没有效果。
还在思否看到三年前有人提出了类似的问题至今还是没有得到解答真的很迷惑!还请各位大神指点!

setTimeout(() => {

this.$emit('liquidgroup')

}, 1000);

上面这样就无法触发 很是诡异

this.$emit('liquidgroup')

这样就可以!!!

回答

貌似并没复现,demo如下。建议题主提供一下能复现的简易版demo

<!DOCTYPE html>

<html>

<head>

<meta charset="UTF-8">

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

<meta content="IE=edge, chrome=1" http-equiv="X-UA-Compatible">

<meta content="webkit" name="renderer">

</head>

<body>

<div id="app">

<test-emit @change="changeHandler"></test-emit>

</div>

</body>

<script src="https://unpkg.com/vue/dist/vue.js"></script>

<script>

Vue.component('test-emit', {

methods: {

clickBtn () {

setTimeout(() => {

console.log('触发定时器')

this.$emit('change')

}, 1000)

this.$nextTick(() => {

console.log('触发nextTick')

this.$emit('change')

})

}

},

template: '<button @click="clickBtn">点我</button>'

})

new Vue({

el: '#app',

methods: {

changeHandler () {

console.log('触发父组件方法')

}

}

})

</script>

</html>

我这边复现了,很奇怪。而且比楼主表现的更奇怪,前面两次都触发了父组件事件,但是两次之后基本都触发不了了

经过我的进一步排查发下 这种问题只有在 async的异步函数中会发生 通过打出 当前vue的实例this 可发现 this是同一一个对象 只是加上定时器后的this中 refs 全都变成了undefined events 数组也变成了空数组

$attrs: (...)

$children: (2) [VueComponent, VueComponent]

$createElement: ƒ (a, b, c, d)

$el: div

$listeners: (...)

$options: {parent: VueComponent, _parentVnode: VNode, propsData: {…}, _parentListeners: {…}, _renderChildren: undefined, …}

$parent: VueComponent {_uid: 42, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

$refs: {Term: undefined, editMore: undefined}

上面是在定时器中打出this对象一部分 最后一行中的refs都变成了undefined

$attrs: (...)

$children: Array(2)

0: VueComponent {_uid: 922, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

1: VueComponent {_uid: 996, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

length: 2

__proto__: Array(0)

$createElement: ƒ (a, b, c, d)

$el: div

$listeners: (...)

$options: {parent: VueComponent, _parentVnode: VNode, propsData: {…}, _parentListeners: {…}, _renderChildren: undefined, …}

$parent: VueComponent {_uid: 42, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …}

$refs: {Term: VueComponent, editMore: VueComponent}~~~~

下面这个则是正常打出的 refs是可以得到的同理 events数组也是这样

以上前提都是我这些操作都是在一个 aysnc方法中得到的 如果为普通函数则没有上述现象

我做了以下4个测试
包括异步的
1.直接定义在异步函数里调用this this是undefined 这个很明白的
2.异步里传个箭头回调函数 正常触发
3.异步里传个一般回调函数 和1一样作用域是基于异步函数的上下文的 而不是当前组件
4.异步里传个箭头回调函数 箭头函数内调用定时器 正常触发
无论是正常的还是异步的 按你的需求应该都可以实现
所以你具体调用的异步代码是什么样的? 应该是异步处理代码的问题吧

export default{ 

name: 'views-segmentfault-questions-1010000023611723-sub',

methods: {

fn () {

console.log('调用fn')

this.$emit('ontest')

},

nexttick_fn () {

console.log('调用nexttick_fn')

this.$nextTick(()=>{

console.log('触发nextTick')

this.$emit('ontest')

})

},

settimeout_fn () {

console.log('调用settimeout_fn')

setTimeout(()=>{

console.log('触发settimeout')

this.$emit('ontest')

},1000)

},

async_fn(){

console.log('调用async_fn 1')

async function test1() {

console.log('触发async_fn 1')

console.log(this)

}

test1()

async function test2(fn) {

fn()

}

test2(()=>{

console.log('触发async_fn 2')

console.log(this)

this.$emit('ontest')

})

async function test3(fn) {

fn()

}

test3(function () {

console.log('触发async_fn 3')

console.log(this)

})

async function test4(fn) {

fn()

}

test4(()=>{

console.log('触发async_fn 4')

setTimeout(()=>{

console.log('触发async_fn 4 settimeout')

console.log(this)

this.$emit('ontest')

},1000)

})

}

}

}

以上是 vue中$emit诡异的无法触发问题 的全部内容, 来源链接: www.h5w3.com/38599.html

回到顶部