将您的modal 组件实例放入Vue.prototype,然后在您可以访问Vue 实例上下文的任何地方调用show/hide。
以下是一个演示:
let vm = null // the instance for your Vue modal
let timeout = null //async/delay popup
const SModal = {
isActive: false,
show ({
delay = 500,
message = '',
customClass = 'my-modal-class'
} = {}) {
if (this.isActive) {
vm && vm.$forceUpdate()
return
}
timeout = setTimeout(() => {
timeout = null
const node = document.createElement('div')
document.body.appendChild(node)
let staticClass = ''
vm = new this.__Vue({
name: 's-modal',
el: node,
render (h) { // uses render() which is a closer-to-the-compiler alternative to templates
return h('div', {
staticClass,
'class': customClass,
domProps: {
innerHTML: message
}
})
}
})
}, delay)
this.isActive = true
},
hide () {
if (!this.isActive) {
return
}
if (timeout) {
clearTimeout(timeout)
timeout = null
} else {
vm.$destroy()
document.body.removeChild(vm.$el)
vm = null
}
this.isActive = false
},
__Vue: null,
__installed: false,
install ({ $my, Vue }) {
if (this.__installed) { return }
this.__installed = true
$my.SModal = SModal // added your SModal object to $my
this.__Vue = Vue //get the Vue constructor
}
}
let installFunc = function (_Vue, opts = {}) {
if (this.__installed) {
return
}
this.__installed = true
const $my = {
'memo': 'I am a plugin management.'
}
if (opts.plugins) {
Object.keys(opts.plugins).forEach(key => {
const p = opts.plugins[key]
if (typeof p.install === 'function') {
p.install({ $my, Vue: _Vue })
}
})
}
_Vue.prototype.$my = $my
}
Vue.use(installFunc, {
plugins: [SModal]
})
app = new Vue({
el: "#app",
data: {
'test 1': 'Cat in Boots'
},
methods: {
openModal: function () {
this.$my.SModal.show({'message':'test', 'delay':1000})
},
closeModal: function () {
this.$my.SModal.hide()
}
}
})
.my-modal-class {
position:absolute;
top:50px;
left:20px;
width:100px;
height:100px;
background-color:red;
z-index:9999;
}
<script src="https://unpkg.com/vue@2.5.16/dist/vue.js"></script>
<div id="app">
<button @click="openModal()">Open Modal!!!</button>
<button @click="closeModal()">Close Modal!!!</button>
</div>
vue-cli 项目的粗略步骤:
在./plugins/SModal.js中(按照官方文档中的教程创建一个vue实例然后添加到document.body):
let vm = null // the instance for your Vue modal
let timeout = null //async/delay popup
const SModal = {
isActive: false,
show ({
delay = 500,
message = '',
customClass = ''
} = {}) {
if (this.isActive) {
vm && vm.$forceUpdate()
return
}
timeout = setTimeout(() => {
timeout = null
const node = document.createElement('div')
document.body.appendChild(node)
vm = new this.__Vue({
name: 's-modal',
el: node,
render (h) { // uses render() which is a closer-to-the-compiler alternative to templates
return h('div', {
staticClass,
'class': props.customClass
})
}
})
}, delay)
this.isActive = true
},
hide () {
if (!this.isActive) {
return
}
if (timeout) {
clearTimeout(timeout)
timeout = null
} else {
vm.$destroy()
document.body.removeChild(vm.$el)
vm = null
}
this.isActive = false
},
__Vue: null,
__installed: false,
install ({ $my, Vue }) {
if (this.__installed) { return }
this.__installed = true
$my.SModal = SModal // added your SModal object to $my
this.__Vue = Vue //get the Vue constructor
}
}
export default SModal
作为the official document said,Vue.js 插件应该公开一个安装方法。该方法将使用 Vue 构造函数作为第一个参数以及可能的选项来调用
在 install.js 中(您也可以根据您的设计将此方法移动到 main.js 中):
// loop all plugins under the folder ./plugins/, then install it.
export default function (_Vue, opts = {}) {
if (this.__installed) {
return
}
this.__installed = true
const $my = {
'memo': 'I am a plugin management.'
}
if (opts.plugins) {
Object.keys(opts.plugins).forEach(key => {
const p = opts.plugins[key]
if (typeof p.install === 'function') {
p.install({ $my, Vue: _Vue })
}
})
}
_Vue.prototype.$my = $my
}
在 main.js 中(最终使用您的插件):
import install from './install'
import * as plugins from './plugins'
Vue.use({ install }, {
plugins
})
最后在您的视图/组件中,您可以像这样显示/隐藏您的模式:
this.$my.SModal.show()
this.$my.SModal.hide()