在Vue 3中,我创建了几个类,其中包含ref和computed值,例如:
class BaseBlock {
id = "XXXXX"
run = ref(false)
disabled = ref(false)
alarm = ref(false)
ready = ref(false)
energySaving = ref(false)
resetNeed = ref(false)
activeCycle = ref(false)
n0 = {
status: ref(false),
sigla: "XXX",
title: "Alarm 0",
description: "Alarm 0 is active",
action: "Contact Saiet Engineering Customer Care",
color: COLORS.red,
}
n1 = {
status: ref(false),
sigla: "XXX",
title: "Alarm 1",
description: "Alarm 1 is active",
action: "Contact Saiet Engineering Customer Care",
color: COLORS.red,
}
constructor(id) {
this.id = id
this.runText = `The element ${id} is running as expected`
this.disabledText = `The element ${id} is currently DISABLED`
// activeAlarms is a computed array that keeps all currently active alarms in priority order
this.activeAlarms = computed(() => {
let activeArray = [];
for (let alarmId of this.alarmPriority) {
if (this[alarmId].status.value) activeArray.push(alarmId)
}
return activeArray
})
// if there are active alarms, color will return the highest priority alarm color
this.color = computed(() => {
// disabled
if (this.disabled.value) return COLORS.blue
// running
if (this.activeAlarms.value[0] == null) {
if (this.run.value) return COLORS.green
return 'white'
}
// alarms
return this[this.activeAlarms.value[0]].color
})
}
}
字符串
注意在我的computed属性中,我是如何调用变量的.value
来检查它是否是ref/computed的。
我不认为这有什么关系,但值得注意的是,这个类被其他类扩展,除了分配特殊值之外没有额外的计算,例如:
class Emergency extends BaseBlock {
alarmPriority = ['n12', 'n13']
alarms = ['n12', 'n13']
constructor(id) {
super(id)
Object.assign(
this.n12,
{
sigla: "SEM1",
title: "Emergency Memory",
description: "-",
action: "-",
}
)
Object.assign(
this.n13,
{
sigla: "SE1",
title: "Emercency pushbutton",
description: "Emergency pushbutton pressed",
action: "Pull Emergency pushbutton",
}
)
}
}
型
我的示例是在ref中创建的:
let blocks = ref({
'MCP01': new MainCabinet('MCP01'),
'CSW1': new LocalCabinet('CSW1'),
'CSW2': new LocalCabinet('CSW2'),
'CSW3': new LocalCabinet('CSW3'),
})
型
现在,假设我想在代码中的其他地方将blocks.value['MCP01'].run
更改为true
**,我期望做的是
blocks.value['MCP01'].run.value = true
型
但是这个不起作用,我需要做的是:
blocks.value['MCP01'].run = true
型
由于我没有从ref中更改.value
,我希望我实际上完全替换了变量,因此失去了React性。情况并非如此:我的类在代码中的任何地方都保持(显然?)React性,甚至是我的计算属性。
我的问题是:这是怎么回事为什么我的ref会自动展开,就像我在模板里面一样?为什么React性不会中断(或者可能会中断,但我还没有意识到?)**
P.S.通过搜索类似的问题,我意识到vue的最佳实践是完全避免类,而是使用可组合的(例如,在我的示例中,useBaseBlock
),但在这个项目中,这有点太晚了,而且我真的很想了解发生了什么。
1条答案
按热度按时间sy5wg1nm1#
如果给定了一个对象,ref会将其内部的所有ref展开。
从docs:
如果一个对象被赋值为一个ref的值,那么这个对象将与
reactive()
深度React。这也意味着如果这个对象包含嵌套的ref,那么它们将被深度展开。为了避免深度转换,请使用
shallowRef()
。你可以在返回类型中看到这一点:
Ref<UnwrapRef<T>>
。因此
let blocks = ref({ /* ... */ })
创建了对象的ref,并将其内部的所有ref展开。因此,作为ref的属性现在在父ref中暴露为简单值,因此必须直接使用,而不是通过.value
。