1. 程式人生 > >vue全域性提示框元件

vue全域性提示框元件

一. 先寫一個普通的vue元件

檔案位置 /src/toast/toast.vue

<template>
  <div class="wrap">我是彈窗</div>
</template>

<style scoped>
  .wrap{
    position: fixed;
    left: 50%;
    top:50%;
    background: rgba(0,0,0,.35);
    padding: 10px;
    border-radius: 5px;
    transform: translate(-50%,-50%);
    color:#fff;
  }
</style>

二. 在我們需要使用的頁面引入元件,方便看效果和錯誤

<template>
  <div id="app">
    <toast></toast>
  </div>
</template>

<script>
  import toast from './toast/toast'
  export default {
    components: {toast},
  }
</script>

三. 實現動態載入元件

我們先在 /src/toast/ 目錄下面,新建一個index.js, 然後在index.js裡面,敲入以下程式碼

檔案位置 /src/toast/index.js

 

import vue from 'vue'

// 這裡就是我們剛剛建立的那個靜態元件
import toastComponent from './toast.vue'

// 返回一個 擴充套件例項構造器
const ToastConstructor = vue.extend(toastComponent)

// 定義彈出元件的函式 接收2個引數, 要顯示的文字 和 顯示時間
function showToast(text, duration = 2000) {

  // 例項化一個 toast.vue
  const toastDom = new ToastConstructor({
    el: document.createElement('div'),
    data() {
      return {
        text:text,
        show:true
      }
    }
  })

  // 把 例項化的 toast.vue 新增到 body 裡
  document.body.appendChild(toastDom.$el)

  // 過了 duration 時間後隱藏
  setTimeout(() => {toastDom.show = false} ,duration)
}

// 註冊為全域性元件的函式
function registryToast() {
  // 將元件註冊到 vue 的 原型鏈裡去,
  // 這樣就可以在所有 vue 的例項裡面使用 this.$toast()
  vue.prototype.$toast = showToast
}

export default registryToast

四.在vue的入口檔案(腳手架生成的話是./src/main.js) 註冊一下元件

檔案位置 /src/main.js

import toastRegistry from './toast/index'

// 這裡也可以直接執行 toastRegistry()
Vue.use(toastRegistry)

五.修改第二步

<template>
  <div id="app">
    <input type="button" value="顯示彈窗" @click="showToast">
  </div>
</template>

<script>
  export default {
    methods: {
      showToast () {
        this.$toast('我是彈出訊息')
      }
    }
  }
</script>

六. 優化

缺少一個動畫,現在的彈出和隱藏都很生硬

我們再對 toast/index.js 裡的showToast函式稍微做一下修改(有註釋的地方是有改動的)

檔案位置 /src/toast/index.js

function showToast(text, duration = 2000) {
  const toastDom = new ToastConstructor({
    el: document.createElement('div'),
    data() {
      return {
        text:text,
        showWrap:true,    // 是否顯示元件
        showContent:true  // 作用:在隱藏元件之前,顯示隱藏動畫
      }
    }
  })
  document.body.appendChild(toastDom.$el)

  // 提前 250ms 執行淡出動畫(因為我們再css裡面設定的隱藏動畫持續是250ms)
  setTimeout(() => {toastDom.showContent = false} ,duration - 1250)
  // 過了 duration 時間後隱藏整個元件
  setTimeout(() => {toastDom.showWrap = false} ,duration)
}

 

然後,再修改一下toast.vue的樣式

檔案位置 /src/toast/toast.vue

<template>
  <div class="wrap" v-if="showWrap" :class="showContent ?'fadein':'fadeout'">{{text}}</div>
</template>

<style scoped>
  .wrap{
    position: fixed;
    left: 50%;
    top:50%;
    background: rgba(0,0,0,.35);
    padding: 10px;
    border-radius: 5px;
    transform: translate(-50%,-50%);
    color:#fff;
  }
  .fadein {
    animation: animate_in 0.25s;
  }
  .fadeout {
    animation: animate_out 0.25s;
    opacity: 0;
  }
  @keyframes animate_in {
    0% {
      opacity: 0;
    }
    100%{
      opacity: 1;
    }
  }
  @keyframes animate_out {
    0% {
      opacity: 1;
    }
    100%{
      opacity: 0;
    }
  }
</style>

總結

看了幾篇唯覺得這篇簡單易懂,搬運過來記錄學習,並分享給大家

  1. vue.extend 函式可以生成一個 元件構造器 可以用這個函式構造出一個 vue元件例項
  2. 可以用 document.body.appendChild() 動態的把元件加到 body裡面去
  3. vue.prototype.$toast = showToast 可以在全域性註冊元件
  4. 顯示動畫比較簡單,隱藏動畫必須要在隱藏之前預留足夠的動畫執行時間


原文連結:感謝作者,遂附原文連結