我正在尝试根据用户选择渲染子组件。在父组件中使用 v-if 时我可以很容易地做到这一点,但是当尝试渲染子组件时它不起作用。
<template>
<div class="mt-4">
<p>{{ continents.asia }}</p>
<p>{{ continents.africa }}</p>
<ul class="space-y-8">
<li>
<button @click="showList('asia')">Asia</button>
</li>
<li>
<button @click="showList('africa')">Africa</button>
</li>
</div>
<div>
<AsiaCountries v-if="continents.asia" />
<AfricaCountries v-if="continents.africa" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import AsiaCountries from '@/components/Asia/AsiaCountries.vue'
import AfricaCountries from '@/components/AfricaCountries.vue'
const continents = {
asia: ref(false),
africa: ref(false),
europe: ref(false)
};
const showList = (listName) => {
for (const key in continents) {
if (key === listName) {
continents[key].value = true;
} else {
continents[key].value = false;
}
}
};
</script>
单击按钮时,
{{ continents.asia }}
正确显示 true,但子组件 AsiaCountries
未渲染。
我的子组件 AsiaCountries.vue :
<template>
<div>
<ul>
<li>Afghanistan</li>
<li>Armenia</li>
<li>Azerbaijan</li>
<li>Bahrain</li>
</ul>
</div>
</template>
<script setup>
</script>
谢谢您的帮助!
PS:在控制台中,我收到以下错误:“外部非 props 属性 (v-if) 已传递给组件,但无法自动继承,因为组件渲染片段或文本根节点。 '
问题在于您使用带有 ref 属性的普通(非反应性)对象。似乎这在
v-if
中不起作用,这似乎是 Vue 的错误。在您的情况下,您提供 continents.asia
,它返回对 ref 的非反应性引用。为了使其工作,您应该明确“取消引用”参考:continents.asia.value
。
为了避免这种情况(看起来很难看),请将您的
continents
转换为具有常用道具的反应性对象。
但是整个方法太冗长了,只需使用一个简单的字符串值即可在各大洲之间切换:
<template>
<div class="mt-4">
<p>{{ continent }}</p>
<ul class="space-y-8">
<li>
<button @click="continent ='asia'">Asia</button>
</li>
<li>
<button @click="continent = 'africa'">Africa</button>
</li>
</ul>
</div>
<div>
<AsiaCountries v-if="continent === 'asia'" />
<AfricaCountries v-if="continent === 'africa'" />
</div>
</template>
<script setup>
import { ref } from 'vue'
import AsiaCountries from './AsiaCountries.vue'
import AfricaCountries from './AfricaCountries.vue'
const continent = ref('africa');
</script>
进一步的改进将避免为大陆使用单独的组件,而只需根据按大陆过滤的 JSON 数据构建列表(使用
computed
)。