index.js
常规做法,添加install
方法来方便作为插件使用。
import Alert from './src/main';
Alert.install = function(Vue) {
Vue.component(Alert.name, Alert);
};
export default Alert;
整体
首先分析一下其模板结构。
<template>
<transition name="el-alert-fade">
<div class="el-alert" :class="[ typeClass ]" v-show="visible">
<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">{{ title }}</span>
<slot>
<p class="el-alert__description" v-if="description">{{ description }}</p>
</slot>
<i class="el-alert__closebtn" :class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }" v-show="closable" @click="close()">{{closeText}}</i>
</div>
</div>
</transition>
</template>
最外层transition
首先,最外层是一个名为el-alert-fade
的过渡动画,查询发现,它只是简单的改变了透明度。
<transition name="el-alert-fade">
</transition>
.el-alert-fade-enter,
.el-alert-fade-leave-active {
opacity: 0;
}````
## el-alert包裹
然后,里面是一层`el-alert 类`的`div`用来包裹整个组件,其中一个属性是根据传递`props`的`type`类型改变样式,另一个是根据`visible`决定是否显示。
```html
<div class="el-alert" :class="[ typeClass ]" v-show="visible">
</div>
type
是一个计算属性
,代码如下:
props: {
type: {
type: String,
default: 'info'
}
}
computed: {
typeClass() {
return `el-alert--${ this.type }`; // 根据传递的type返回不同的类
}
}
再往里面,是一个i
标签和一个div
标签,前者是相应的图标,后者是警告具体的内容。
图标
图标通过两个类控制样式,它们都是计算属性
,其中iconClass
决定图标类型,isBigIcon
决定图标大小,而showIcon
是传递来的props
决定是否显示这个图标。其代码如下:
<i class="el-alert__icon" :class="[ iconClass, isBigIcon ]" v-if="showIcon"></i>
props: {
showIcon: {
type: Boolean,
default: false
}
}
computed: {
iconClass() {
return TYPE_CLASSES_MAP[this.type] || 'el-icon-information';
},
isBigIcon() {
return this.description ? 'is-big' : '';
}
}
其中TYPE_CLASSES_MAP
是一个常量对象,用来做map
,根据传递的type
来决定相应的类名。
const TYPE_CLASSES_MAP = {
'success': 'el-icon-circle-check',
'warning': 'el-icon-warning',
'error': 'el-icon-circle-cross'
};
而isBigIcon
是根据props
中的description
来决定的,当存在描述内容的时候就使用大的图标。
props: {
description: {
type: String,
default: ''
},
}
主体内容
接下来是主要的内容部分,包括标题、内容和关闭按钮三个部分。
标题
标题是由名为title
的prop
来决定的,包含一个isBoldTitle
的计算属性来决定是否粗体,以及根据title
是否存在来决定是否显示这一部分。
<span class="el-alert__title" :class="[ isBoldTitle ]" v-if="title">{{ title }}</span>
computed: {
isBoldTitle() {
return this.description ? 'is-bold' : '';
}
}
警告描述
然后是最为主要的描述部分,这部分是一个slot
,这使得,这一部分可以自定义,也可以通过传递description
这一prop
来决定内容。
<slot>
<p class="el-alert__description" v-if="description">{{ description }}</p>
</slot>
关闭按钮
最后是关闭按钮的实现。
<i
class="el-alert__closebtn"
:class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }"
v-show="closable"
@click="close()">
{{closeText}}
</i>
不难看出,做了如下处理:
- 存在
closeText
这一prop
的内容的话,会自定义关闭内容; - 会根据
closable
这一prop
决定是否显示该关闭按钮; - 绑定单击时触发事件
close()
其中closeText
和closable
的代码如下:
props: {
closable: {
type: Boolean,
default: true
},
closeText: {
type: String,
default: ''
},
}
close
会将visible
设置为false
从而关闭该警告,并且触发close
事件。
methods: {
close() {
this.visible = false;
this.$emit('close');
}
},
网友评论