最近在按照之前文章提到的母题理论整理前端开发知识点。个人觉得这样总结更加具有代表性,且具抽象性,具有一劳永逸的那种效果。首先整体截图
这种整体方式是超越UI组件概念层次的,是更大层次的抽象。且更符合实际的开发环境,能够和业务关联。下面具体介绍一下整理的一些介绍
何为母场景
在教育学中,母题是各门学科包含若干知识点的基本题、典型题,也是中高考命题所参照的原型题。最后这点原型题是重点。
母场景也是原型场景,可以演变出同类多个场景。每个人的母场景是不同的,这个是我整理的而已。
场景划分要求
不管是展示,交互还是反馈一定是dom实体:至少有html和css。
划分种类和原则
目前划分了4种母场景类型:
- 展示:下分为布局、数据展示和导航
- 交互:用户与页面元素交互的场景
- 反馈:交互之后的反馈场景
- 综合:以上三种方式的类型的综合
将导航划分到展示而不是交互,是因为分类的原则是看最优先哪个目的
。导航的第一目的就是展示数据,其次才是交互所以放在展示里。
又比如按钮首先也是展示,但按钮的第一目的是为了交互,所以放在交互分类。放在交互里的还有自制水平滚动条。还有input
和textarea
等。
整理原则
去实现核心那部分,实际开发为了符合业务要求,可以通过以下几种规则去演变实现。这里是基于Vue的逻辑进行的说明。
向内传入
- 占位slot
- 传值prop
- 外部属性$attrs
正宗的向内传入是prop
,其次slot
也是向内传入,而后$attrs
也是。
内部逻辑
- v-for
- v-if
- v-show
- v-model
- v-bind
- v-on
- v-text
- v-html
- watch
- computed
- class
- style
- methods
- transition
- data
- h渲染函数
- jsx
等。
内部逻辑很多:遍历、是否逻辑、绑定逻辑、监听逻辑watch、延长上下文computed、标签属性、动画、模板生成方式等。
作为一个对象存在
- $refs
$refs
是Vue组件的标记,可以获取到当前组件,进而拿到内部的属性和方法。
向外传递
- $emit
- 作用域插槽slotScope
向外:向外触发$emit
、向外传递变量slotScope
跨组件通信
- 事件总线
以上是分析组件或者分析框架的一种模型。
示例
项目当中的Link组件。直接用的是element-ui的源码。它的源码还是很具有代表性的。
js
<template>
<a
:class="[
'unit-link',
type ? `unit-link--${type}` : '',
disabled && 'is-disabled',
underline && !disabled && 'is-underline',
]"
:href="disabled ? null : href"
v-bind="$attrs"
@click="handleClick"
>
<i :class="icon" v-if="icon"></i>
<span class="unit-link--inner">
<slot>我是默认文字</slot>
</span>
<template v-if="$slots.icon"
><slot v-if="$slots.icon" name="icon"></slot
></template>
</a>
</template>
<script>
export default {
name: "Link 文字链接",
// 组件构造函数:传参包括props和slot和slotScope三部分
props: {
type: {
type: String,
default: "default",
},
underline: {
type: Boolean,
default: true,
},
disabled: Boolean,
href: String,
icon: String,
},
data(){
return {
}
},
methods: {
handleClick(event) {
if (!this.disabled) {
if (!this.href) {
this.$emit("click", event);
}
}
},
},
};
</script>
<style lang="scss" scoped>
.unit-link {
display: -webkit-inline-box;
display: -ms-inline-flexbox;
display: inline-flex;
-webkit-box-orient: horizontal;
-webkit-box-direction: normal;
-ms-flex-direction: row;
flex-direction: row;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
vertical-align: middle;
position: relative;
text-decoration: none;
outline: 0;
cursor: pointer;
padding: 0;
font-size: 14px;
font-weight: 500;
}
.unit-link.is-underline:hover:after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 0;
bottom: 0;
border-bottom: 1px solid #409eff;
}
.unit-link.unit-link--default:after,
.unit-link.unit-link--primary.is-underline:hover:after,
.unit-link.unit-link--primary:after {
border-color: #409eff;
}
.unit-link.is-disabled {
cursor: not-allowed;
}
.unit-link [class*="unit-icon-"] + span {
margin-left: 5px;
}
.unit-link.unit-link--default {
color: #606266;
}
.unit-link.unit-link--default:hover {
color: #409eff;
}
.unit-link.unit-link--default.is-disabled {
color: #c0c4cc;
}
.unit-link.unit-link--primary {
color: #409eff;
}
.unit-link.unit-link--primary:hover {
color: #66b1ff;
}
.unit-link.unit-link--primary.is-disabled {
color: #a0cfff;
}
.unit-link.unit-link--danger.is-underline:hover:after,
.unit-link.unit-link--danger:after {
border-color: #f56c6c;
}
.unit-link.unit-link--danger {
color: #f56c6c;
}
.unit-link.unit-link--danger:hover {
color: #f78989;
}
.unit-link.unit-link--danger.is-disabled {
color: #fab6b6;
}
.unit-link.unit-link--success.is-underline:hover:after,
.unit-link.unit-link--success:after {
border-color: #67c23a;
}
.unit-link.unit-link--success {
color: #67c23a;
}
.unit-link.unit-link--success:hover {
color: #85ce61;
}
.unit-link.unit-link--success.is-disabled {
color: #b3e19d;
}
.unit-link.unit-link--warning.is-underline:hover:after,
.unit-link.unit-link--warning:after {
border-color: #e6a23c;
}
.unit-link.unit-link--warning {
color: #e6a23c;
}
.unit-link.unit-link--warning:hover {
color: #ebb563;
}
.unit-link.unit-link--warning.is-disabled {
color: #f3d19e;
}
.unit-link.unit-link--info.is-underline:hover:after,
.unit-link.unit-link--info:after {
border-color: #909399;
}
.unit-link.unit-link--info {
color: #909399;
}
.unit-link.unit-link--info:hover {
color: #a6a9ad;
}
.unit-link.unit-link--info.is-disabled {
color: #c8c9cc;
}
</style>
项目代码
项目还在更新迭代中。除了参考element-ui源码,还会参考其他的,包括日常开发遇到的。
(本文完)