相信很多人用vuejs構(gòu)建單頁應(yīng)用時(shí)都會(huì)用到一些全局方法,比如發(fā)ajax請(qǐng)求時(shí)喜歡用axios掛載到vue原型上鸟召,如下:
// 1 引入vue和axios
import Vue from 'vue'
import axios from 'axios'
// 2 對(duì)axios的一些封裝
// code ...
// 3 然后掛載到原型上
Vue.prototype.$axios = axios
用的時(shí)候就直接上this.$axios
// 用axios.get()方法可以這樣用
this.$axios.get()
這樣確實(shí)方便,不用每個(gè)用到axios的組件都去引入
類似如此膜钓,當(dāng)我們要用到一些操作dom的方法時(shí)要怎么做呢桃煎,上面的例子純屬js的封裝,沒有涉及到dom笤受;下面我用一個(gè)全局提示組件為例穷缤,類似element-ui的message組件為大家演示一遍如何封裝一個(gè)包含操作dom的的全局組件的,步驟主要有3步:
1, 在componenets/Message 目錄下新建一個(gè)Message.vue組件
<template>
<transition name="fade">
<div class="message" :class="type" v-show="show">
<i class="icon"></i>
<span class="text">{{text}}</span>
</div>
</transition>
</template>
<script type="text/ecmascript-6">
export default {
name: 'message',
props: {
type: {
type: String,
default: 'info',
validator: val => ['info', 'success', 'warning', 'error'].includes(val)
//['info', 'success', 'warning', 'error'] 表示type只接收這四個(gè)字符串作為參數(shù)傳入message組件
},
text: {
type: String,
default: ''
},
show: {
type: Boolean,
default: false
}
}
}
</script>
<style scoped lang="stylus">
@import "~@/common/style/global.styl"
// fade動(dòng)畫 <transition name="fade"> </transition>
// 下面的樣式可以自己改
.fade-enter-active,
.fade-leave-active
transition: opacity .3s
.fade-enter,
.fade-leave-to
opacity: 0
.message
position fixed
top 40px
text-align center
left 50%
transform translateX(-50%)
min-width 400px
padding 10px 20px
color $strong-text-color
background #f5f5f5
font-size 14px
line-height 1.4
border-radius 4px
z-index 1000
box-shadow 0 0 10px rgba(0, 0, 0, .3)
&.info
color $strong-text-color
&.success
color $success-color
&.error
color $danger-color
&.warning
color $warning-color
</style>
2, 在componenets/Message目錄準(zhǔn)備一個(gè)index.js
import Message from './Message.vue'
const MESSAGE = {
duration: 3000, // 顯示的時(shí)間 ms
animateTime: 300, // 動(dòng)畫時(shí)間,表示這個(gè)組件切換show的動(dòng)畫時(shí)間
install(Vue) {
if (typeof window !== 'undefined' && window.Vue) {
Vue = window.Vue
}
Vue.component('Message', Message)
function msg(type, text, callBack) {
let msg
let duration = MESSAGE.duration
if (typeof text === 'string') {
msg = text
} else if (text instanceof Object) {
msg = text.text || ''
if (text.duration) {
duration = text.duration
}
}
let VueMessage = Vue.extend({
render(h) {
let props = {
type,
text: msg,
show: this.show
}
return h('message', {props})
},
data() {
return {
show: false
}
}
})
let newMessage = new VueMessage()
let vm = newMessage.$mount()
let el = vm.$el
document.body.appendChild(el) // 把生成的提示的dom插入body中
vm.show = true
let t1 = setTimeout(() => {
clearTimeout(t1)
vm.show = false //隱藏提示組件箩兽,此時(shí)會(huì)有300ms的動(dòng)畫效果津肛,等動(dòng)畫效果過了再從body中移除dom
let t2 = setTimeout(() => {
clearTimeout(t2)
document.body.removeChild(el) //從body中移除dom
newMessage.$destroy()
vm = null // 設(shè)置為null,好讓js垃圾回收算法回收汗贫,釋放內(nèi)存
callBack && (typeof callBack === 'function') && callBack()
// 如果有回調(diào)函數(shù)就執(zhí)行身坐,沒有就不執(zhí)行,用&&操作符落包,
// 只有&&左邊 的代碼為true才執(zhí)行&&右邊的代碼部蛇,避免用面條代碼:
// if(true){
// ...
// if(true){
// ...
// }
// }
}, MESSAGE.animateTime)
}, duration)
}
// 掛載到vue原型上,暴露四個(gè)方法
Vue.prototype.$message = {
info(text, callBack) {
if (!text) return
msg('info', text, callBack)
},
success(text, callBack) {
if (!text) return
msg('success', text, callBack)
},
error(text, callBack) {
if (!text) return
msg('error', text, callBack)
},
warning(text, callBack) {
if (!text) return
msg('warning', text, callBack)
}
}
}
}
export default MESSAGE
上面的代碼關(guān)鍵點(diǎn)就是用Vue.extend()構(gòu)造出一個(gè)Vue子類實(shí)例咐蝇,(注意我這里模板渲染只用到render函數(shù)涯鲁,沒有用template選項(xiàng),因?yàn)閠emplate選項(xiàng) 要求裝Vue時(shí)要加入模板編譯器那塊代碼,用render函數(shù)更加簡(jiǎn)潔,只需要裝運(yùn)行時(shí)版本撮竿,Vue體積更加小)吮便;然后調(diào)用$mount()方法生成需要的dom,再拿到對(duì)應(yīng)的$el,實(shí)例內(nèi)部自己維護(hù)插入dom和移除dom的操作,對(duì)外暴露了四個(gè)方法info幢踏、success髓需、error、warning方便不同的場(chǎng)景調(diào)用房蝉;類似的組件還有confrim組件僚匆、alert組件等,大同小異搭幻。
3咧擂,在main.js中引入components/Message/index.js,以插件形式安裝
import Vue from 'vue'
import vMessage from './components/Message/index'
Vue.use(vMessage)
最后,當(dāng)你需要用的時(shí)候就直接檀蹋,特別適合在ajax回調(diào)函數(shù)里面用來提示
this.$message.info('普通消息')
this.$message.error('錯(cuò)誤消息')
this.$message.warning('警告消息')
this.$message.success('成功消息')