1、文件结构
packages/* 主要存放编写的组件
types/* 主要存放 组件中使用的 类型标注
2、编写组建样式 及 开放属性
这里要提前考虑好,把什么样的属性开放出去,就是以下的 props.options要存在哪些你需要动态获取的属性
文件路径: packages/Message/index.vue
<template>
<div class="message" :class="{'active': props.options?.show}">
<div :class="['message-icon', props.options?.type]">
<svg-icon :icon-class="props.options?.icon" />
</div>
<div class="message-content">
<div class="message-title">{{ props.options?.title }}</div>
<div class="message-description">{{ props.options?.message }}</div>
</div>
</div>
</template>
<script lang="ts" setup>
/**icon 图标 */
import SvgIcon from '../SvgIcon/index.vue';
import { defineProps } from 'vue'
import { OptionsInIt } from '../../types/message';
const props = defineProps<{
options: OptionsInIt;
}>();
</script>
<style lang="less">
.message{
max-width: 330px;
width: calc(100vw - 50px);
padding: 15px;
margin: 0 auto;
position: fixed;
top: 10px;
right: -400px;
z-index: 9998;
transition: right .6s ease;
background: #ffffff;
border: 1px solid #ebeef5;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .3);
display: flex;
justify-content: flex-start;
border-radius: 8px;
&.active{
right: 10px;
transition: right .6s ease;
}
.message-icon{
font-size: 30px;
color: var(--black);
padding-right: 6px;
&.error{
color: var(--red)
}
&.warning{
color: var(--yellow)
}
&.success{
color: var(--green)
}
&.info{
color: var(--info)
}
}
.message-content{
width: calc(100% - 46px);
.message-title{
font-size: 16px;
color: var(--black);
font-weight: bold;
}
.message-description{
overflow: hidden;
white-space: normal;
word-break: break-word;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
font-size: 13px;
color: #555666;
}
}
}
</style>
要开发的message所需的功能
- 可以使用方法直接弹出提示
- 多种不同类的情景提示(如: error、success、warning、info)
- 可自动关闭提示
- 可自定提示的图标
3、创建组件实例 及 扩展方法
文件路径: packages/Message/index.ts
import { createApp, reactive } from 'vue'
import MessageComponent from './index.vue'
import { OptionsInIt } from '../../types/message';
const options = reactive<OptionsInIt>({
show: false,
title: "",
icon: "",
type: "",
message: "",
duration: 3000, // 显示时间
})
const $message = createApp(MessageComponent, { options }).mount(document.createElement('div'))
// 抛出组件方便挂载
export const message = {
open (opts: OptionsInIt = options): void { // 控制显示 message 的方法
options.show = true
Object.keys(opts).forEach((K: keyof OptionsInIt) => {
options[K] = opts[K]
})
if (options.duration > 0) {
setTimeout(() => {
options.show = false
}, options.duration)
setTimeout(() => {
options.icon = ""
options.type = ""
options.message = ""
options.title = ""
options.duration = 3000
}, options.duration + 600) // 600为动画时长
}
document.body.appendChild($message.$el)
},
error (opts: OptionsInIt = options): void {
opts.icon = opts.icon || "message-error"
opts.type = "error"
message.open(opts)
},
warning (opts: OptionsInIt = options): void {
opts.icon = opts.icon || "message-warning"
opts.type = "warning"
message.open(opts)
},
success (opts: OptionsInIt = options): void {
opts.icon = opts.icon || "message-success"
opts.type = "success"
message.open(opts)
},
info (opts: OptionsInIt = options): void {
opts.icon = opts.icon || "message-info"
opts.type = "info"
message.open(opts)
}
}
// 抛出组件及组件名称
export default {
name: "message",
component: MessageComponent
}
这里还可以扩展自己所需要的功能
4、集成组件 和 install 挂载方法
文件目录: plugIns/index.ts
import SvgIcon from './packages/SvgIcon/index';
import Loading, { loading } from './packages/Loading/index';
import Message, { message } from './packages/Message/index';
import type { App } from 'vue';
const pluginsComponents = [
Loading,
SvgIcon,
Message,
]
const install = function (Vue : App, opts = {}): void {
// 挂载实例到 全局的 globalProperties 上
Vue.config.globalProperties.$loading = loading
Vue.config.globalProperties.$message = message
// opts 用于扩展 plugins => 目前暂无用到
console.log(opts);
pluginsComponents.forEach(item => {
Vue.component(item.name, item.component)
})
}
export default {
install,
}
注意这里一定要是install方法名,并且要导出,Vue的文档上有准确描写,Vue.use 会默认读取包内容的install作为包初始化的方法
5、挂载到Vue实例上
文件目录: src/main.ts
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/store';
import Plugins from '@/plugIns/index';
const app = createApp(App)
// 初始化plugIns ******* 挂载到vue实例上
app.use(Plugins)
app.use(router)
app.use(store)
app.mount('#app')
export default app
6、 使用
import { getCurrentInstance, ComponentPublicInstance } from 'vue';
// getCurrentInstance.proxy 能获取到挂载在vue原型上的方法
const proxy: ComponentPublicInstance<any> = getCurrentInstance()?.proxy
proxy.$message.error({
title: "错误",
message: "获取博客错误"
})
效果图:
如需要源码请私信我。