【发布时间】:2020-09-04 16:20:55
【问题描述】:
我正在开发一个 vue 项目,并希望在一段时间后从子组件向父组件发出事件(用户将鼠标悬停在元素上,几秒钟后,应该会发出)。
我很确定我在其他组件中已经完成了与此类似的发射,并且它以前也有效,但现在我得到了这两个错误。我不确定发生了什么变化。我在第一次尝试后实现了 vuex,回到了这个,现在我不确定发生了什么?但也许我只是删除了一些东西,或者我不知道。 我还在似乎有问题的行上方尝试了一个控制台日志,并且该值似乎不为空。 这些是我得到的错误:
[Vue 警告]:v-on 处理程序中的错误:“TypeError:无法读取 null 的属性 'emit'” 之后出现错误 Cannot read property 'emit' of null 第一个错误提到,该错误是在组件中发现的,如下所示。
我看到的与此问题相关的大部分内容都是关于人们不正确地执行 es6 箭头功能,所以 this.timer = setInterval(() => this.countdown(), 1000); 可能有问题?我不太确定。
这是组件(请原谅凌乱的代码):
<template>
<div
:id="id"
class="board"
@dragenter.prevent
@dragover.prevent
@drop.prevent="drop"
@dragenter="dragenter($event)"
@dragover="dragover($event)"
@dragleave="dragleave($event)"
>
<slot class="row"/>
<div
:id="`ui-details-${id}`"
v-show="extendedHover">
Long hover
</div>
</div>
</template>
<script>
export default {
name: 'Devices',
props: ['id', 'acceptsDrop'],
data() {
return {
extendedHover: false,
timer: null,
totalTime: 2,
};
},
methods: {
drop(e) {
if (e.dataTransfer.getData('type') === 'layout') { // only accept dropped cards, not boards
const layoutId = e.dataTransfer.getData('layout_id');
this.$emit('dropped-layout', layoutId);
}
clearInterval(this.timer);
this.timer = null;
this.totalTime = 2;
console.log(e.dataTransfer.getData('card_id'));
e.target.classList.remove('hover-drag-over');
this.extendedHover = false;
// this.$emit('cancel-hover');
console.log('-------------dropped');
console.log(e);
console.log(e.dataTransfer.getData('type'));
/* const cardId = e.dataTransfer.getData('card_id');
console.warn('dropped onto device');
this.$emit('dropped-component', cardId);
e.target.classList.remove('hover-drag-over'); */
},
dragenter(e) {
// on dragenter we start a countdown of 1s
// over this value --> we see it as a long hover
console.log('------------dragenter');
console.log(e);
this.timer = setInterval(() => this.countdown(), 1000);
},
dragover(e) {
if (this.acceptsDrop) {
e.target.classList.add('hover-drag-over');
}
},
dragleave(e) {
if (this.acceptsDrop) {
clearInterval(this.timer);
this.timer = null;
this.totalTime = 2;
e.target.classList.remove('hover-drag-over');
this.extendedHover = false;
// this.$emit('cancel-hover');
}
},
countdown() {
this.totalTime -= 1;
if (this.totalTime === 0) {
this.extendedHover = true;
console.warn(this);
this.$emit('long-hover'); //this is the problematic line
}
},
},
};
</script>
<style scoped>
.board{
width: 100%;
min-height: 200px;
}
</style>
感谢您的帮助!
编辑:
console.log 的输出如下VueComponent {_uid: 18, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: VueComponent, …},如果需要,还可以扩展以获取更多信息。
Edit2:这个组件是根据父组件中的数组生成的,就像这样。所以这个槽现在只被一个字符串填充。
<div
class = "col-4"
v-for="(device, index) in devices"
v-bind:key="`device-${device.ip}`"
>
<Devices
:id="`board-${device.ip}`"
v-bind:class="{'droparea-device':true, 'your-device': (index === thisDeviceIndex)}"
@dropped-layout="$emit('dropped-layout', $event, index)"
@long-hover="fetchAvailableUIsForDevice(device.device_name)"
@cancel-hover="cancelHover()"
:acceptsDrop=true
>
{{device.device_name}}
</Devices>
</div>
编辑3: 对于测试,我也只是想尝试一个非常基本的东西。所以我添加了一个带有这样的点击事件的按钮(但仍然存在错误):
<b-button
type="button"
variant="success"
v-on:click="$emit('long-hover')"
>
Control Center
</b-button>
【问题讨论】:
-
console.warn(this);的输出是什么? -
@Anatoly,我将输出添加到问题描述的底部。这样做有帮助吗?
-
直接在dragenter中调用
this.$emit('long-hover');,问题会消失吗? -
我用这一行测试了它 this.timer = setInterval(() => this.$emit('long-hover'), 1000); 和同样的错误遗迹。此外,我尝试完全摆脱计时器并仅使用 this.$emit('long-hover') 对其进行测试,并且错误也仍然存在。我觉得有点奇怪......
-
你确定那个 $emit 调用中的错误而不是另一个错误吗?
标签: javascript vue.js events components emit