Vue custom component getting started

Define the custom component MessageBox in vue file

this file named MessageBox.vue

  1<template>
  2  <transition name="fade-in" mode="out-in">
  3    <div
  4      v-if="show"
  5      :class="['alert', 'notification', 'is-' + type]"
  6      :style="{ transform: 'translate(-50%,' + offset + 'px)' }"
  7    >
  8      <button
  9        @click="() => (this.show = !this.show)"
 10        v-show="this.showBtn"
 11        class="delete"
 12      ></button>
 13      <p v-html="message"></p>
 14    </div>
 15  </transition>
 16</template>
 17
 18<script>
 19export default {
 20  name: "MessageBox",
 21  props: {
 22    message: {
 23      thype: String,
 24      required: true,
 25    },
 26    type: {
 27      type: String,
 28      default: "default",
 29    },
 30    offset: {
 31      type: Number,
 32      default: 20,
 33    },
 34    showBtn: {
 35      type: Boolean,
 36      default: true,
 37    },
 38  },
 39  data() {
 40    return {
 41      show: true,
 42    };
 43  },
 44  methods: {
 45    isShow(status) {
 46      this.show = status;
 47    },
 48  },
 49};
 50</script>
 51
 52<style scoped>
 53.alert {
 54  /*width: 380px;*/
 55  height: fit-content;
 56  position: fixed;
 57  left: 50%;
 58  transform: translate(-50%);
 59  top: 20px;
 60  padding: 0.5rem;
 61  border: 1px solid transparent;
 62  border-radius: 0.25rem;
 63  z-index: 99999;
 64}
 65
 66
 67.alert p {
 68  padding: 0.2rem 0rem;
 69  padding-right: 1.5rem;
 70  /*width: 350px;*/
 71  font-size: .8em;
 72  word-break: break-all;
 73  text-align: left;
 74}
 75
 76
 77.alert .close-btn {
 78  position: absolute;
 79  top: 0.2rem;
 80  right: 0;
 81  padding: 0.2rem 0.5rem;
 82  margin-left: 0.2rem;
 83  background-color: transparent;
 84  border: none;
 85  font-size: 1.5rem;
 86  cursor: pointer;
 87  transform: translate(-50%);
 88}
 89
 90.close-btn:hover {
 91  color: red;
 92}
 93
 94.alert-default {
 95  color: #004085;
 96  background-color: #cce5ff;
 97  border-color: #b8daff;
 98}
 99
100.alert-success {
101  color: #155724;
102  background-color: #d4edda;
103  border-color: #c3e6cb;
104}
105.alert-warning {
106  color: #856404;
107  background-color: #fff3cd;
108  border-color: #ffeeba;
109}
110
111.alert-error {
112  color: #721c24;
113  background-color: #f8d7da;
114  border-color: #f5c6cb;
115}
116
117.fade-in-enter-active,
118.fade-in-leave-active {
119  transition: all 0.5s;
120}
121
122.fade-in-enter,
123.fade-in-leave-to {
124  top: 0;
125  opacity: 0;
126  transform: translate(-50%, 0);
127}
128</style>

Registe global component to vue context

 1import MessageBox from '../components/MessageBox.vue'
 2import { createApp } from 'vue';
 3
 4const componetns = [MessageBox];
 5
 6const messageQueen = [];
 7export default (app) => {
 8
 9  //register global component
10  componetns.forEach((component) => {
11    app.component(component.name, component);
12  });
13  //mount instance of componet
14  app.config.globalProperties.$message = {
15    warning(data) {
16      app.config.globalProperties.$show({ message: data.message, type: "warning", duration: data.duration, showBtn: data.showBtn});
17    },
18    success(data) {
19      app.config.globalProperties.$show({ message: data.message, type: "success", duration: data.duration, showBtn: data.showBtn});
20    },
21    error(data) {
22      app.config.globalProperties.$show({ message: data.message, type: "danger", duration: data.duration, showBtn: data.showBtn });
23    },
24    default(data) {
25      app.config.globalProperties.$show({ message: data.message, type: "info", duration: data.duration, showBtn: data.showBtn });
26    },
27  };
28  app.config.globalProperties.$show = (props) => {
29    // add the pop window queen
30    if (!messageQueen.length) {
31      messageQueen.push(20);
32    } else {
33      messageQueen.push(messageQueen[messageQueen.length - 1] + 20 + 48);
34    }
35    const tempDiv = document.createElement('div');
36    let MessageBoxInstance = createApp(MessageBox, {
37      ...props,
38      offset: !messageQueen.length ? 20 : messageQueen[messageQueen.length - 1]
39    }).mount(tempDiv);
40
41    document.body.appendChild(MessageBoxInstance.$el);
42    // show messagebox
43    MessageBoxInstance.isShow(true);
44    setTimeout(() => {
45      // pop stack current messagebox
46      messageQueen.shift();
47      // destory messagebox
48      MessageBoxInstance.isShow(false);
49    }, props.duration ? props.duration : 3000);
50  };
51
52};

Initialization the global custom component in entry js file main.js

 1import { createApp } from 'vue'
 2import { createStore } from 'vuex'
 3import messageBox  from './utils/messageBox'
 4import App from './App.vue'
 5
 6
 7const app = createApp(App)
 8
 9messageBox(app)
10
11app.mount('#app')
12export {app}

Use the global custom component in project or other component

 1 // method one
 2 this.$message.error({message: mess, duration: 5000})
 3 // method two
 4 import { getCurrentInstance } from 'vue'
 5 const instance = getCurrentInstance();
 6
 7 const onSubmit = () => {
 8   let gp = instance.appContext.app.config.globalProperties;
 9   gp.$message.warning({message:"No changed..."})
10 }