使用
demo: element-plus.gitee.io/zh-CN/compo…
源码
layout组件包含了 el-row 和 el-col 组件
el-row组件阅读
<template>
<component :is="tag" :class="rowKls" :style="style">
<slot />
</component>
</template>
<script setup lang="ts">
// 当传了props.gutter
const gutter = computed(() => props.gutter);
provide(rowContextKey, {
gutter,
});
const style = computed(() => {
const styles: CSSProperties = {};
if (!props.gutter) {
return styles;
}
styles.marginRight = styles.marginLeft = `-${props.gutter / 2}px`;
return styles;
});
</script>
- 通过
<component :is=xxx></component>实现自定义标签 - 当传了
props.gutter,通过provide()传给后代组件,并设置marginLeft和marginRight为负gutter的一半,这里主要提供给el-col用
el-col组件阅读
el-col部分代码
// 获取上面el-row的provide
const { gutter } = inject(rowContextKey, { gutter: computed(() => 0) });
// class的计算
const colKls = computed(() => {
const classes: string[] = [];
const pos = ['span', 'offset', 'pull', 'push'] as const; // 这4个都是prop的属性
pos.forEach((prop) => {
const size = props[prop]; // 获取对应prop的值
if (isNumber(size)) {
if (prop === 'span') {
// 如果传了`<el-col :span=4>`,那么这里就是`el-col-4`
classes.push(ns.b(`${props[prop]}`));
} else if (size > 0) {
// 如果传了`<el-col :offset=4>`,那么这里就是`el-col-offset-4`
classes.push(ns.b(`${prop}-${props[prop]}`));
}
}
});
const sizes = ['xs', 'sm', 'md', 'lg', 'xl'] as const; // 这5个都是prop的属性
sizes.forEach((size) => {
if (isNumber(props[size])) {
classes.push(
ns.b(
`${size}-${props[size]}`, // 类似 el-col-xs-4 的class
),
);
} else if (isObject(props[size])) {
Object.entries(props[size]).forEach(([prop, sizeProp]) => {
classes.push(
prop !== 'span'
? ns.b(`${size}-${prop}-${sizeProp}`) // 类似 el-col-xs-span-4 的class
: ns.b(`${size}-${sizeProp}`), // 类似 el-col-xs-4 的class
);
});
}
});
// this is for the fix
if (gutter.value) {
classes.push(ns.is('guttered'));
}
return [ns.b(), classes];
});
- 通过
inject()获取到el-row的provide - 根据传入的props组装各种className