擼一個toast組件(vue)

第一次寫文章,不喜少噴😅,最好不噴,哈哈哈。若有錯誤,還請大佬提出,🙏🙏前端

做爲一個前端開發,開發調試中console.log()還有alert(),不能再熟悉了,要是想在頁面輸出一個彈框,不能一直alert()吧,太反人類了,做爲直男審美的我都接受不了,其實公司封裝好了一個toast組件,可是最近在弄本身的畢業設計,就想本身也封裝一個吧,😂就是想本身折騰折騰,絕對不是爲了kpi!!! 第一個圖是alert(),微信端還有手機瀏覽器都不同,總之調試的時候無所謂,可是想上線或者一個完整的項目,彈框確定是有的,那就動手擼一個吧。 vue

就模仿我司的toast寫一個組件吧,至少看上去還能看(😂直男審美),但是修改樣式,修改時間,總之就是可配置。

一. 新建一個Toast.vue文件

Toast.vue命名習慣很重要,以前一直被吐槽,組件仍是首字母大寫吧。一個好的編程習慣可讓你更好的進行團隊開發,尤爲是codeReview的時候。編程

<template>
  <div class="toast-item">hello world !</div>
</template>

<script>
export default {
  name: 'Toast'
</script>

<style scoped>
.toast-item {
  margin-bottom: 15px;
  padding: 10px 20px;
  line-height: 25px;
  color: #FFF;
  background-color: rgba(0, 0, 0, .9);
  border-radius: 5px;
  transition: all .3s;
}
</style>


複製代碼

二. 樣式查看

這就是一個普通的vue文件,在使用的地方註冊一下,就能看到頁面,調整樣式,這裏就不用多說了。瀏覽器

三. ToastList.vue文件

以前看到一篇文章,每次彈窗都會在body後添加一個新的div,感受性能不是很好,我使用這個文件,將toast的值傳進來,這樣就只添加一個div,只是改變div的內容bash

<template>
  <transition-group tag="div" class="toast-list" name="toast" v-bind="options">
    <toast-item v-for="toast in toasts" :key="toast.message" v-bind="toast" @remove="remove(toast)" />
  </transition-group>
</template>

<script>
import ToastItem from './Toast'

export default {
  name: 'ToastList',

  components: { ToastItem },

  props: ['options'],

  data () {
    return {
      toasts: []
    }
  },

  created () {
    document.body.appendChild(this.$mount().$el)
  },

  destroyed () {
    document.body.removeChild(this.$el)
  },

  methods: {
    add (toast = {}) {
      const { message } = toast

      if (
        message &&
        this.toasts.every(item => item.message !== message)
      ) {
        this.toasts.push(toast)
      }
    },

    remove (toast) {
      this.toasts = this.toasts.filter(item => item !== toast)
    }
  }
}
</script>

<style scoped>
.toast-list {
  position: fixed;
  top: 50px;
  left: 0;
  z-index: 9999;
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  pointer-events: none;
}

.toast-enter, .toast-leave-to {
  opacity: 0;
  transform: translate3d(0, -5px, 0);
}

.toast-leave-active {
  position: absolute;
}
</style>

複製代碼

四. 動態傳值

toast彈出的文字是須要動態傳進來的,因此,把以前的Toast.vue文件修改一下微信

<template>
  <div class="toast-item">{{ message }}</div>
</template>

<script>
export default {
  name: 'Toast',

  props: {
    message: String,
    duration: {
      type: Number,
      default: 2000
    }
  },

  mounted () {
    if (this.duration) {
      setTimeout(() => this.$emit('remove'), this.duration)
    }
  }
}
</script>

<style scoped>
.toast-item {
  margin-bottom: 15px;
  padding: 10px 20px;
  line-height: 25px;
  color: #FFF;
  background-color: rgba(0, 0, 0, .9);
  border-radius: 5px;
  transition: all .3s;
}
</style>

複製代碼

五. 如何加載組件

剛剛只是寫的一個靜態的vue文件,但是這並非咱們須要的效果,如今的需求是動態加載這個組件 在當前目錄新建一個index.js(和Toast.vue等同級),直接放代碼了 爲了是組件能夠複用,樣式就不能寫死,尤爲是面對不一樣的甲方爸爸,有時候只要改個背景色,有時候改個位置,那就設置一個屬性toast.listOptions專門來調整樣式吧app

import Vue from 'vue'
import ToastList from './ToastList'

let toastList

function toast (arg) {
  if (!toastList) {
    toastList = new Vue({
      extends: ToastList,
      propsData: {
        options: toast.listOptions
      }
    })
  }

  const toastItem = typeof arg === 'string'
    ? { message: arg }
    : arg

  toastList.add(toastItem)
}

toast.listOptions = {}
//注意這邊export出來的是toast
export default toast

複製代碼

六. 使用

到這裏,咱們已經基本上完成了一個能夠全局註冊和動態加載的toast組件,只須要在頁面中import一下性能

import toast from '../components/toast/index.js'

toast('Error !')

// custom options
toast({
  message: 'Error !',

  // auto close after 2000ms
  duration: 2000,

  //change style
  style: {
    color: '#F56C6C',
    background: '#FEF0F0',
    border: '1px solid #FDE2E2'
  }
})
複製代碼

哈哈哈,大功告成!!!此處應有🍗🍗🍗

相關文章
相關標籤/搜索