受控状态
如何在 Reka UI 中处理受控状态与非受控状态。
Reka UI 为组件提供了灵活的状态管理,允许开发者使用受控或非受控状态。理解何时使用每种方法可确保与 Vue 的响应式系统更好地集成。
受控状态 vs. 非受控状态
受控状态
受控组件通过 prop 接收其状态,并需要通过事件监听器进行显式更新。父组件管理并同步状态。
示例:受控 SwitchRoot
vue
<script setup>
import { SwitchRoot, SwitchThumb } from 'reka-ui'
import { ref } from 'vue'
const isActive = ref(false)
function handleUpdate(value) {
isActive.value = value
}
</script>
<template>
<SwitchRoot :model-value="isActive" @update:model-value="handleUpdate">
<SwitchThumb />
</SwitchRoot>
</template>
工作原理
SwitchRoot
组件的状态由isActive
ref 管理。@update:modelValue
事件确保更新正确传播。
在以下情况使用受控状态
- 您需要将状态与 Vuex、Pinia 或 API 同步时。
- 多个组件依赖于相同的状态时。
- 您需要对更新进行细粒度控制时。
将 v-model 与受控组件一起使用
Vue 的 v-model
语法提供了一种便捷的方式,可以在 Reka UI 中将值绑定到受控组件。它会自动处理值的传递和更新的监听。
示例:将 v-model
与 SwitchRoot
一起使用
vue
<script setup>
import { SwitchRoot, SwitchThumb } from 'reka-ui'
import { ref } from 'vue'
const isActive = ref(false)
</script>
<template>
<SwitchRoot v-model="isActive">
<SwitchThumb />
</SwitchRoot>
</template>
非受控状态
非受控组件在内部管理其自身状态,无需父组件控制的 prop。Reka UI 组件使用 defaultValue
初始化状态,而不是 modelValue
。
示例:非受控 SwitchRoot
vue
<template>
<SwitchRoot default-value="true">
<SwitchThumb />
</SwitchRoot>
</template>
工作原理
SwitchRoot
使用defaultValue
初始化其状态。- 状态更改在内部发生,无需外部控制。
在以下情况使用非受控状态
- 组件不需要与外部逻辑同步时。
- 您希望设置更简单,无需显式状态管理时。
- 状态是局部的,不影响其他组件时。
常见错误与修复
1. 忘记 @update:modelValue
vue
<!-- ❌ Incorrect: -->
<SwitchRoot :modelValue="isActive" />
<!-- ✅ Correct: -->
<SwitchRoot :modelValue="isActive" @update:modelValue="(val) => isActive = val" />
2. 使用 modelValue
而非 defaultValue
vue
<!-- ❌ Incorrect: -->
<SwitchRoot :modelValue="true" />
<!-- ✅ Correct: -->
<SwitchRoot defaultValue="true" />
3. 未为计算属性 (Computed Props) 提供 Setter
ts
// ❌ Incorrect:
const isActive = computed(() => store.state.toggleState)
// ✅ Correct:
const isActive = computed({
get: () => store.state.toggleState,
set: val => store.commit('setToggleState', val)
})