第一次寫文章,不喜少噴😅,最好不噴,哈哈哈。若有錯誤,還請大佬提出,🙏🙏前端
做爲一個前端開發,開發調試中console.log()
還有alert()
,不能再熟悉了,要是想在頁面輸出一個彈框,不能一直alert()
吧,太反人類了,做爲直男審美的我都接受不了,其實公司封裝好了一個toast組件,可是最近在弄本身的畢業設計,就想本身也封裝一個吧,😂就是想本身折騰折騰,絕對不是爲了kpi!!! 第一個圖是alert()
,微信端還有手機瀏覽器都不同,總之調試的時候無所謂,可是想上線或者一個完整的項目,彈框確定是有的,那就動手擼一個吧。 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文件,在使用的地方註冊一下,就能看到頁面,調整樣式,這裏就不用多說了。瀏覽器
以前看到一篇文章,每次彈窗都會在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'
}
})
複製代碼