步骤
1、App.vue中使用provide()函数提供数据
provide() {
return {
topics: this.topics,
};
},
2、在使用到的最下层需要使用该数据的组件中添加inject
<script>
export default {
inject: ['topics'],
};
</script>
完整代码
App.vue
<template>
<div>
<active-element :topic-title="activeTopic && activeTopic.title"
:text="activeTopic && activeTopic.fullText"></active-element>
<knowledge-base @select-topic="activateTopic"></knowledge-base>
</div>
</template>
<script>
export default {
data() {
return {
topics: [
{
id: 'basics',
title: 'The Basics',
description: 'Core Vue basics you have to know',
fullText:
'Vue is a great framework and it has a couple of key concepts: Data binding, events, components and reactivity - that should tell you something!',
},
{
id: 'components',
title: 'Components',
description:
'Components are a core concept for building Vue UIs and apps',
fullText:
'With components, you can split logic (and markup) into separate building blocks and then combine those building blocks (and re-use them) to build powerful user interfaces.',
},
],
activeTopic: null,
};
},
// provide: {
// topics: [
// {
// id: 'basics',
// title: 'The Basics',
// description: 'Core Vue basics you have to know',
// fullText:
// 'Vue is a great framework and it has a couple of key concepts: Data binding, events, components and reactivity - that should tell you something!',
// },
// {
// id: 'components',
// title: 'Components',
// description:
// 'Components are a core concept for building Vue UIs and apps',
// fullText:
// 'With components, you can split logic (and markup) into separate building blocks and then combine those building blocks (and re-use them) to build powerful user interfaces.',
// },
// ],
// },
provide() {
return {
topics: this.topics,
};
},
methods: {
activateTopic(topicId) {
this.activeTopic = this.topics.find((topic) => topic.id === topicId);
},
},
mounted() {
setTimeout(() => {
this.topics.push({
id: 'vue',
title: 'Vue',
description: 'The best framework ever!',
fullText: 'Vue is the best framework ever!',
});
}, 3000);
},
};
</script>
<style>
* {
box-sizing: border-box;
}
html {
font-family: sans-serif;
}
body {
margin: 0;
}
section {
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.26);
margin: 2rem auto;
max-width: 40rem;
padding: 1rem;
border-radius: 12px;
}
ul {
list-style: none;
margin: 0;
padding: 0;
display: flex;
justify-content: center;
}
li {
border-radius: 12px;
border: 1px solid #ccc;
padding: 1rem;
width: 15rem;
margin: 0 1rem;
display: flex;
flex-direction: column;
justify-content: space-between;
}
h2 {
margin: 0.75rem 0;
text-align: center;
}
button {
font: inherit;
border: 1px solid #c70053;
background-color: #c70053;
color: white;
padding: 0.75rem 2rem;
border-radius: 30px;
cursor: pointer;
}
button:hover,
button:active {
background-color: #e24d8b;
border-color: #e24d8b;
}
</style>
ActiveElement.vue
<template>
<section>
<h2>{{ topicTitle }}</h2>
<p>{{ text }}</p>
</section>
</template>
<script>
export default {
props: ['topicTitle', 'text'],
};
</script>
KnowledgeBase.vue
<template>
<section>
<h2>Select a Topic</h2>
<knowledge-grid @select-topic="$emit('select-topic', $event)"></knowledge-grid>
</section>
</template>
<script>
export default {
emits: ['select-topic'],
};
</script>
KnowledgeGrid.vue
<template>
<ul>
<knowledge-element
v-for="topic in topics"
:key="topic.id"
:id="topic.id"
:topic-name="topic.title"
:description="topic.description"
@select-topic="$emit('select-topic', $event)"
></knowledge-element>
</ul>
</template>
<script>
export default {
inject: ['topics'],
emits: ['select-topic']
};
</script>
KnowledgeElement.vue
<template>
<li>
<h3>{{ topicName }}</h3>
<p>{{ description }}</p>
<button @click="$emit('select-topic', id)">Learn More</button>
</li>
</template>
<script>
export default {
props: ['id', 'topicName', 'description'],
emits: ['select-topic'],
};
</script>
main.js
import { createApp } from 'vue';
import App from './App.vue';
import ActiveElement from './components/ActiveElement.vue';
import KnowledgeBase from './components/KnowledgeBase.vue';
import KnowledgeElement from './components/KnowledgeElement.vue';
import KnowledgeGrid from './components/KnowledgeGrid.vue';
const app = createApp(App);
app.component('active-element', ActiveElement);
app.component('knowledge-base', KnowledgeBase);
app.component('knowledge-element', KnowledgeElement);
app.component('knowledge-grid', KnowledgeGrid);
app.mount('#app');