开发应用级组件 Vue3 + TypeScript

文章介绍了如何构建一个Vue组件Message,包括组件的文件结构,定义props和样式,以及创建组件实例和扩展方法。组件支持多种类型(error、success、warning、info)的提示,并可自定义图标和自动关闭。最后,文章展示了如何将组件集成到Vue应用中,通过Vue.use方法挂载并使用全局方法。
摘要由CSDN通过智能技术生成

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: "获取博客错误"
})

效果图:
在这里插入图片描述

如需要源码请私信我。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值