我有一个应用程序需要遍历并显示类似于文件系统的目录结构。下面是一个如何使用文件系统的示例。
App.vue
<script setup>
import ListItem from './components/ListItem.vue';
const data = {
'C:/': {
'users/': {
'testUser/': {
'documents/': {},
},
},
'windows/': {
'system32': {},
},
},
'E:/': {
'test/': {},
},
};
</script>
<template>
<div style="display: flex; flex-direction: column">
<h1>Recursive Directory Browser</h1>
<ListItem title="Browse" :items="data" />
</div>
</template>
<style scoped></style>
ListItem.vue
<script setup>
import { defineProps, ref, nextTick } from 'vue';
const props = defineProps({
title: {
type: String,
required: true,
},
items: {
type: Object,
required: true,
},
});
const selectedName = ref();
const selectedValue = ref();
async function updateSelected(key, value) {
selectedName.value = key;
selectedValue.value = value;
}
</script>
<template>
<div style="border: 2px solid black; margin: 1em; padding: .25em;">
<h2>{{ title }}</h2>
<div style="display: flex; flex-direction: row;">
<template v-for="(value, key) in items">
<button @click="updateSelected(key, value)">{{ key }}</button>
</template>
</div>
</div>
<template v-if="selectedName">
<ListItem
:title="selectedName"
:items="selectedValue"
/>
</template>
</template>
<style scoped></style>
此代码生成的应用程序如下:
问题是,这里有一个错误,用户可以在目录中走几层深,然后如果用户导航回父目录上的不同节点,则已经探索过的路径的子组件仍然存在。
我通过添加一个名为的prop/ref来解决这个问题
updating
上
ListItem
组件,并在调用之间切换
nextTick()
.
ListItem.vue使用prop+组件和
nextTick()
<script setup>
import { defineProps, ref, nextTick } from 'vue';
const props = defineProps({
title: {
type: String,
required: true,
},
items: {
type: Object,
required: true,
},
updating: {
type: Boolean,
required: false,
default: false,
},
});
const updating = ref(props.updating);
const selectedName = ref();
const selectedValue = ref();
async function updateSelected(key, value) {
updating.value = true;
await nextTick();
selectedName.value = key;
selectedValue.value = value;
updating.value = false;
}
</script>
<template>
<div style="border: 2px solid black; margin: 1em; padding: .25em;">
<h2>{{ title }}</h2>
<div style="display: flex; flex-direction: row;">
<template v-for="(value, key) in items">
<button @click="updateSelected(key, value)">{{ key }}</button>
</template>
</div>
</div>
<template v-if="selectedName && !updating">
<ListItem
:title="selectedName"
:items="selectedValue"
:updating="updating"
/>
</template>
</template>
<style scoped></style>
StackBlitz Example
是否有更好的解决方案不依赖于
nextTick()
以及添加组件+道具?