点击上方 前端瓶子君,关注公众号
回复算法,加入前端编程面试算法每日一题群
来源:wy白菜
https://juejin.cn/post/6964954862991704094
前言
害,最近两个月忙于工作和生活(明明就是给自己偷懒找借口),太久太久没更新文章了,正好趁着今天加班(摸鱼)来写一写最近在项目中封装的自以为很装的组件。在ui疯狂出图的前提条件下,我发现了很多轻提示和弹框dialog高度相似又要支持自定义,便开始了封装之路。
好孩子要学会先借鉴别人的作业
我在封装的第一版轻提示中,还是用的老传统props去接收一个visiable控制提示的显示和隐藏,归根结底还是不让组件一上来就挂载在dom节点上。组件写完了自然要使用不是吗,便高高兴兴的提交了代码。我自己在使用的过程中就感觉到很麻烦了,因为还要先引入组件,再定义一个visiable,再在template上写上一个<Toast :xxx="xxx" xxxxxxx/>,再一个页面上如果出现多次调用的话,要么你就多写几个toast(不会吧,不会吧,应该没人会选择这么做吧),要么就疯狂的改变data中定义的数据。虽然自己已经发现了这个弊端,但是不偷懒的程序员不是一个好的程序员,还是选择忽视了这个问题,害,躲的了初一躲不了十五,第二天旁边的仙女同事(她自认为的嘻嘻嘻)就在不经意间吐槽了使用起来过于复杂,完全没有element的好用。内心os:我要是能写的和element差不多就不坐在这了。当然,有其他人也提出了和我相同的问题,那自然要去解决不是吗。
熟练的打开element ui翻到MessageBox组件哪里(此时的我还没意识到自己的项目是vue3环境),发现他们的调用方法也太简单了吧:
<template>
<el-button type="text" @click="open">点击打开 Message Box</el-button>
</template>
<script>
export default {
methods: {
open() {
this.$alert('这是一段内容', '标题名称', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: `action: ${ action }`
});
}
});
}
}
}
</script>
<style>
</style>
复制代码
再看看自己的代码,简直不能看哈哈哈。古人云:师夷长技以制夷。打开自己开的vue2项目,打开庞大的node_modules包,找到对应的代码开始借鉴。
第一步,先写好要展示的页面。
工欲善其事,必先利其器。我们要想组件能使用,自然少不了我们的页面,我们写个demo演示一下:
<template>
<div>测试{{booo}}</div>
</template>
<script>
export default {
data() {
return {
visiable: false
};
}
};
</script>
<style></style>
复制代码
可能有小伙伴会问我写的visiable是干啥的,前面不是才说这个东西会抛弃掉吗?嘿嘿嘿,这里写只是单纯的为了后面测试用的,没有实际作用哈。
第二步,使用vue构造器创造“子类”
在翻阅官方文档过程中,我们可以得知vue.extend(options)中的options必须是一个组件,也就是我们前面写的demo,有一点必须要知道的是data必须是一个函数,不过,我相信小伙伴们肯定一直写的都是函数。又因为我们extend创建的不是平常我们写的组件实例,所以不能使用new Vue({ components: test }),这里官方为我们提供了挂在到节点的方法$mount。千说万说不如直接上代码靠谱。
import Vue from "vue";
import Main from "./main.vue";
const MessageConstructor = Vue.extend(Main);
let instance;
const Message = function(options) {
if (Vue.prototype.$isServer) {
return;
}
console.log(Vue.prototype.$isServer);
options = options || {};
instance = new MessageConstructor({
data: options
});
instance.$mount();
document.body.appendChild(instance.$el);
console.log(instance.visiable);
console.log(instance.booo);
return instance;
};
export default Message;
复制代码
在看完代码中,可能会有部分小伙伴会问Vue.prototype.$isServer是什么,说实话,在没看文档前我也不会哈哈哈。
![](https://i-blog.csdnimg.cn/blog_migrate/1d3d9fd50af9c23a0376ee3b4d48cb9e.png)
通过文档中可以知道这是判断是否运行在服务器上,我们在服务器上又没有界面自然不需要了。当我们调用方法的时候可以将参数正常传递进来就需要在new构造器的时候接受参数,然后再挂载在$mount上,最后插入到我们的body上.
第三步,收获成果调用方法
我们前面的准备工作都做完之后先别着急,怎么会这么容易就让我们可以使用了呢。我们还需要在最外面的main.js导入我们写好的文件
import Vue from "vue";
import ElementUI from "element-ui";
import Message from "@/components/test/main";
import "element-ui/lib/theme-chalk/index.css";
import App from "./App.vue";
Vue.config.productionTip = false;
Vue.use(ElementUI);
// Vue.use(Message);
Vue.prototype.$Message = Message;
new Vue({
render: h => h(App)
}).$mount("#app");
复制代码
这样我们就可以正常使用啦。
mounted() {
setTimeout(() => {
this.$Message({
booo: true
});
}, 3000);
},
复制代码
![](https://i-blog.csdnimg.cn/blog_migrate/45a7949595aa0f5751b305f6fc8efbb9.png)
看到这里有人会问这个booo哪里来的,为什么在组件中没有props去接收参数也可以显示,这个就是构造器特殊的地方哈。
开始在正式项目中使用
有了前面的铺垫,我自然兴致冲冲的把自己的思路在项目中实践,突然想到自己之前挖的坑项目使用的是vue3,不确定之前写的还可不可以,先放上去试试。果然不出意外的报错了。翻看vue3文档,因为现在不能直接import Vue from "vue";了,所以对应的vue.extend()也没有了。虽然官方删除了extend但是也提供了新的createApp给我们使用。
![](https://i-blog.csdnimg.cn/blog_migrate/b732b60d07f4e3189a9578086f45ec0b.png)
最后改造完的代码如下:
import { createApp } from "vue";
import ToastMessage from "./index.vue";
const createMount = options => {
const mountNode = document.createElement("div");
document.body.appendChild(mountNode);
const app = createApp(ToastMessage, {
...options,
remove() {
app.unmount(mountNode);
document.body.removeChild(mountNode);
}
});
return app.mount(mountNode);
};
const toast = options => {
return createMount(options);
};
toast.install = app => {
app.component("Toast", ToastMessage);
app.config.globalProperties.$toast = toast;
};
export default toast;
复制代码
这里小伙伴们要注意了,在vue2中我们可以不用props接受数据也可以显示出来,但是vue3不行了哦。
后记
希望这篇文章能对大家有所帮助,如果有写的不对的地方也希望指点一二。
--wy白菜
复制代码
最后
欢迎关注【前端瓶子君】✿✿ヽ(°▽°)ノ✿
回复「算法」,加入前端编程源码算法群,每日一道面试题(工作日),第二天瓶子君都会很认真的解答哟!
回复「交流」,吹吹水、聊聊技术、吐吐槽!
回复「阅读」,每日刷刷高质量好文!
如果这篇文章对你有帮助,「在看」是最大的支持
》》面试官也在看的算法资料《《
“在看和转发”就是最大的支持