This is the 9th day of my participation in the August More Text Challenge
0 x00 profile
Component tags are mostly used for marking and sorting. 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 /tag/ SRC /tag.vue files are component source implementations. 🔗 Component documentation Tag 🔗 Github source Tag. Vue
For more component profiling see 👉 📚 Element 2 source profiling Component Overview.
0x01 Component source code
Use the render function to create the component with the following code structure 👇.
<script>
export default {
name: 'ElTag'./ / component prop
props: {
// ...
},
methods: {
// The event triggered when the Tag is closed
handleClose(event) {
// ...
},
// The event triggered when a Tag is clicked
handleClick(event) {
// ...}},// Calculate attributes
computed: {
// Label size
tagSize() {
// ...}},// Render the tag virtual DOM
render(h) {
// ...}}; </script>Copy the code
The attributes property
The component defines eight prop.
props: {
text: String.// is not used in the code
closable: Boolean.// Can be closed
type: String./ / type
hit: Boolean.// Whether there is a border stroke
disableTransitions: Boolean.// Whether to disable gradient animation
color: String./ / the background color
size: String./ / size
/ / theme
effect: {
type: String.default: 'light'.validator(val) {
return ['dark'.'light'.'plain'].indexOf(val) ! = = -1; }}},Copy the code
Prop is described in detail as follows (there are only 7) :
parameter | instructions | type | An optional value | The default value |
---|---|---|---|---|
type | type | string | success/info/warning/danger | – |
closable | Whether it can be closed | boolean | – | false |
disable-transitions | Whether to disable gradient animation | boolean | – | false |
hit | Whether there is a border stroke | boolean | – | false |
color | The background color | string | – | – |
size | size | string | medium / small / mini | – |
effect | The theme | string | dark / light / plain | light |
Text is defined in prop but is not used in the code. If the values of type, size, and effect do not match the specified string, an invalid class is generated based on the values (the style rule is not defined).
Calculate attribute
TagSize dynamically calculates the tagSize based on size and $ELEMENT.
If the component defines prop size, the tagSize value is the value defined by size. If size is undefined and “”, the tagSize value is determined by the global $ELEMENT configuration.
If the $ELEMENT object is not empty and contains the size attribute, the tagSize value is the object’s attribute value $element.size. Otherwise, the tagSize value is undefined,
// Label size
tagSize() {
return this.size || (this.$ELEMENT || {}).size;
}
Copy the code
As you know, the $ELEMENT global configuration is defined in the install method in the component entry file. Where the default size value for the component is “”.
// SRC /index.js component entry file
const install = function(Vue, opts = {}) {
// ...
// The default size of the global configuration component size the initial z-index of the popbox
Vue.prototype.$ELEMENT = {
size: opts.size || ' '.zIndex: opts.zIndex || 2000
};
// ...
};
Copy the code
When a component is fully imported and registered with vue.use(), the install method is executed and the global attribute $ELEMENT is declared.
import Element from 'element-ui';
Vue.use(Element);
// Manually set the default size of the component
Vue.use(Element, {
size: "small"});Copy the code
Prototype $ELEMENT = {size: ‘small’, zIndex: 3000}; If $ELEMENT is not defined, Uncaught ReferenceError will be raised if $ELEMENT is not defined.
import { Tag } from 'element-ui'
// Global configuration
Vue.prototype.$ELEMENT = { size: 'small'.zIndex: 3000 };
// Import components
Vue.use(Tag);
Copy the code
Expressions (enclosing $ELEMENT | | {}) to prevent $ELEMENT to prevent abnormal call undefined giving empty object.
Events event
Trigger the click event when a Tag is clicked.
// The event triggered when a Tag is clicked
handleClick(event) {
// Triggers events on the current instance
this.$emit('click', event);
}
Copy the code
The close event is emitted when the Tag is closed.
// The event triggered when the Tag is closed
handleClose(event) {
// Prevents further propagation of current events in the capture and bubble phases.
event.stopPropagation();
// Triggers events on the current instance
this.$emit('close', event);
},
Copy the code
Render () render function
The component will create a element VNode, add classes dynamically, set the background color using inline styles, and define the component click event. The element contains two child nodes
- Default slot;
- called
el-icon-close
theIcon
Icon that defines the click event when the Tag is closed. whenclosable
A value oftrue
Will render.
When the disableTransitions value is true, the zoom Zoom-in-Center effect is achieved by wrapping the element with the built-in component Transition.
// Render the tag virtual DOM
render(h) {
const { type, tagSize, hit, effect } = this;
// Add classes dynamically
const classes = [
'el-tag',
type ? `el-tag--${type}` : ' ',
tagSize ? `el-tag--${tagSize}` : ' ',
effect ? `el-tag--${effect}` : ' ',
hit && 'is-hit'
];
/ / the tag element
const tagEl = (
<span
class={ classes }
style={{ backgroundColor: this.color }}
on-click={ this.handleClick} >
{ this.$slots.default }
{
this.closable && <i class="el-tag__close el-icon-close" on-click={ this.handleClose} ></i>
}
</span>
);
/ / component VNode
return this.disableTransitions ? tagEl : <transition name="el-zoom-in-center">{ tagEl }</transition>;
}
Copy the code
Dynamically add classes based on component Prop.
'el-tag'
Component default style.type ? 'el-tag--${type}' : ''
Sets the colors of different component types. iftype
Values are notsuccess/info/warning/danger
One of them, setting invalid (generating invalid class).tagSize ? 'el-tag--${tagSize}' : ''
Set different sizes of components. iftagSize
Values are notmedium/small/mini
One of them, setting invalid (generating invalid class).effect ? 'el-tag--${effect}' : ''
Set different themes for components. ifeffect
Values are notdark/light/plain
One of them, setting invalid (generating invalid class).effect
The default value islight
, the correspondingel-tag--light
Is an invalid style, undefined.hit && 'is-hit'
Border stroke effect.
The color property defines the component’s inline style backgroundColor, with higher weights overwriting other styles of color.
0x02 Component Style
src/tag.scss
SCSS uses mixed instructions B, M, and genTheme to generate component styles.
GenTheme () Component theme
The genTheme hybrid directive is used to generate theme styles for components.
@mixin genTheme($backgroundColorWeight.$borderColorWeight.$fontColorWeight.$hoverColorWeight) {
background-color: mix($--tag-primary-color.$--color-white.$backgroundColorWeight);
// ...
/ / generated & is - hit
@include when(hit) {
// ...
}
.el-tag__close {
// ...
&:hover {
// ...}}// info/success/warning/danger has the same structure
&.el-tag--info {
// ...
/ / generated & is - hit
@include when(hit) {
// ...
}
.el-tag__close {
// ...
&:hover {
// ...}}}// success
// warning
// danger
}
Copy the code
The Mix function mixes two colors together in a certain proportion to produce another color. The first two arguments are the colors you want to mix (you can use color variables, hexadecimal, RGBA, RGB, HSL, or HSLA color values), and the third argument is the scale value of the first color.
mix($color1, $color2, $weight: 50%) //=> color
Copy the code
The component theme default style is generated directly under el-Tag.
/ / generated. El - tag
@include b(tag) {
// Theme rules default to light
@include genTheme(10%.20%.100%.100%);
// ...
/ / generated. El - tag -- -- dark
@include m(dark) {
// Theme rules
@include genTheme(100%.100%.0.80%);
}
/ / generated. El - tag -- -- plain
@include m(plain) {
// Theme rules
@include genTheme(0.40%.100%.100%); }}Copy the code
The theme style generated by combining the above rules is as follows
// El-tag can be replaced with el-tag--dark el-tag--plain
.el-tag {
// ...
}
.el-tag.is-hit {
// ...
}
.el-tag .el-tag__close {
// ...
}
.el-tag .el-tag__close:hover {
// ...
}
// info/success/warning/danger has the same structure
.el-tag.el-tag--info {
// ...
}
.el-tag.el-tag--info.is-hit {
// ...
}
.el-tag.el-tag--info .el-tag__close {
// ...
}
.el-tag.el-tag--info .el-tag__close:hover {
// ...
}
// success ...
// warning ...
// danger ...
Copy the code
Component style
The component style logic is as follows.
/ / generated. El - tag
@include b(tag) {
// The default light style
// ...
// Generate.el-tag. el-icon-close
.el-icon-close {
// ...
// generate.el-tag. el-icon-close::before
&::before {
// ...}}// Dark style...
// Plaink style...
/ / generated. El - tag - medium
@include m(medium) {
// ...
// generate.el-tag--medium. El-icon -close
.el-icon-close {
// ...}}/ / generated. El - tag -- -- small
@include m(small) {
// ...
// generate.el-tag--small. El-icon -close
.el-icon-close {
// ...}}/ / generated. El - tag -- -- mini
@include m(mini) {
// ...
// generate.el-tag--mini. El-icon -close
.el-icon-close {
// ...}}}Copy the code
lib/tag.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\tag. SCSS is generated.
.el-tag{/ /... }.el-tag .el-tag__close{/ /... }.el-tag .el-tag__close:hover{/ /... }/* theme start -- el-tag / el-tag--dark / el-tag--plain -------------------------- */
.el-tag.is-hit{/ /... }.el-tag .el-icon-close{/ /... }.el-tag .el-icon-close::before{/ /... }/* type -- info / success / warning / danger -------------------------- */
.el-tag.el-tag--info{/ /... }.el-tag.el-tag--info.is-hit{/ /... }.el-tag.el-tag--info .el-tag__close{/ /... }.el-tag.el-tag--info .el-tag__close:hover{/ /... } // success ... // warning ... // danger .../* el-tag--dark
-------------------------- */
// ...
/* el-tag--plain
-------------------------- */
// ...
/* theme end -- el-tag / el-tag--dark / el-tag--plain -------------------------- */
/* size -- medium / small / mini -------------------------- */
.el-tag--medium{/ /... }.el-tag--medium .el-icon-close{/ /... }Copy the code
0 x03 📚 reference
“StopPropagation”, MDN “mix funciton color”, sass
0x04 Attention column
This article has been included in the column 👇, you can directly follow.