Vue.js 组件开发
Vue.js 的核心思想之一就是组件化。组件化允许我们将 UI 划分为独立、可复用的部分,每个部分都有自己的逻辑和视图。
1. 单文件组件 (Single-File Components)
Vue.js 推荐使用单文件组件(SFC,文件扩展名为 .vue
)来定义组件。一个 .vue
文件通常包含三个部分:<template>
、<script>
和 <style>
。
示例 (Greeting.vue
):
<template>
<div class="greeting">
<p>{{ message }}</p>
</div>
</template>
<script>
export default {
name: "Greeting",
data() {
return {
message: "你好, Vue!",
};
},
};
</script>
<style scoped>
.greeting {
color: green;
font-family: sans-serif;
}
</style>
2. Props:父组件向子组件传递数据
Props 是你可以在组件上注册的一些自定义 attribute。当一个值传递给一个 prop attribute 的时候,它就变成了那个组件实例的一个属性。
父组件 (App.vue
):
<template>
<div id="app">
<UserProfile name="张三" :age="30" />
</div>
</template>
<script>
import UserProfile from "./components/UserProfile.vue";
export default {
components: {
UserProfile,
},
};
</script>
子组件 (UserProfile.vue
):
<template>
<div>
<p>姓名: {{ name }}</p>
<p>年龄: {{ age }}</p>
</div>
</template>
<script>
export default {
name: "UserProfile",
props: {
name: String,
age: {
type: Number,
required: true,
},
},
};
</script>
3. Events ($emit
):子组件向父组件通信
子组件可以通过 $emit
方法触发一个事件,并携带数据。父组件可以通过 v-on
(或 @
) 来监听这些事件。
子组件 (ButtonCounter.vue
):
<template>
<button @click="incrementCounter">点击了 {{ count }} 次</button>
</template>
<script>
export default {
name: "ButtonCounter",
data() {
return { count: 0 };
},
methods: {
incrementCounter() {
this.count++;
this.$emit("increment", this.count); // 触发事件,并传递count值
},
},
};
</script>
父组件 (App.vue
):
<template>
<div id="app">
<ButtonCounter @increment="handleIncrement" />
<p>父组件记录的总数: {{ totalClicks }}</p>
</div>
</template>
<script>
import ButtonCounter from "./components/ButtonCounter.vue";
export default {
components: { ButtonCounter },
data() {
return { totalClicks: 0 };
},
methods: {
handleIncrement(newCount) {
this.totalClicks = newCount;
},
},
};
</script>
4. Slots:内容分发
Slot(插槽)用于分发内容。它允许父组件向子组件的模板中注入内容。
子组件 (Card.vue
):
<template>
<div class="card">
<div class="card-header">
<slot name="header">默认标题</slot>
</div>
<div class="card-body">
<slot>默认内容</slot>
</div>
</div>
</template>
<style scoped>
.card {
border: 1px solid #ccc;
border-radius: 4px;
margin: 10px;
}
.card-header {
background: #f0f0f0;
padding: 10px;
}
.card-body {
padding: 10px;
}
</style>
父组件 (App.vue
):
<template>
<Card>
<template v-slot:header>
<h3>自定义标题</h3>
</template>
<p>这是卡片的主要内容。</p>
<p>可以包含任何 HTML。</p>
</Card>
</template>
<script>
import Card from "./components/Card.vue";
export default { components: { Card } };
</script>
5. 组件生命周期
每个 Vue 组件实例在创建时都需要经历一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。
常用的钩子包括:
created
: 实例创建完成后调用。mounted
: 实例挂载到 DOM 后调用。updated
: 数据更新导致虚拟 DOM 重新渲染和打补丁后调用。unmounted
: 实例卸载后调用。