前因
因为在上家公司没有操作过把组件转换为函数调用,现在想自己动手尝试下自定义message组件,夯实下基础。
第一步:确定ui
ui一开始是想简单实现下组件,主要的工作是在于install函数。
所以只是涉及了简单的页面。
第二步:开始编写组件
组件的代码很简单,如下所示。
<div class="message" v-show="show">
<div class="message-content">
<span class="message-text">消息内容</span>
</div>
</div>
</template>
<script>
export default {
name: 'message',
props: {
show: {
type: Boolean,
default: false
},
duration: {
type: Number,
default: 0
}
},
watch: {
async show (o) {
if (o) {
this.duration !== 0 && setTimeout(() => {
setTimeout(() => {
this.show = false
}, 500)
}, this.duration)
}
}
},
methods: {
close () {
setTimeout(() => {
this.show = false
}, 500)
}
}
};
</script>
<style scoped>
.message {
position: fixed;
top: 0px;
bottom: 0;
left: 0;
right: 0;
width: 100vw;
height: 100vh;
/* */
display: flex;
align-items: center;
justify-content: center;
}
.message .message-content {
width: 120px;
height: 100px;
background-color: rgba(0, 0, 0, 0.75);
border-radius: 5px;
line-height: 1.5;
padding: 10px 0;
display: flex;
align-items: center;
flex-direction: column;
justify-content: center;
}
.message .message-content .message-text {
padding-top: 10px;
color: #fff;
font-size: 14px;
}
</style>
第三步:开始编写index.js
export default {
install (Vue) {
Vue.prototype['$message'] = function (options = {}) {
const Message = Vue.extend(MessageSub);
const component = new Message({
data: options
}).$mount();
document.body.appendChild(component.$el); // 因为函数调用不存在parent,所以需要添加到body中
Vue.nextTick(() => {
component.show = true;
});
};
}
};
简单实现了一下。参考了网上的代码,以前没使用过extend方法。
总结: 到这里,message已经是简单实现了,同时也了解到了extend方法的使用技巧。(extend 方法返回构造函数,然后在new一下,最后添加到document.body中)
进阶:优化组件
目前的组件只是基础版本,需要在优化下。
问题1:多次调用$message事件会产生多个Message 实例,这个是不被允许的。所以我提供了一个变量来缓存组件。
let cache; // index.js中定义
if (cache) {
Vue.nextTick(() => {
component.show = true;
});
return true
}
问题2:假设这个message不会自动关闭,那么需要在$message方法需要返回一个方法,用来关闭message组件。
return {
close () {
cache.close.call(Vue);
}
};
具体组件的close方法也很简单
close () {
setTimeout(() => {
this.show = false
}, 500)
}
总结:至此,已经解决了2个问题。
总结
通过这个自定义组件,学到了如何把组件转为函数调用。 写的不好,请大家多多包涵。