撸一个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'
  }
})
复制代码

哈哈哈,大功告成!!!此处应有🍗🍗🍗

相关文章
相关标签/搜索