手动实现一个Vue插件
手动实现一个Vue插件在web开发过程中,实现一个全局的定制化组件是很常见的需求,下面会以message组件为例子,来自己手动实现一个全局的message组件,分别用vue和react两种方式来实现,vue的message对照element-ui,而react的message对照antd,本篇文章会首先介绍vue的实现方法,下一篇会介绍react实现方法我们看antd或者element不难发现,其
·
手动实现一个Vue插件
在web开发过程中,实现一个全局的定制化组件是很常见的需求,下面会以message组件为例子,来自己手动实现一个全局的message组件,分别用vue和react两种方式来实现,vue的message对照element-ui,而react的message对照antd,本篇文章会首先介绍vue的实现方法,下一篇会介绍react实现方法
我们看antd或者element不难发现,其实message这样的全局组件和常规组件不同,他暴露的不是一个组件而是一些调用API
// element-ui的Message调用
this.$message({
message: '恭喜你,这是一条成功消息',
type: 'success'
});
// antd的Message调用
import { message } from 'antd'
message.success({ content: 'Loaded!', key, duration: 2 })
这其实就是意味着,在调用API之前,先把装这些全局组件的容器渲染到页面上,在正式调用API的时候再把,内容渲染到容器中
实现这个vue版本的messsage其实分为三个部分
- message组件的template部分
- 如何把message组件实例放到vue原型上(方便调用,不用每个文件都引入)
- 考虑一些边界问题
- 如何使用这个message
- message组件的template部分(模板和样式)
<template>
<div class="message-wrap">
<transition-group name="msg-fade">
<div class="message" :class="item.type" v-for="item in list" :key="item.tag">
<span class="icon"></span>
<p class="content">{{item.content}}</p>
</div>
</transition-group>
</div>
</template>
<style scoped lang='less'>
.message-wrap{
position: fixed;
left: 50%;
top: 60px;
transform: translate(-50%);
z-index: 1000;
.message{
height: 34px;
min-width: 180px;
padding: 0px 10px;
font-size: 12px;
margin-top: 30px;
display: flex;
align-items: center;
border-radius: 4px;
box-shadow: 0 0 8px #ddd;
border: 1px solid #eee;
.icon {
width: 10px;
height: 10px;
border-radius: 50%;
margin-right: 6px;
}
}
.error {
color: #ff4d4f;
>.icon{
background: #ff4d4f;
}
}
.warning {
color: #faad14;
>.icon{
background: #faad14;
}
}
.success {
color: #52c41a;
>.icon{
background: #52c41a;
}
}
}
.msg-fade-enter-active {
animation: alert-fade-in .3s;
}
.msg-fade-leave-active {
animation: alert-fade-out .3s;
}
@keyframes alert-fade-in {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes alert-fade-out {
0% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>
-
如何把message组件实例以及instance上暴露的API放到vue原型上(方便调用,不用每个文件都引入)
要达到这个效果,需要用到Vue.extend()和Vue.use()
- 在Vue.use()时候会去,执行组件里面的install方法,我们可以在这里把message组件实例以及instance上暴露的API放到vue原型上
<script>
let tag= 0;
let instance = null;
const Msg = {
name:'message',
data(){
return {
type:'',
content:'',
list:[]
}
},
install(Vue){
Vue.prototype.$msg = (config)=>{
// 创建构造器
let MessageConstructor = Vue.extend(Msg);
if(!instance){
instance = new MessageConstructor();
// 创建 MessageConstructor 实例,并挂载到一个元素上。
instance.$mount();
document.body.appendChild(instance.$el);
}
instance.add(config)
}
},
}
export default Msg
</script>
- 考虑一些边界问题
- 考虑到页面长度,限制最多容纳10条数据
- 考虑到超时之后超时的message消失,需要给每一条数据添加唯一tag
<script>
let tag= 0;
let instance = null;
const Msg = {
methods:{
add(eachList){
// 超过10条删除第一条
if(this.list.length > 10){
this.list.shift()
}
// 给每一条message加一个唯一tag
const obj = Object.assign({tag: tag++},eachList)
this.list.push(obj);
setTimeout(()=>{
this.removeList(obj.tag)
},eachList.duration)
},
removeList(tag){
const newList = this.list.filter(each=>each.tag !== tag);
this.list = newList;
}
},
}
export default Msg
</script>
- 如何使用这个message
// main.js
import Vue from 'vue';
import App from './App.vue';
import msg from './index.vue';
Vue.use(msg)
new Vue({
render: h => h(App),
}).$mount('#app')
// xxx.vue
this.$message(
{
type:'error',
content:'自定义message',
duration: 5000,
}
)
效果如下:
更多推荐
已为社区贡献1条内容
所有评论(0)