持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情。
今天主要学的是Vue3中如何开发插件。
插件开发
第一步:新建插件文件
新建一个plugins文件夹,以toast插件为例,toast文件夹包含两个文件,toast.vue和index.ts
第二步,写入插件所需内容(以toast插件为例)
在toast中,这里简单做个示范,具体写的时候根据具体需求去写:
// toast.vue
<template>
<div class="toast-wrap">
{{ message }}
</div>
</template>
<script>
export default {
name: 'my-toast',
props: {
message: {
type: String,
default: '',
},
},
};
</script>
<style scoped>
.toast-wrap {
background-color: rgba(0, 0, 0, 0.8);
padding: 8px 15px;
font-size: 14px;
color: #ffffff;
text-align: center;
position: fixed;
z-index: 99;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
border-radius: 5px;
}
</style>
// index.ts
import MyToast from './toast.vue';
import { createVNode, render } from 'vue';
interface IOptions {
message: string;
duration?: number;
onClose?: Function;
}
export default {
install: (app: any) => {
//是否存在toast,防止toast在未销毁前,连续点击按钮生成多个toast
let isToast = false;
// app.config.globalProperties注册全局方法,相当于vue2的Vue.prototype
app.config.globalProperties.$myToast = function (opts: IOptions) {
//如果toast不存在,开始创建toast
if (!isToast) {
isToast = true; //在toast未销毁前,不执行以下程序
//创建虚拟节点
let vm: any = createVNode(MyToast);
//创建div容器
let container = document.createElement('div');
//渲染虚拟节点
render(vm, container);
//将创建好的div元素添加到body元素内
document.body.appendChild(container);
//设置toast.vue文件中的props选项内部的message的值
vm.component.props.message = opts.message || '';
let duration = opts.duration || 2000;
setTimeout(() => {
//销毁toast
document.body.removeChild(container);
//toast销毁后将isToast设置为false,可以再次创建toast
isToast = false;
//如果存在onClose方法
if (opts.onClose) {
//调用onClose方法
opts.onClose();
}
}, duration);
}
};
},
};
第三步:全局导入
在main.ts中导入使用:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router';
import store from './store';
import MyToast from './plugins/my-toast';
let app = createApp(App).use(store).use(router);
app.use(MyToast);
app.mount('#app');
第四步,导入页面中使用
<template>
<div>
<button @click="showToast()">显示toast</button>
</div>
</template>
<script lang="ts">
import { defineComponent, getCurrentInstance } from 'vue';
export default defineComponent({
name: 'show-toast',
setup() {
//getCurrentInstance:可以获取到组件的实例
let { proxy }: any = getCurrentInstance(); // 代替this
let showToast = () => {
proxy.$myToast({
message: '我是toast插件',
duration: 3000,
onClose: () => {
console.log('已关闭');
},
});
};
return {
showToast,
};
},
});
</script>