defaultprops / article Goto Github PK
View Code? Open in Web Editor NEWtodo list for life
License: MIT License
todo list for life
License: MIT License
<template>
<button
class="el-button"
@click="handleClick"
:disabled="buttonDisabled || loading"
:autofocus="autofocus"
:type="nativeType" // 原生type: submit | reset | button | menu(废弃)
:class="[
// computed缺少type类型校验
type ? 'el-button--' + type : '',
// computed缺少size类型校验
buttonSize ? 'el-button--' + buttonSize : '',
{
'is-disabled': buttonDisabled,
// 在联调UED设置的主题中,局部使用少量属性配置主题。
// 其他属性屏蔽使用或使其不生效(工作量较大)
'is-loading': loading,
'is-plain': plain,
'is-round': round,
'is-circle': circle
}
]"
>
<i class="el-icon-loading" v-if="loading"></i> // 图标前置
<i :class="icon" v-if="icon && !loading"></i>
<span v-if="$slots.default"><slot></slot></span>
</button>
</template>
<script>
export default {
name: 'ElButton', // 通常而言,不建议使用name属性,定位难还容易重名
inject: { // 当然,更不建议使用这种穿透形式的inject
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
props: { // 建议使用严格模式的,required 和 default
type: {
type: String,
default: 'default'
},
size: String,
icon: {
type: String,
default: ''
},
nativeType: {
type: String,
default: 'button'
},
loading: Boolean,
disabled: Boolean,
plain: Boolean,
autofocus: Boolean,
round: Boolean,
circle: Boolean
},
computed: {
// 下划线的声明写法一般是内部私有变量,建议统一风格。本人不习惯使用该写法。
// level el-form-item > el-form
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
// level: button-size > el-form-item-size
// > el-form-size > global size (Vue.prototype.$ELEMENT)
buttonSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
},
buttonDisabled() {
// new 实例中使用propsData情况少见,可以不考虑这种情况。v3抛弃
// el-form 全局disabled属性
return this.$options.propsData.hasOwnProperty('disabled') ? this.disabled : (this.elForm || {}).disabled;
}
},
methods: {
// 非常不喜欢这种写法,handle就包含click,这么写有点重复意思
handleClick(evt) {
this.$emit('click', evt);
}
}
};
</script>
el-button-group
源码<template>
<div class="el-button-group">
<slot></slot>
</div>
</template>
<script>
export default {
name: 'ElButtonGroup'
};
</script>
<template>
// 增加动画效果,透明度
// .el-alert-fade-enter,.el-alert-fade-leave-active {opacity: 0;}
<transition name="el-alert-fade">
// 我更习惯 classname 静态和动态一起写
// role这种增强语义的方式,感觉怪怪的,有种四不像的赶脚
// 必须使用v-show,不然动画效果不生效。
// todo: BEM className命名规范
<div
class="el-alert"
:class="[typeClass, center ? 'is-center' : '', 'is-' + effect]"
v-show="visible"
role="alert"
>
<i class="el-alert__icon" :class="[ iconClass, isBigIcon ]" v-if="showIcon"></i>
<div class="el-alert__content">
<span class="el-alert__title" :class="[ isBoldTitle ]" v-if="title || $slots.title">
<slot name="title">{{ title }}</slot>
</span>
// $slots.default && !description 写入 computed 变量更直观一点
<p class="el-alert__description" v-if="$slots.default && !description"><slot></slot></p>
<p class="el-alert__description" v-if="description && !$slots.default">{{ description }}</p>
// 这个也可以写入 computed 变量成 className
// closeText == '' ? 'el-icon-close' : 'is-customed']
// 习惯增加 eslint-plugin-vue vue/attributes-order 属性排序
<i class="el-alert__closebtn" :class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }" v-show="closable" @click="close()">{{closeText}}</i>
</div>
</div>
</transition>
</template>
<script type="text/babel">
const TYPE_CLASSES_MAP = {
'success': 'el-icon-success',
'warning': 'el-icon-warning',
'error': 'el-icon-error'
};
export default {
// 习惯增加 vue/order-in-components 强制顺序关系,更容易 review 和 debug
name: 'ElAlert',
props: {
title: {
type: String,
default: ''
},
description: {
type: String,
default: ''
},
type: {
type: String,
default: 'info'
},
closable: {
type: Boolean,
default: true
},
closeText: {
type: String,
default: ''
},
showIcon: Boolean,
center: Boolean,
effect: {
type: String,
default: 'light',
validator: function(value) {
// advise: includes api is better
return ['light', 'dark'].indexOf(value) !== -1;
}
}
},
data() {
return {
visible: true
};
},
methods: {
// 语义化一点
close() {
this.visible = false;
this.$emit('close');
}
},
computed: {
typeClass() {
return `el-alert--${ this.type }`;
},
iconClass() {
return TYPE_CLASSES_MAP[this.type] || 'el-icon-info';
},
isBigIcon() {
return this.description || this.$slots.default ? 'is-big' : '';
},
isBoldTitle() {
return this.description || this.$slots.default ? 'is-bold' : '';
}
}
};
</script>
<script>
export default {
// 不建议使用name属性,后期定位组件难
name: 'ElAvatar',
props: {
size: {
type: [Number, String],
// 以前用得少这种校验方式,这种校验方式可能会丢失上一级真实传递的数据
// 但是确实是一个有趣的方法
// validator 校验props类型,false控制台告警
validator(val) {
if (typeof val === 'string') {
return ['large', 'medium', 'small'].includes(val);
}
return typeof val === 'number';
}
},
// 展示类型,默认circle圆形头像, square方形头像
// 看来都是看心情写validator啊
shape: {
type: String,
default: 'circle',
validator(val) {
return ['circle', 'square'].includes(val);
}
},
icon: String,
src: String,
alt: String,
srcSet: String,
error: Function,
fit: {
type: String,
default: 'cover'
}
},
data() {
return {
isImageExist: true
};
},
computed: {
avatarClass() {
const { size, icon, shape } = this;
let classList = ['el-avatar'];
// add class-size
if (size && typeof size === 'string') {
classList.push(`el-avatar--${size}`);
}
// add class-icon
if (icon) {
classList.push('el-avatar--icon');
}
// add class-shape
if (shape) {
classList.push(`el-avatar--${shape}`);
}
return classList.join(' ');
}
},
methods: {
// handleError 这名字怪怪的,手动报错?? 写 loadErrorImg 语义化一点
handleError() {
// const errorFlag = this.error?.() || undefined 简单点
const { error } = this;
const errorFlag = error ? error() : undefined;
if (errorFlag !== false) {
this.isImageExist = false;
}
},
renderAvatar() {
// 个人习惯更喜欢使用this, this在vue2代表自定义的vue变量或者方法
// 这种解构方式容易误会成函数内部局部变量而不是vue变量
// 而且后期扩展容易重名
const { icon, src, alt, isImageExist, srcSet, fit } = this;
// todo 学习css: object-fit
if (isImageExist && src) {
return <img
src={src}
onError={this.handleError}
alt={alt}
srcSet={srcSet}
style={{ 'object-fit': fit }}/>;
}
if (icon) {
return (<i class={icon} />);
}
// 应该增加一个具名插槽。联调UED的主题头像时,还要我自己封装。唉...
return this.$slots.default;
}
},
render() {
const { avatarClass, size } = this;
const sizeStyle = typeof size === 'number' ? {
height: `${size}px`,
width: `${size}px`,
lineHeight: `${size}px`
} : {};
return (
<span class={ avatarClass } style={ sizeStyle }>
{
this.renderAvatar()
}
</span>
);
}
};
</script>
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.