自定义vue插件
main.ts
import { createApp, Ref } from 'vue';
import App from './App.vue';
const app = createApp(App);
// 扩充声明
declare module 'vue' {
export interface ComponentCustomProperties {
$showMessage: {
show: () => void;
hide: () => void;
isShow: Ref<any>;
};
}
}
import showMessage from './components/show-message';
// 注册全局插件
app.use(showMessage);
app.mount('#app');
./components/show-message/index.ts
import { App, VNode, createVNode, render } from 'vue';
import showMessage from './index.vue';
export default {
// 注册插件必须实现install方法
install: (app: App) => {
// 组件转为vNode,虚拟dome结构
const vNode: VNode = createVNode(showMessage);
// 手动把虚拟节点挂载到全局,因为是全局,所以直接挂载到document.body
render(vNode, document.body);
app.config.globalProperties.$showMessage = {
show: vNode.component.exposed.show,
hide: vNode.component.exposed.hide,
isShow: vNode.component.exposed.isShow,
};
},
};
./components/show-message/index.vue
<template>
<div v-if="isShow" class="box">
<pre>测试数据</pre>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const isShow = ref(false);
const show = () => {
isShow.value = true;
};
const hide = () => {
isShow.value = false;
};
// 把方法&变量暴露出去
defineExpose({
show,
hide,
isShow,
});
</script>
<style scoped>
.box {
float: right;
background-color: white;
border: 2px solid black;
height: 500px;
width: 500px;
}
</style>
全局,任何地方都可以直接使用
<template>
<div>
<div>我是index</div>
<hr />
<t-button @click="hclick">点我</t-button>
</div>
</template>
<script lang="ts">
export default {
name: 'ApplyAWSIndex',
};
</script>
<script setup lang="ts">
import { getCurrentInstance } from 'vue';
// 获取当前组件实例
const instance = getCurrentInstance();
const hclick = () => {
console.log(instance.proxy.$showMessage.isShow.value);
// 调用方法
instance.proxy.$showMessage.show();
setTimeout(() => {
instance.proxy.$showMessage.hide();
}, 3000);
};
</script>
<style scoped lang="less">
.box {
border: 3px solid black;
height: 50px;
}
</style>
点击前
点击后