在前端组件设计之理论篇中已经对前端组件设计的原则进行了介绍,本文将在实际开发过程中使用这些原则,根据自己学习理解后总结出来的组件开发的步骤进行开发实战。
前端组件设计系列:
前端组件设计之理论篇前端组件设计之实践篇 一、组件开发流程/步骤 1、确定组件的功能;2、确定组件接收的数据;3、确定组件自身维护的状态;4、确定组件的 *** 作功能;5、确定组件输出的数据;亲身实践标明,根据上述的5个步骤进行开发,能够有效的规避很多不必要的坑,同时使开发的组件更加“健康”;
接下来我将以开发一个Tree组件为例,进行实践的应用和讲解;
技术栈:Vue
二、组件解析本实例实现 Tree树形组件 并非涵盖所有能力(排序、选择···),主要是通过 前端组件化 实践让读者能够熟悉组件开发中的原则和步骤。
按照『组件开发流程』对组件进行解析,方便后续代码层面的开发;
1、确定组件的功能分析Tree树形组件应该具有以下两个核心功能:
1)展示树状数据;2)父节点展开/折叠; 2、确定组件接收的数据;组件接收的数据通常用Props表示,数据本身只用于数据的展示,所以组件内部不应该改变传入的数据本身,需要遵循数据的单向传递**的原则。
展示数据:
以每个节点进行分析,节点属性:节点名称(title)、节点唯一标识(key),节点的子节点数据(children);
treeData = [ { title: '0-0', key: 1, children: [ { title: '0-0-0', key: 2, children: [ { title: '0-0-0-0', key: 3 }, { title: '0-0-0-1', key: 4 }, { title: '0-0-0-2', key: 5 }, ··· ], }, ··· ], }, ··· ];
默认展开的节点:
3、确定组件自身维护的状态初始加载组件时,控制哪些父节点默认呈展开状态,数据为一个数组,数组中元素为节点唯一标识(key)
expandedKeys = [1, 2, 3,···]
组件自身状态可以用States表示,其用来维护组件自身的状态变化,也就是说组件状态的维护应该在组件内部,与组件外部传入什么数据、怎么使用组件没有丝毫关系。例如,点击父节点是否展开和折叠其子节点树的状态是组件本身就具有的,无论你传入的数据内容如何不同,都不会影响这个能力。
通过组件功能可以确定组件自身有以下状态:
每个节点的否展开和折叠状态(isFold); 4、确定组件的 *** 作功能组件的 *** 作功能可以使用Methods表示,一般都需要依托以数据和状态,例如Tree树形组件中点击节点(onClick),打开或者折叠其子节点,是对组件自身状态的改变。
5、确定组件输出的数据组件的输出可以用Emit表示,本质是组件向父组件进行通信。
首先,Tree树形组件更偏向于数据展示类组件,有别于按钮、输入等数据 *** 作类组件;
数据展示类组件
一般只会对传入的数据做展示,或者更改数据的展示形式;
数据 *** 作类组件
除了有数据展示的能力外,一般都具有主动向引用组件的父组件输出数据的能力,比如输入框能将输入的数据回传给父组件,按钮组件能够通知父组件执行某些callback *** 作等。
首先看看最终实现效果:
根据『组件解析』可以画出组件UML图,如下:
代码实现 index组件引入的父组件,如下图所示:传入树形组件展示数据treeData
、默认展开的父节点expandedKeys
在设计中,Tree.vue组件维护组件自身的状态,即每个节点的展开和折叠状态isFlod
,同时对数据进行传入参数Props
处理,生成结合了组件自身状态的用于渲染的数据。
组件代码如下:
在设计中,Tree.vue
只会对当层的数据进行处理,然后对处理的数据进行渲染,父节点中的子节点数据处理让子节点自己执行,这也算是单一职责
的一种体现;
setCurrentRenderData
函数:遍历传入的树形组件展示数据的当层数据,确定当层中每个节点的状态isFold
,最后返回一个全新的渲染数据renderData
,该数据用于当层节点的渲染, *** 作renderData
并不会对Props
数据产生影响,保证了数据单向传递
的原则。
组件的自我调用。为了让组件自己能够调用自己,我们给予组件一个确定的名称name:'tree-node'
,然后组件就可以通过
方式调用自己本身了;
通过组件自身状态isFold
对组件展示样式和 *** 作进行控制, *** 作只会改变自身状态,不会对传入参数进行修改;
<div
:class="node.isFold ? 'node-item node-color' : 'node-item'"
@click="() => node.isFold = !node.isFold"
>{{ node.title }}
div>
无论是在引用组件index.vue
中,还是在Tree.vue
自身调用,组件都保持了一致性,这个一致性体现在传参的一致。从侧面也是对于封装
原则的实践:
// index.vue
import TreeVue from './component/Tree.vue';
<tree-vue
:tree-data="treeData"
:expanded-keys="[1, 6]"
/>
// Tree.vue
<div v-show="node.isFold">
<tree-node
:tree-data="node.children"
:expanded-keys="expandedKeys"
/>
div>
···
export default defineComponent({
name: 'tree-node',
···
})
无论是组件名称、还是变量名、函数名,基本上都遵循着富有意义
原则,让代码一目了然、清晰易懂;
上述代码只是对『树形组件』的简单实现,一个完整的『树形组件』也并非上面呈现的那么简单,主要目的并不是写一个组件,而是通过组件的开发让大家能够理解 前端组件化设计和开发的原则和细节。
同时也让大家熟悉一些组件化开发的方法和思想,比如开发前的组件分析、组件的UML结构设计等,看完本篇文章希望都能有所收获!
参考 [译] 前端组件设计原则欢迎分享,转载请注明来源:内存溢出
评论列表(0条)