This is the 10th day of my participation in the August More Text Challenge

0 x00 profile

The Divider component is used to divide the content. This article will be an in-depth analysis of component source code, analysis of its implementation principle, patience to read, I believe will help you. Packages/divider/SRC/main. Vue file is component source code to achieve. 🔗 component document Divider 🔗 Github source main.vue

For more component profiling see 👉 📚 Element 2 source profiling Component Overview.


0x01 Component source code

Component Divider/SRC /main.vue Single-file Components (SFC), which defines template-based functional components.

<template functional>
    // ...
</template>
<script>
export default {
  name: 'ElDivider'.props: {
    // ...}};</script>
Copy the code

The attributes property

The component defines two prop: Direction and contentPosition

direction

Horizontal is the default value, horizontal/vertical is the optional value. A validator is defined for verification. Generates an invalid style el-Divider –${direction} if other values are passed.

direction: {
  type: String.default: 'horizontal'.validator(val) {
    return ['horizontal'.'vertical'].indexOf(val) ! = = -1; }},Copy the code

contentPosition

Sets the location of the splitter copy, default center, optional left/right/center, and defines a validator for validation. Invalid style is-${props. ContentPosition} if other values are passed.

contentPosition: {
  type: String.default: 'center'.validator(val) {
    return ['left'.'center'.'right'].indexOf(val) ! = = -1; }}Copy the code

Template Template content

The component creates a

element node that draws the dividing line. This node contains one child

with built-in slots for custom splitter copywriting. Child nodes are rendered only if the component is sectioned horizontally and provides slot content for custom sectioned copywriting.

  <div
    v-bind="data.attrs"
    v-on="listeners"
    :class="[data.staticClass, 'el-divider', `el-divider--${props.direction}`]"
  >
    <div
      v-if="slots().default && props.direction ! == 'vertical'"
      :class="['el-divider__text', `is-${props.contentPosition}`]"
     >
      <slot />
    </div>
  </div>
Copy the code

Before taking a closer look at components, let’s take a closer look at functional components.

The functional component Context

Everything a functional component needs is passed through the context parameter, which uses some of its properties in the component:

  • props: Provides objects for all prop
  • slots: a function that returns an object containing all slots
  • data: The entire data object passed to the component
  • listeners: an object that contains all event listeners registered by the parent component for the current component. This is adata.onAn alias for “.

See the official documentation for the other attributes parent, children, scopedSlots, and Injections.

The context interface defines @2.6 source code types/options.d.ts#L136

export interface RenderContext<Props=DefaultProps> {
  props: Props;
  children: VNode[];
  slots(): any;
  data: VNodeData;
  parent: Vue;
  listeners: { [key: string]: Function | Function[]}. scopedSlots: { [key: string]: ScopedSlot }; injections: any }Copy the code

The data object data type is VNodeData Official document.

VNodeData interface definition @2.6 source flow/vnode.js#L35.

class Vs staticClass

The difference in interface declarations is that staticClass can only be a string. Class supports all other formats, such as objects or arrays.

declare interface VNodeData {
  // ...staticClass? : string;class? :any;
  // ...
};
Copy the code

The following uses vue.compile to compile template strings in real time.

Vue.js is specifically enhanced when the directive V-bind is used for class. The result of an expression can be an object or an array in addition to a string.

<div :class="['element','active']"></div> 
Copy the code

Render the content output class

function anonymous(
) {
  with(this){return _c('div', {class: ['element'.'active']})}}Copy the code

When the class string contents are defined without the instruction V-bind.

<div class="active"></div> 
Copy the code

Compile the content to output the staticClass

function anonymous(
) {
  with(this){return _c('div', {staticClass:"active"}}})Copy the code

Component functions

The component creates a

element parent that draws a dividing line through the background color. El-divider defines the background color of the elements. The el-Divider –horizontal or el-Divider –vertical defines the width and height of the elements to divide them horizontally and vertically

A template-based functional component whose independent context content can be accessed through context. V-bind =”data.attrs” passes any HTML attribute using data.attrs; V-on =” Listeners “use listeners (alias for data.on) to pass any event listeners.

:class=”[data. StaticClass, ‘el-Divider ‘,’ el-Divider –${props. Direction}’]” Then merge the static and dynamically generated classes.

The component contains 1 child

, and only the component is sectioned horizontally (props. Direction! == ‘vertical’) and provide the contents of slots(slots.default). Generate a copy position style based on contentPosition, IS-left, IS-Right, or IS-Center.

0x02 Component Style

src/divider.scss

SCSS uses mixed instructions B, m, e, when to generate component styles.

/ / generated. El - divider
@include b(divider) {
  // ...
  / / generated. El - divider -- -- horizontal
  @include m(horizontal) {
    // ...
  }
  / / generated. El - divider -- -- vertical
  @include m(vertical) {
    // ...
  }
  / / generated. El - divider__text
  @include e(text) {
    // ...
    / / generated. El - divider__text. Is to the left
    @include when(left) {
      // ...
    }
    / / generated. El - divider__text. Is - center
    @include when(center)  {
      // ...
    }
    / / generated. El - divider__text. Is right
    @include when(right)  {
      // ...}}}Copy the code

lib/divider.scss

Gulpfile. js is used to compile the SCSS file and convert it to CSS. After browser compatibility and format compression, packages\theme-chalk\lib\divider. SCSS is generated.

.el-divider{/ /... }.el-divider--horizontal{/ /... }.el-divider--vertical{/ /... }.el-divider__text{/ /... }.el-divider__text.is-left{/ /... }.el-divider__text.is-center{/ /... }.el-divider__text.is-right{/ /... }Copy the code

0 x03 📚 reference

Vm-attrs,vuejs.org vm-listeners,vuejs.org functional components,vuejs.org class vs StaticClass, StackOverflow

0x04 Attention column

This article has been included in the column 👇, you can directly follow.