vue做移动端经常碰到弹窗的需求, 这里写一个功能简单的vue弹窗
popup.vue
<template><div class="popup-wrapper" v-show="visible" @click="hide"><div class="popup-text">{{text}}</div></div>
</template>
组件html结构, 外层divposition:fixed
定位, 内层div显示弹窗内容
export default {name: 'popup',props: {text: { //文字内容type: String,default: ''},time: { //显示的时长type: Number,default: 3e3},},data(){return {visible: false}},methods: {open() {this.visible = trueclearTimeout(this.timeout);this.$emit('show')if(this.time > 0){this.timeout = setTimeout(() => {this.hide()}, this.time)}},hide() {this.visible = falsethis.$emit('hide')clearTimeout(this.timeout);}}
}
popup.vue只有2个属性: 文本和显示时间。组件显示隐藏由内部属性visible控制,只暴露给外界open和hide2个方法,2个方法触发对应的事件
测试一下
<template><popup ref="popup" text="弹窗内容" :time="1e3"></popup>
</template>
<script>
import Popup from '@/components/popup'...this.$refs.popup.open()...
</script>
插件化
组件功能写好了,但是这种调用方式显得很累赘。举个例子layer.js的调用就是layer.open(...)没有import,没有ref,当然要先全局引用layer。我们写的弹窗能不能这么方便呢,为此需要把popup改写成vue插件。
说是插件,但能配置属性调用方法的还是组件本身,具体是实例化的组件,而且这个实例必须是全局单例,这样不同vue文件唤起popup的时候才不会打架
生成单例
// plugins/popupVm.js
import Popup from '@/components/popup'
let $vm
export const factory = (Vue)=> {if (!$vm) {let Popup = Vue.extend(PopupComponent)$vm = new Popup({el: document.createElement('div')})document.body.appendChild($vm.$el)}return $vm
}
组件实例化后是添加在body上的,props
不能写在html里需要js去控制,这里写个方法让属性默认值继续发挥作用
// plugins/util.js
export const setProps = ($vm, options) => {const defaults = {}Object.keys($vm.$options.props).forEach(k => {defaults[k] = $vm.$options.props[k].default})const _options = _.assign({}, defaults, options)for (let i in _options) {$vm.$props[i] = _options[i]}
}
// plugins/popupPlugin.js
import { factory } from './popupVm'
import { setProps } from './util'export default {install(Vue) {let $vm = factory(Vue);const popup = {open(options) {setProps($vm, options)//监听事件typeof options.onShow === 'function' && $vm.$once('show', options.onShow);typeof options.onHide === 'function' && $vm.$once('hide', options.onHide);$vm.open();},hide() {$vm.hide()},//只配置文字text(text) {this.open({ text })}}Vue.prototype.$popup = popup}
}
在main.js内注册插件
//main.js
import Vue from 'vue'
import PopupPlugin from '@/plugins/popupPlugin'Vue.use(PopupPlugin)
在vue框架内调用就非常方便了
<script>...this.$popup.text('弹窗消息')...
</script>