我有键盘导航系统。当你按下箭头向上或箭头向下时,一个事件从app.js发出(我发现最好的地方听这些按键,因为它们需要在系统范围内)到组件中的mounted()。
在组件的mounted()部分中,Event.$on()调用一个函数,该函数使用$refs来识别当前选中的项目,并在按ENTER键时显示它的模式。
app.js代码(听按键):
else if (event.key === 'ArrowUp' || event.key === 'ArrowDown' || event.key === 'Enter') {
event.preventDefault()
switch (this.$router.currentRoute.path) {
case "/pedidos":
Event.$emit('navegarSetasPedidos', event.key)
break;
case "/clientes":
Event.$emit('navegarSetasClientes', event.key)
break;
}
}
所讨论组件的mounted()节:
mounted() {
Event.$on('navegarSetasPedidos', (key) => {this.navegarSetas(key)})
}
函数负责导航(抱歉格式不好,还没有弄清楚stackoverflow的代码块是如何工作的):
navegarSetas(key) {
if (this.navegacaoSetasAtiva == false) {
this.navegacaoSetasAtiva = true
this.navegacaoAtual = 0
} else if (this.modalAtivado == false && this.navegacaoSetasAtiva == true) {
if (key == 'ArrowDown' && this.navegacaoAtual < this.pedidos.length - 1) {
this.navegacaoAtual++
let elementoSelecionado = this.$refs['pedido'+this.navegacaoAtual][0].$el
let boundaries = elementoSelecionado.getBoundingClientRect()
if (boundaries.top < 0 || boundaries.top > (window.innerHeight || document.documentElement.clientHeight)){
elementoSelecionado.scrollIntoView({behavior: 'smooth'})
}
} else if (key == 'ArrowUp' && this.navegacaoAtual <= this.pedidos.length && this.navegacaoAtual > 0) {
this.navegacaoAtual--
let elementoSelecionado = this.$refs['pedido'+this.navegacaoAtual][0].$el
let boundaries = elementoSelecionado.getBoundingClientRect()
if (boundaries.top < 0 || boundaries.top > (window.innerHeight || document.documentElement.clientHeight)){
elementoSelecionado.scrollIntoView({behavior: 'smooth'})
}
} else if (key == 'Enter') {
let pedidoSelecionado = this.pedidos[this.navegacaoAtual].id
Event.$emit('changeShow', pedidoSelecionado)
}
}
这在第一次访问时非常有效。问题是,如果我更改当前路由以显示另一个组件,然后返回到前一个组件,我会得到很多"this.$refs['pedido'+this. navegacaoatual][0]。$el未定义"错误,但系统仍然正常工作,尽管不规律。
有趣的是:如果我控制台日志"this.$refs['pedido'+this. navegacaoual][0]。$el是未定义的",我将在错误之前得到一个空日志,然后在它的正下方得到另一个,这次不是空的。
其他地方我已经搜索这说,问题是由于如何Vue重新渲染的东西,我调用这个事件之前,它被渲染,这应该是不可能的,因为我调用它内部mounted()。
任何帮助都是非常感激的,谢谢!
事实证明,经过大量的搜索,Event.$on
事件设置器也可以作为正常的JavaScript设置器工作(现在我正在考虑它,这很有意义)-这意味着您必须在组件卸载时销毁它们(又名销毁)。
即使VUE Dev Tools在重路由后只选择一个事件,它仍然触发两个(通过console.log()
返回一个空值,一堆错误,以及错误后填充数组的另一个值)。
解决这个问题的方法是简单地将Event.$off('eventName')
加到组件的destroyed()
函数上。