zoukankan      html  css  js  c++  java
  • vue 3.0 封装一个message提示组件

    前言

    vue2.x中,可以使用 Vue.extends 来封装一个弹框,在vue 3.0中,该api已经被废除。

    实现后使用方式: Message.info(‘提示’); Message.error(‘错误’);

    1.修改index.html

    注: 添加 < div id=“message”></ div>

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width,initial-scale=1.0">
        <link rel="icon" href="<%= BASE_URL %>favicon.ico">
        <title><%= htmlWebpackPlugin.options.title %></title>
      </head>
      <body>
        <noscript>
          <strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
        </noscript>
        <div id="app"></div>
        <div id="message"></div>
        <!-- built files will be auto injected -->
      </body>
    </html>
    

    2.新建一个index.ts文件

    注:

    使用class类方式来写调用方法。当然如果是loading等也可以直接用函数方法实现
    createApp(组件) mount(id / class / div), 可以参考main.ts。
    h函数第一个参数是组件,第二个是组件的props,第三个是插槽的属性。

    import { createApp, h, ref, reactive } from 'vue';
    // 注意这里替换成存放路径
    import MessageComponent from './MessageComponent.vue';
    
    // 初始消息列表
    interface MessageList {
      type: string;
      title: string;
    }
    const messageList = reactive<MessageList[]>([]);
    // 消息显示时长
    const timer = ref<number>(3000);
    
    // 处理数据
    function handleData(type: string, title: string): void {
      // 数据添加
      messageList.push({ type, title });
    
      // 数据删除
      setTimeout(() => {
        if (messageList.length > 0) {
          messageList.shift();
        }
      }, timer.value);
      
      // 创建
      const app = createApp({
        render() {
          return h(MessageComponent, { messageList });
        }
      });
    
      // 容器挂载
        //备注,如果这里没有 #message dom元素,可以动态创建一个,然后挂载
        //const divEle = document.createElement('div')
        //divEle.setAttribute('id', 'customShowLoading')
        // 让我们节点挂载到一个dom元素上
        //document.body.appendChild(divEle)
    
      app.mount('#message');
    }
    
    interface MessageImplements {
      info(title: string): void;
      wraning(title: string): void;
      success(title: string): void;
      error(title: string): void;
    }
    
    class MessageClass implements MessageImplements {
      // 普通提示
      info(title: string): void {
        handleData('info', title);
      }
    
      // 警告提示
      wraning(title: string): void {
        handleData('wraning', title);
      }
    
      // 成功提示
      success(title: string): void {
        handleData('success', title);
      }
    
      // 错误提示
      error(title: string): void {
        handleData('error', title);
      }
    }
    
    const Message = new MessageClass();
    
    export default Message;
    
    

    3.MessageComponent.vue, 弹框内容部分

    注:< script lang=“ts” setup=“props”></ script> 是 setup(){} 入口函数的语法糖写法(实验性新特性)

    <template>
      <ul class="message-list">
        <li
          :class="`message-item ${setClass(item.type)}`"
          v-for="(item, index) in messageList"
          :key="index"
        >
          {{ item.title }}
        </li>
      </ul>
    </template>
    
    <script lang="ts" setup="props">
    import { reactive } from 'vue';
    
    interface MessageList {
      type: string;
      title: string;
    }
    
    declare const props: {
      messageList: {
        type: Array<MessageList[]>;
        default: [];
      };
    };
    
    export function setClass(type: string): string {
      if (type === 'info') {
        return 'message-info-item';
      } else if (type === 'wraning') {
        return 'message-wraning-item';
      } else if (type === 'success') {
        return 'message-success-item';
      } else if (type === 'error') {
        return 'message-error-item';
      }
    
      return '';
    }
    </script>
    
    <style lang="less" scoped>
    .message-list {
      position: fixed;
      top: 24px;
      right: 24px;
      z-index: 1000;
      max- 200px;
      margin-bottom: 0;
      text-align: right;
      .message-item {
        display: inline-block;
        padding: 12px 24px;
        border: 1px solid #b3d0cf;
        margin-left: 8px;
        margin-bottom: 12px;
        background-color: #e6f3ff;
        font-size: 14p;
        color: #007bff;
        text-align: left;
        box-shadow: 0 1px 1px 0 hsla(0, 0%, 80.4%, 0.5);
        border-radius: 2px;
        cursor: default;
      }
      .message-info-item {
        border: 1px solid #b3d0cf;
        background-color: #e6f3ff;
        color: #007bff;
      }
      .message-error-item {
        border: 1px solid #e99;
        background-color: #f6e3e3;
        color: #e33;
      }
    }
    </style>
    
    

    4. 使用

    <template>
      <button @click="clickMe">点我</button>
    </template>
    
    <script lang="ts">
    import { defineComponent } from 'vue';
    // 注意这里替换成存放路径
    import Message from '@components/message/index.ts';
    
    export default defineComponent({
      setup() {
        function clickMe(): void {
          Message.info('详情跳转');
        }
        return {
          clickMe
        };
      }
    });
    </script>
    
    
  • 相关阅读:
    defence系列的网游不错,我信网游能挣钱了,做得太好了
    关于Debug和Release之本质区别的讨论
    phpmyadmin设置密码,不用登录直接进入
    北京可以备案什么域名
    如何将本地文件复制到远程服务器听语音
    win7 64位wamp2.5无法启动MSVCR110.DLL丢失听语音
    最大连接数:60 iops:150 什么概念?
    about diigo
    Install Microsoft fonts in Ubuntu Linux
    a crawler base on libevent
  • 原文地址:https://www.cnblogs.com/xm0328/p/15217512.html
Copyright © 2011-2022 走看看