来自:掘金,作者:Huup_We
链接:https://juejin.cn/post/6917771825808146446
场景
前端开发的同学可能会遇到过这样的问题: 产品找那个需要实现某项功能,常用的elementui,antd组件库中确实有差不多功能的组件 但实际上这些组件可能并不能满足你的功能,或多或少都需要修改才能满足需求
关于组件库可能要修改的地方,我将它们分为以下五类可供参考
- 样式问题
- 组件暴露的参数和方法不充分 但是源码中存在
- 可利用部分功能 但其余功能需要自己开发封装
- 两个及以上的组件之间有联动
- 完全没有符合的组件
分析和解决
组件样式问题
当修改单个文件的样式时,以 less 为例,如果你想要修改组件的样式,可以使用 /deep/ 或 >>> 来深度选择到你要修改的样式(这能够帮你省去一大串的类名)
.dialog-wrapper {
/deep/.el-dialog__body{
border: solid 1px #999;
}
}
如果你要修改全局的样式,第一种方法,你可以在全局样式文件中写样式覆盖,引入到 main.js 中即可全局生效。如下
import "./assets/css/index.css";
如果是修改antd 可以使用:global(.className)的语法去修改组件库的样式
.wrap {
:global(.ant-modal-body) {
padding-top: 0;
& > div {
margin: 0 -24px;
max-height: 680px !important;
}
}
}
组件库的组件暴露的参数和方法不充分
当我们想要获取组件的一个参数,首先是看文档中提供了哪些 Attributes、Events、Methods。如果符合需求,直接拿来用就好。如果没有你要的属性和方法,请你先去看看源码中提供了哪些东西没有向外暴露出来的,但是我们能拿来用的
以elementui的cascader级联选择器举例,我想要在选中一个搜索的选项后不关闭看板。我在组件的 Events、Methods中没有找到相关的方法控制看板展开,但当我去 github 上看该组件的源码时,我发现 toggleDropDownVisible() 方法是控制看板展开的。于是我在外部用 $refs 直接调用组件里的这个方法就好了
el-cascader
ref="cascader" // ref获取组件
placeholder="试试搜索:指南"
:options="options"
:props="{ multiple: true }"
filterable></el-cascader
@visible-change="$refs.cascader.toggleDropDownVisible(true)"> // 调用组件及其方法
可利用部分功能,其余功能要自己开发封装
当要用到一个组件,但从头开发这个组件既复杂又耗时,而组件库中这个组件需要再往上加一些功能就能为你所用时,你可以考虑把组件库的代码拿到自己本地,修改它
两个及以上的组件之间的联动
其实场景有很多,例如将「Form 表单」、「Table 表格」和「Pagination 分页」结合起来,封装成一个组件,这样在多表格的项目中直接使用就好了;将 table 和 pagination 放到一个组件中:
<template lang="pug">
div
.el-table
template(v-for="(item, index) in columns")
el-table-column(
:prop="item.prop"
:key="index"
:label="item.label")
el-pagination.pg-wrapper(
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[10, 20, 50, 100]"
:page-size="pagesize"
:total="total")
</template>
需要传入的参数如下:列信息 columns、单页数据量 pagesize、当前页码 currentPage、表格数据 tableData、数据总数 total、表单查询的参数 query 等
props: {
// 列信息
columns: {
type: Array,
default: [],
}
// 单页数据量
pagesize: {
type: Number,
default: 10,
},
// 当前页码
currentPage: {
type: Number,
default: 1,
},
// 表格数据
tableData: {
type: Array,
default: [],
},
// 数据总数
total: {
type: Number,
default: 1000,
},
// 获取数据的接口
fetch:{
type: function,
default:() => {}
},
// 表单查询的参数
query:{
type: Object,
default: () => {}
}
},
methods: {
// 改变当前页码 currentPage 时触发
handleCurrentChange: function (currentPage) {
this.$emit('handleChange', this.pagesize, currentPage)
this.fetch(this.query)
},
// 改变当前页 pageSize 时触发
handleSizeChange: function (pageSize) {
this.$emit('handleChange', pageSize, this.currentPage)
this.fetch(this.query)
}
}
完全没有符合的组件
如果你要的组件,外部的组件库中都没有提供,那就自己动手封装一个。尽可能将你的组件变得通用,兼容。尝试想一想你的组件是否在其他情况下也能用。另外也可以多看看别人是如何封装组件的,这有助于你自己开发。
如果你可以将你在前端开发道路上自己封装的组件一个个收集起来,大概率可以方便你以后相同场景下直接复用,也有助于你的代码解耦