vue怎么实现封装组件
封装 Vue 组件的方法
创建组件文件
在 Vue 项目中,通常将组件放在 components 文件夹中。创建一个 .vue 文件,例如 MyComponent.vue,包含模板、脚本和样式三部分。
<template>
<div class="my-component">
<button @click="handleClick">{{ buttonText }}</button>
</div>
</template>
<script>
export default {
name: 'MyComponent',
props: {
buttonText: {
type: String,
default: 'Click Me'
}
},
methods: {
handleClick() {
this.$emit('button-clicked');
}
}
};
</script>
<style scoped>
.my-component {
margin: 10px;
}
</style>
定义 Props 接收参数
通过 props 接收父组件传递的数据,可以指定类型和默认值。例如接收 buttonText 参数并设置默认值。
使用 $emit 触发事件
在子组件中通过 this.$emit('event-name') 触发自定义事件,父组件可以通过 @event-name 监听并处理。
在父组件中使用
导入并注册组件后,通过标签形式使用,传递 props 或监听事件。
<template>
<div>
<MyComponent
button-text="Submit"
@button-clicked="handleButtonClick"
/>
</div>
</template>
<script>
import MyComponent from '@/components/MyComponent.vue';
export default {
components: {
MyComponent
},
methods: {
handleButtonClick() {
console.log('Button clicked in parent');
}
}
};
</script>
使用插槽(Slots)
通过 <slot> 实现内容分发,允许父组件向子组件插入内容。
<!-- 子组件 -->
<template>
<div class="card">
<slot></slot>
</div>
</template>
<!-- 父组件 -->
<template>
<MyCard>
<p>This content is slotted into the card.</p>
</MyCard>
</template>
作用域插槽
通过作用域插槽实现子组件向父组件传递数据。
<!-- 子组件 -->
<template>
<div>
<slot :item="itemData"></slot>
</div>
</template>
<!-- 父组件 -->
<template>
<MyComponent>
<template v-slot:default="slotProps">
<p>{{ slotProps.item }}</p>
</template>
</MyComponent>
</template>
通过 provide/inject 跨层级传递数据
在祖先组件中使用 provide 提供数据,后代组件通过 inject 注入使用。
// 祖先组件
export default {
provide() {
return {
theme: 'dark'
};
}
};
// 后代组件
export default {
inject: ['theme'],
created() {
console.log(this.theme); // 输出 'dark'
}
};
使用 mixins 复用逻辑
通过 mixins 将公共逻辑混入多个组件。
const myMixin = {
methods: {
logMessage(message) {
console.log(message);
}
}
};
export default {
mixins: [myMixin],
created() {
this.logMessage('Component created');
}
};
通过 $attrs 和 $listeners 传递属性和事件
使用 v-bind="$attrs" 和 v-on="$listeners" 实现属性和事件的透传。
<template>
<child-component v-bind="$attrs" v-on="$listeners"></child-component>
</template>






