【发布时间】:2021-06-30 20:51:19
【问题描述】:
我目前正在将基于 MQTT 的仪表板从 Vue 2 重写为 Vue 3,但无法解决一个问题。
仪表板有许多 Vue 组件,它们对特定的 MQTT 主题和值做出反应,以显示当前系统状态。其中之一是 mqtt-multi-state 组件,声明如下:
// status-page
<mqtt-multi-state subscribe-topic="home/env/sensor/wc/door/status" json-path="state">
<div value="OPEN"><font-awesome-icon icon="door-open"/></div>
<div value="CLOSED"><font-awesome-icon icon="door-closed"/></div>
</mqtt-multi-state>
它包含两个div 元素,具有系统传感器(门)可以具有的两种状态。这些元素被传递到default 插槽,默认通过css隐藏。
我想要实现的是基于它们每个中的value attr 与当前 MQTT 值的相等性来显示其中一个。因此,如果当前值为 OPEN 则显示第一个 div,当值为 CLOSED 时出现第二个。
// mqtt-multi-state
<template>
<div class="mqtt-multi-state">
<div>
<slot></slot>
</div>
</div>
</template>
<script>
export default {
methods: {
messageArrived(value){
let states = this.$slots.default() // here are the two divs
for(let i = 0;i < states.length;i++ ){
if(states[i].props.value === value )
{
//states[i].elm.className = "state-active" <- Vue 2 solution using DOM with elm
//states[i].props.class = "state-active"; <- Vue 3, doesn't work, not reactive?
}
else
{
//states[i].props.class = "";
}
}
}
}
}
</script>
我知道,这种方法有点不同,但我真的很喜欢用这种方式在 HTML 中描述仪表板元素。在messsageArrive() 方法中,我正在迭代default 插槽子元素,如果值与当前value 道具匹配,我想通过添加state-active 类来显示此项目。但是这个解决方案不起作用。 VNode 已更改(在控制台中检查)。
在 Vue 2 中,我只是直接访问 DOM 元素并更改它的类,但在 Vue 3 中,我无法弄清楚如何从 VNode 到 DOM 节点。或者可能有其他/更好的方法来做到这一点?
【问题讨论】:
标签: javascript vuejs3