Vue 组件化开发全攻略:从基础到进阶实战
·
Vue组件化开发全攻略:从基础到进阶实战
本文系统讲解Vue组件化开发的核心技术,涵盖组件通信、动态组件、插槽等实用特性,并提供可直接运行的代码示例。
一、组件基础:全局与局部组件
全局组件(可在任意位置使用)
Vue.component('navbar', {
template: `
<div class="navbar">
<button>后退</button>
<h3>导航栏组件</h3>
<button>前进</button>
</div>
`,
data() {
return { myAge: 25 }
}
})
局部组件(仅在当前Vue实例中使用)
new Vue({
el: '#app',
components: {
local: {
template: `
<div class="local-comp">
<h3>局部组件</h3>
</div>
`
}
}
})
二、组件通信三大核心方式
1. 父传子(Props)
<!-- 父组件 -->
<navbar :my-name="name"></navbar>
<!-- 子组件 -->
<script>
Vue.component('navbar', {
props: ['myName'], // 接收父组件数据
template: `<p>接收的名字: {{ myName }}</p>`
})
</script>
2. 子传父(自定义事件)
<!-- 父组件 -->
<navbar @getage="handleAge"></navbar>
<!-- 子组件 -->
<script>
Vue.component('navbar', {
methods: {
sendAge() {
this.$emit('getage', this.myAge) // 触发事件
}
}
})
</script>
3. Ref获取组件实例
<navbar ref="mynavbar"></navbar>
<button @click="getChildData">获取子组件数据</button>
<script>
new Vue({
methods: {
getChildData() {
// 访问子组件数据
console.log(this.$refs.mynavbar.myAge)
}
}
})
</script>
三、动态组件与状态保持
基础实现
<button @click="currentView = 'home'">首页</button>
<button @click="currentView = 'goods'">商品</button>
<component :is="currentView"></component>
<script>
Vue.component('home', { template: '<h3>首页组件</h3>' })
Vue.component('goods', { template: '<h3>商品组件</h3>' })
new Vue({
data: {
currentView: 'home'
}
})
</script>
使用keep-alive保持状态
<keep-alive>
<component :is="currentView"></component>
</keep-alive>
应用场景:表单填写、多步骤操作等需要保存状态的场景
四、插槽:内容分发机制
1. 默认插槽
<!-- 组件定义 -->
<template>
<div class="card">
<h3>卡片标题</h3>
<slot></slot> <!-- 内容分发位置 -->
</div>
</template>
<!-- 使用组件 -->
<my-card>
<p>这是插入的内容</p>
</my-card>
2. 具名插槽
<!-- 组件定义 -->
<template>
<div class="layout">
<header><slot name="header"></slot></header>
<main><slot name="body"></slot></main>
<footer><slot name="footer"></slot></footer>
</div>
</template>
<!-- 使用组件 -->
<my-layout>
<template v-slot:header>
<h2>页面标题</h2>
</template>
<template v-slot:body>
<p>主要内容区域</p>
</template>
</my-layout>
五、组件通信高级场景
1. 非父子组件通信
// 事件总线模式
const bus = new Vue()
// 组件A发送事件
bus.$emit('data-update', newData)
// 组件B接收事件
bus.$on('data-update', data => {
console.log('收到数据:', data)
})
2. Provide/Inject(跨层级通信)
// 祖先组件
export default {
provide() {
return {
appContext: this // 提供整个实例
}
}
}
// 后代组件
export default {
inject: ['appContext'],
mounted() {
console.log(this.appContext.someData)
}
}
六、组件设计最佳实践
-
命名规范:
// 推荐 components/ ├── BaseButton.vue ├── AppHeader.vue └── UserProfile.vue -
Props验证:
props: { userData: { type: Object, required: true, validator: value => value.id && value.name } } -
单向数据流:
- 父组件通过props传递数据
- 子组件通过事件通知变化
- 避免直接修改props
-
作用域插槽:
<!-- 组件 --> <template> <ul> <li v-for="item in items"> <slot :item="item"></slot> </li> </ul> </template> <!-- 使用 --> <my-list :items="users"> <template v-slot:default="slotProps"> {{ slotProps.item.name }} - {{ slotProps.item.age }} </template> </my-list>
七、实战案例:可复用的模态框组件
<!-- Modal.vue -->
<template>
<div class="modal" v-show="visible">
<div class="modal-header">
<slot name="header">
<h3>默认标题</h3>
</slot>
</div>
<div class="modal-body">
<slot></slot>
</div>
<div class="modal-footer">
<slot name="footer">
<button @click="close">关闭</button>
</slot>
</div>
</div>
</template>
<script>
export default {
props: {
visible: Boolean
},
methods: {
close() {
this.$emit('close')
}
}
}
</script>
<!-- 使用示例 -->
<modal :visible="showModal" @close="showModal = false">
<template #header>
<h3>自定义标题</h3>
</template>
<p>这是模态框内容...</p>
<template #footer>
<button @click="submit">提交</button>
<button @click="showModal = false">取消</button>
</template>
</modal>
更多推荐
所有评论(0)