前言
我最近想要封装一个组件库,所以准备来从0开始学习怎样设计和封装组件的时候应该思考什么。
也是为我以后的校招做准备吧!!!
封装组件的一些思考
从四个方面进行思考
- 样式的思考
- template的思考:Slot还是组件里写好
- 行为的思考:父组件定义还是子组件定义
- props的思考:哪些东西可以作为props,哪些东西作为组件自身的东西。
接下来从这四个方面来进行讨论。
样式
从三个方面进行思考
- 容器的基本样式(你想要这个组件呈现的基本样式),内部内容的基本样式
- 尽量使用低权值
- 定义一些内置类(这样使用者可以通过你写的文档来进行使用这些提前定义好的来修改样式)
Search.vue
<script lang="ts">
</script>
<template>
<div class="btn">
<slot></slot>
<label for="" class="name">名字:</label>
<input type="text"/>
<button>重置</button>
<button>搜索</button>
</div>
</template>
<style lang="scss" scoped>
.btn{
display: flex;
}
//权重要低,为了防止外面引用这个组件的时候样式因为权重问题而修改不了而被迫使用important.
.name{
margin-right:10px;
}
//根据不同的需求定义的一些类型
.mini-type{
width:20px;
height: 10px;
}
.middle-type{
width: 50px;
height: 10px;
}
</style>
<script lang="ts">
import Search from './search.vue'
</script>
<template>
<div>
<Search>
<label>名字</label>
<input type="text" class="mini-type">
</Search>
</div>
</template>
<style lang="scss" scoped>
</style>
template
- 内容该有的就写死,不确定的通过slot传入
- 还可以判断有没有slot,没有写一个默认内容
<script lang="ts">
</script>
<template>
<div class="btn">
<slot></slot>
<div v-if="!('default' in $slots)">
<label for="">名字:</label>
<input type="text"/>
</div>
<button>重置</button>
<button>搜索</button>
</div>
</template>
<style lang="scss" scoped>
.btn{
display: flex;
}
.mini-type{
width:20px;
height: 10px;
}
.middle-type{
width: 50px;
height: 10px;
}
</style>
行为
- 基本部分和业务部分,建议每一个行为都留给父组件监听
- 为了更好的拓展可以拆分某一个行为的前后中几个周期
基本的部分就是这个组件它产生出来就是因为它身上有着自己的特性,业务部分就是具体的你使用这个组件干了一些事,解决了一些问题。
<script lang="ts">
import Search from './search.vue'
const getImage = ()=>{
console.log(123);
}
const beforeSearch = ()=>{}
const afterSearch = () =>{
}
</script>
<template>
<div>
<Search @search="getImage" @beforeSearch="beforeSearch" @afterSearch="afterSearch">
<label>名字</label>
<input type="text" class="mini-type">
</Search>
</div>
</template>
<style lang="scss" scoped>
</style>
<script lang="ts">
//添加监听事件
const emit = defineEmits(['search','beforeSearch','afterSearch'])
const search = ()=>{
//最好添加上这个事件的周期
emit('beforeSearch')
emit('search')
emit('afterSearch')
}
</script>
<template>
<div class="btn">
<slot></slot>
<div v-if="!('default' in $slots)">
<label for="">名字:</label>
<input type="text" @change="search"/>
</div>
<button>重置</button>
<button>搜索</button>
</div>
</template>
<style lang="scss" scoped>
.btn{
display: flex;
}
.mini-type{
width:20px;
height: 10px;
}
.middle-type{
width: 50px;
height: 10px;
}
</style>
props
- 组件前端的一些行为(样式数据)在数据内部定义,业务相关数据父组件传入
- props也是一个组件拓展的接口。