1. 程式人生 > >從零開始徒手擼一個vue的toast彈窗元件

從零開始徒手擼一個vue的toast彈窗元件

相信普通的vue元件大家都會寫,定義 -> 引入 -> 註冊 -> 使用,行雲流水,一氣呵成,但是如果我們今天是要自定義一個彈窗元件呢?

首先,我們來分析一下彈窗元件的特性(需求):
0. 輕量 –一個元件小於 1Kib (實際打包完不到0.8k)
1. 一般都是多處使用 –需要解決每個頁面重複引用+註冊
2. 一般都是跟js互動的 –無需 在<template>裡面寫 <toast :show="true" text="彈窗訊息"></toast>

今天,我們就抱著上面2個需求點,來實現一個基於vue的toast彈窗元件,下圖是最終完成的效果圖.

step_3

一. 先寫一個普通的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>

step_1

三. 實現動態載入元件

可以看到,已經顯示出一個靜態的彈出層了,接下來我們就來看看如何實現動態彈出.

我們先在 /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

四. 試用

到這裡,我們已經初步完成了一個可以全域性註冊和動態載入的toast元件,接下來我們來試用一下看看

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

檔案位置 /src/main.js

import toastRegistry from './toast/index'

// 這裡也可以直接執行 toastRegistry()
Vue.use(toastRegistry)
  1. 我們稍微修改一下使用方式,把第二步 的引用靜態元件的程式碼,改成如下
<template>
  <div id="app">
    <input type="button" value="顯示彈窗" @click="showToast">
  </div>
</template>

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

step_2

可以看到,我們已經不需要在頁面裡面引入註冊元件,就可以直接使用this.$toast()了.

五. 優化

現在我們已經初步實現了一個彈窗.不過離成功還差一點點,缺少一個動畫,現在的彈出和隱藏都很生硬.

我們再對 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>

大功告成,一個toast元件初步完成

step_3

總結

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

相關推薦

開始徒手一個vue的toast元件

相信普通的vue元件大家都會寫,定義 -> 引入 -> 註冊 -> 使用,行雲流水,一氣呵成,但是如果我們今天是要自定義一個彈窗元件呢? 首先,我們來分析一下彈窗元件的特性(需求): 0. 輕量 –一個元件小於 1Kib (實際打包完不到0

開始仿寫一個抖音App——音視訊開篇

本文於掘金——何時夕,搬運轉載請註明出處,否則將追究版權責任。交流qq群:859640274 GitHub地址 大家好,距離上次本專題發文已經有五個星期了,中間發了兩篇非本專題的文章,可能很多人都以為我要棄坑了。但是並不是這回事,主要是工作有點忙,而且我在音視訊方面其實也有許多東西需要學習和整理。那

開始仿寫一個抖音App——基於FFmpeg的極簡視訊播放器

本文發於掘金——何時夕,搬運轉載請註明出處,否則將追究版權責任。交流qq群:859640274 GitHub地址 好久不見,最近加班比較多所以第二篇音視訊方面的文章 delay 了一週,大家多包涵哈。本文預計閱讀時間二十分鐘。 本文分為以下章節,讀者可以按需閱讀 1.FFmpeg原始碼

Python+Flask+Gunicorn 專案實戰(一) 開始,寫一個Markdown解析器 —— 初體驗

      (一)前言 在開始學習之前,你需要確保你對Python, JavaScript, HTML, Markdown語法有非常基礎的瞭解。專案的原始碼你可以在 https://github.com/zhu-y/markdown-toolkit 找到,最後的

開始仿寫一個抖音App——跨平臺視訊編輯SDK專案搭建

本文發於掘金——何時夕,搬運轉載請註明出處,否則將追究版權責任。交流qq群:859640274 GitHub地址 不知不覺已經到了2019年,本系列的文章也更新到了8篇。很慶幸筆者能堅持下來,從我司的程式碼中學習到了很多東西。當然更慶幸的是收穫了眾多讀者的鼓勵和支援。從本篇文章開始,我們將接觸短視訊

使用asp.net開始製作設計一個網站之一

使用ASP.NET從零開始製作設計網站之一 (蔣惠全 楚東明) ☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆    小問號:蔣老師,告訴你一個好訊息,我應聘成功了!謝謝您!回頭再打給您,我要告訴爸媽一聲。

(1/2) 為了理解 UWP 的啟動流程,我開始建立了一個 UWP 程式

每次使用 Visual Studio 的模板建立一個 UWP 程式,我們會在專案中發現大量的專案檔案、配置、應用啟動流程程式碼和介面程式碼。然而這些檔案在 UWP 程式中到底是如何工作起來的? 我從零開始建立了一個 UWP 程式,用於探索這些檔案的用途,瞭解

開始寫第一個Android應用程式

學習Android準備知識 安卓四層系統構成: 第一層:最底層 Linux層 第二層:函式庫層 由C或者C++寫 第三層:Application FrameWork 應用框架層 第四層:最上層 應用層 在很久以前,安卓還是用的jvm虛擬機器,但是好景不

webpack 4.x 開始初始化一個vue專案

建立目錄 專案名稱: vue-init app css reset.sass js home index.vue router index.js main.js App.vue views index.html 安裝webpack npm i -D webpack 建立配置檔案 w

開始一個App】Dagger2

Dagger2是一個IOC框架,一般用於Android平臺,第一次接觸的朋友,一定會被搞得暈頭轉向。它延續了Java平臺Spring框架程式碼碎片化,註解滿天飛的傳統。嘗試將各處程式碼片段串聯起來,理清思緒,真不是件容易的事。更不用說還有各版本細微的差別。 *與Spring不同的是,Spring是通過反射建立

開始一個App】PKCE

一個成功的App背後肯定有一堆後端服務提供支撐,認證授權服務(Authentication and Authorization Service,以下稱`AAS`)就是其中之一,它是約束App、保障資源安全的必備元件。現在也有第三方平臺提供此類服務,但萬事不求人,自己擼才是我們的風格。 *本文假設讀者有一定的O

開始一個App】Kotlin

工欲善其事必先利其器。像我們從零開始擼一個App的話,選擇最合適的語言是首要任務。如果你跟我一樣對Java蹣跚的步態和僵硬的語法頗感無奈,那麼Kotlin在很大程度上不會令你失望。雖然為了符合JVM規範和相容Java,它引入了一些較為複雜的概念和語法,很多同學就是因此放棄入門。其實越深入進去,就會越欲罷不能。

開始一個App】Fragment和導航中的使用

## Fragment簡介 `Fragment`自從Android 3.0引入開始,它所承擔的角色就是顯而易見的。它之於`Activity`就如html片段之於頁面,好處無需贅述。 Fragment例項由Activity的`FragmentManager`管理,其生命週期和Activity一樣,都不是由開

開始構建一個的asp.net Core 項目(二)

mage .... cfi web execute 運行 figure 今天 deb 接著上一篇博客繼續進行。上一篇博客只是顯示了簡單的MVC視圖頁,這篇博客接著進行,連接上數據庫,進行簡單的CRUD。 首先我在Controllers文件夾點擊右鍵,添加->控制器 彈

開始unity特效

分享 小說 dem 世界 ima 9.png log diy 坐標 畢業到現在,三年多沒碰3d渲染了,猛然發現當初問我學編程該先學哪門語言的人已經看paper如看小說了,而我還在看小說。。。深感慚愧,遂決定補課,計劃在盡可能短的時間內把主要理論淺擼輒止,同時每部分琢磨出一個

開始一個Jmeter性能測試

conf ber img group 測試報告 響應 介紹 oop 系統環境 安裝Jmeter 1、下載地址http://jmeter.apache.org/download_jmeter.cgi 2、解壓下載文件,然後將bin目錄添加到系統環境變量PATH裏。 3、確保已

[閑的蛋疼系列]開始用TypeScript寫React的UI組件(0)-先寫一個Button??

component extension lap exp closed struct app target 參數 0.鹹魚要說的 一入前端深似海,鹹魚入海更加鹹。 最近閑的蛋疼,手上年前的事也完成了7788了,借助[PG1]的話來說,我們要keep real. 鹹魚肯定不

開始構建一個centos+jdk7+tomcat7的docker鏡像文件

entos 命名 doc 讀取 com 工作目錄 perm 後臺運行 star 從零開始構建一個centos+jdk7+tomcat7的鏡像文件 centos7系統下docker運行環境的搭建 準備centos基礎鏡像 docker pull centos 或者直接下載我

手把手教你開始一個好看的 APP

@+ error 教你 教授 wip rac tco 需要 apt 前言 從零開始,手把手帶你實現一個「專註睡前的 APP」。睡覺之前如果能有一個 APP,能讓我們寫一寫這一天的見聞或者心得,同時又能看一會段子、瞄一會好看的妹子,放松一下疲憊的身心那該多好,這也是我完成這

vue-用Vue-cli開始搭建一個Vue項目

-a htm sset VM bin size 過多 sets 掃描   Vue是近兩年來比較火的一個前端框架(漸進式框架吧)。 Vue兩大核心思想:組件化和數據驅動。組件化就是將一個整體合理拆分為一個一個小塊(組件),組件可重復使用;數據驅動是前端的未來發展方向,釋放了對