我有一个显示数据行的组件,我想切换显示或隐藏细节。这是它应该看起来:
这是通过将数据Map到一个新数组并添加一个opened
属性来完成的。
<script setup>
import { defineProps, reactive } from 'vue';
const props = defineProps({
data: {
type: Array,
required: true,
},
dataKey: {
type: String,
required: true,
},
});
const rows = reactive(props.data.map(value => {
return {
value,
opened: false,
};
}));
function toggleDetails(row) {
row.opened = !row.opened;
}
</script>
<template>
<div>
<template v-for="row in rows" :key="row.value[dataKey]">
<div>
<!-- Toggle Details -->
<a @click.prevent="() => toggleDetails(row)">
{{ row.value.key }}: {{ row.opened ? 'Hide' : 'Show' }} details
</a>
<!-- Details -->
<div v-if="row.opened" style="border: 1px solid #ccc">
<div>opened: <pre>{{ row.opened }}</pre></div>
<div>value: </div>
<pre>{{ row.value }}</pre>
</div>
</div>
</template>
</div>
</template>
但是,我不想让Array具有很强的React性,所以我尝试使用ref
,只让opened
具有React性:
const rows = props.data.map(value => {
return {
value,
opened: ref(false),
};
});
function toggleDetails(row) {
row.opened.value = !row.opened.value;
}
属性opened
现在是完全被动的,但是切换不再起作用:
我怎样才能让这个开关工作,而不使整个价值React?
1条答案
按热度按时间fruv7luv1#
问题似乎来自Vue将ref替换为它的值。
当
row.opened
是初始化为ref(false)
的ref时,模板表达式如下:似乎被解释为(字面上)
不如预期的(比喻):
但是如果我像上面那样写(用
.value
),它就能工作。if
也是一样,如果我这样做,它就工作:有趣的是,这种行为发生在
v-if
和三元组中,但不发生在直接访问上,即{{ rows[0].opened }}
是React式的,而{{ rows[0].opened ? "true" : "false" }}
不是,这似乎是Vue的表达式解析器的问题,here也有类似的问题。