Vue3 学习教程,从入门到精通,Vue 3 组件语法知识点与案例代码(14)
Vue 3 组件语法知识点与案例代码
Vue 3 是一个用于构建用户界面的渐进式 JavaScript 框架。Vue 3 引入了许多新特性和改进,使得开发更加高效和灵活。以下是 Vue 3 组件的全面语法知识点以及一个详细的案例代码,带有详细注释,帮助初学者快速上手。
组件核心概念
- 单文件组件(SFC):
.vue文件,包含模板、脚本和样式 - 组件选项:
data,methods,computed,props,emits等 - 生命周期钩子:
onMounted,onUpdated,onUnmounted等 - 组合式API:
setup()函数,ref,reactive等 - 组件通信:
props向下传递,emits向上触发
一、Vue 3 组件语法知识点
1. 创建 Vue 应用
使用 createApp 方法创建一个新的 Vue 应用实例。
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
2. 组件基础
一个 Vue 组件通常由三个部分组成:模板(Template)、脚本(Script)和样式(Style)。
<template>
<div>{{ message }}</div>
</template>
<script>
export default {
data() {
return {
message: 'Hello, Vue 3!'
};
}
};
</script>
<style scoped>
div {
color: blue;
}
</style>
3. 使用组合式 API(Composition API)
组合式 API 提供了更灵活的逻辑复用方式,主要通过 setup 函数和 ref, reactive 等函数实现。
import { ref, reactive } from 'vue';
export default {
setup() {
const count = ref(0);
const state = reactive({ message: 'Hello' });
function increment() {
count.value++;
}
return {
count,
state,
increment
};
}
};
4. 生命周期钩子
Vue 3 提供了多个生命周期钩子,如 onMounted, onUpdated, onUnmounted 等,用于在组件的不同阶段执行代码。
import { onMounted, onUpdated, onUnmounted } from 'vue';
export default {
setup() {
onMounted(() => {
console.log('组件已挂载');
});
onUpdated(() => {
console.log('组件已更新');
});
onUnmounted(() => {
console.log('组件已卸载');
});
}
};
5. 组件通信
5.1 Props 和 Emits
通过 props 接收父组件传递的数据,通过 emits 触发自定义事件向父组件传递数据。
<!-- ChildComponent.vue -->
<template>
<button @click="notifyParent">点击我</button>
</template>
<script>
export default {
props: {
title: {
type: String,
required: true
}
},
emits: ['notify'],
methods: {
notifyParent() {
this.$emit('notify', '来自子组件的消息');
}
}
};
</script>
<!-- ParentComponent.vue -->
<template>
<ChildComponent :title="parentTitle" @notify="handleNotify" />
</template>
<script>
import ChildComponent from './ChildComponent.vue';
export default {
components: { ChildComponent },
data() {
return {
parentTitle: '父组件标题'
};
},
methods: {
handleNotify(message) {
console.log(message);
}
}
};
</script>
5.2 Provide 和 Inject
provide 和 inject 用于祖先组件向后代组件传递数据,而无需通过 props 逐层传递。
// AncestorComponent.vue
export default {
setup() {
const sharedData = ref('共享数据');
provide('shared', sharedData);
}
};
// DescendantComponent.vue
import { inject } from 'vue';
export default {
setup() {
const sharedData = inject('shared');
return { sharedData };
}
};
6. 插槽(Slots)
插槽允许在组件中插入任意模板内容。
<!-- MyButton.vue -->
<template>
<button class="my-button">
<slot></slot>
</button>
</template>
<style scoped>
.my-button {
padding: 10px 20px;
background-color: #42b983;
color: white;
border: none;
border-radius: 5px;
}
</style>
<!-- ParentComponent.vue -->
<template>
<MyButton>
<span>点击我</span>
</MyButton>
</template>
<script>
import MyButton from './MyButton.vue';
export default {
components: { MyButton }
};
</script>
7. Teleport 组件
Teleport 允许将组件的模板内容渲染到 DOM 结构中的其他位置。
<!-- TeleportComponent.vue -->
<template>
<button @click="showModal = true">打开模态框</button>
<Teleport to="body">
<div v-if="showModal" class="modal">
<p>这是一个模态框</p>
<button @click="showModal = false">关闭</button>
</div>
</Teleport>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const showModal = ref(false);
return { showModal };
}
};
</script>
<style scoped>
.modal {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
padding: 20px;
background-color: white;
border: 1px solid #ccc;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
}
</style>
8. 过渡与动画
Vue 3 提供了 <transition> 和 <transition-group> 组件,用于实现元素进入和离开的过渡效果。
<!-- TransitionComponent.vue -->
<template>
<button @click="show = !show">切换显示</button>
<transition name="fade">
<p v-if="show">Hello, Vue 3!</p>
</transition>
</template>
<script>
import { ref } from 'vue';
export default {
setup() {
const show = ref(true);
return { show };
}
};
</script>
<style scoped>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
.fade-enter-to, .fade-leave-from {
opacity: 1;
}
</style>
9. 自定义指令
可以通过自定义指令来扩展 Vue 的功能。
// focusDirective.js
export default {
mounted(el) {
el.focus();
}
};
<!-- 使用自定义指令 -->
<template>
<input v-focus />
</template>
<script>
import focusDirective from './focusDirective.js';
export default {
directives: {
focus: focusDirective
}
};
</script>
10. 插件
插件用于为 Vue 添加全局功能,如全局指令、混入等。
// myPlugin.js
export default {
install(app, options) {
app.directive('focus', {
mounted(el) {
el.focus();
}
});
app.mixin({
created() {
console.log('全局混入');
}
});
}
};
// main.js
import { createApp } from 'vue';
import App from './App.vue';
import myPlugin from './myPlugin.js';
const app = createApp(App);
app.use(myPlugin);
app.mount('#app');
二、案例代码
以下是一个简单的 Vue 3 应用示例,包含导航栏、主内容区和侧边栏组件,使用组合式 API 和组件通信实现。代码中包含详细注释,帮助理解每个部分的功能。
<!-- App.vue -->
<template>
<div id="app">
<Header :title="appTitle" @toggle-sidebar="toggleSidebar" />
<div class="container">
<Sidebar :isVisible="isSidebarVisible" @close="toggleSidebar" />
<MainContent />
</div>
</div>
</template>
<script>
import { ref } from 'vue';
import Header from './components/Header.vue';
import Sidebar from './components/Sidebar.vue';
import MainContent from './components/MainContent.vue';
export default {
name: 'App',
components: {
Header,
Sidebar,
MainContent
},
setup() {
const isSidebarVisible = ref(false);
const appTitle = '我的 Vue 3 应用';
function toggleSidebar() {
isSidebarVisible.value = !isSidebarVisible.value;
}
return {
isSidebarVisible,
appTitle,
toggleSidebar
};
}
};
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
text-align: center;
color: #2c3e50;
}
.container {
display: flex;
min-height: 100vh;
}
@media (max-width: 768px) {
.container {
flex-direction: column;
}
}
</style>
<!-- components/Header.vue -->
<template>
<header class="header">
<h1>{{ title }}</h1>
<button @click="emitToggle">侧边栏</button>
</header>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'Header',
props: {
title: {
type: String,
required: true
}
},
emits: ['toggle-sidebar'],
setup(props, { emit }) {
function emitToggle() {
emit('toggle-sidebar');
}
return {
emitToggle
};
}
};
</script>
<style scoped>
.header {
background-color: #42b983;
padding: 20px;
color: white;
display: flex;
justify-content: space-between;
align-items: center;
}
</style>
<!-- components/Sidebar.vue -->
<template>
<div v-if="isVisible" class="sidebar">
<h2>侧边栏</h2>
<ul>
<li><a href="#">首页</a></li>
<li><a href="#">关于</a></li>
<li><a href="#">联系</a></li>
</ul>
<button @click="close">关闭</button>
</div>
</template>
<script>
import { ref } from 'vue';
export default {
name: 'Sidebar',
props: {
isVisible: {
type: Boolean,
required: true
}
},
emits: ['close'],
setup(props, { emit }) {
function close() {
emit('close');
}
return {
close
};
}
};
</script>
<style scoped>
.sidebar {
background-color: #f4f4f4;
padding: 20px;
width: 200px;
border-right: 1px solid #ccc;
}
.sidebar ul {
list-style: none;
padding: 0;
}
.sidebar li {
margin: 10px 0;
}
.sidebar a {
text-decoration: none;
color: #2c3e50;
}
.sidebar button {
margin-top: 20px;
padding: 10px 15px;
background-color: #42b983;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
<!-- components/MainContent.vue -->
<template>
<main class="main-content">
<h1>欢迎来到我的 Vue 3 应用</h1>
<p>这是一个使用 Vue 3 构建的简单示例应用。</p>
</main>
</template>
<script>
export default {
name: 'MainContent'
};
</script>
<style scoped>
.main-content {
padding: 20px;
flex-grow: 1;
}
</style>
代码说明
-
App.vue:
- 使用组合式 API 管理侧边栏的显示状态。
- 通过
props将标题传递给Header组件,并通过emit触发toggle-sidebar事件。 - 使用
Sidebar组件并通过props控制其显示状态。 - 使用
MainContent组件显示主内容。
-
Header.vue:
- 显示应用标题和一个按钮,用于切换侧边栏的显示。
- 使用
emit触发toggle-sidebar事件,向父组件传递事件。
-
Sidebar.vue:
- 根据
isVisible状态显示或隐藏侧边栏。 - 显示侧边栏内容和关闭按钮,并通过
emit触发close事件,向父组件传递关闭事件。
- 根据
-
MainContent.vue:
- 显示主内容区域,包含一个标题和一段文本。
-
样式:
- 使用 scoped 样式,确保样式仅作用于当前组件。
- 使用 Flexbox 实现布局的响应式设计。
运行效果
该案例展示了一个简单的 Vue 3 应用,包含导航栏、主内容区和侧边栏。通过点击导航栏的按钮,可以显示或隐藏侧边栏。布局在不同屏幕尺寸下具有响应性,适应不同的设备。
三、总结
Vue 3 提供了丰富的组件语法和强大的功能,使得构建复杂的用户界面变得更加容易。通过掌握上述语法知识点,并结合实际案例进行练习,可以帮助初学者快速掌握 Vue 3 的使用方法。
更多推荐




所有评论(0)