是否可以从组件外部调用方法以使组件可重用?
现在我添加我的按钮以在模板槽中打开模态:
index.php
<modal>
<template slot="button">
<button class="btn">Open modal</button>
</template>
Some modal text
</modal>
Modal.vue
<template>
<div>
<div @click="showModal"><slot name="button"></slot></div>
<div v-if="showingModal"><slot></slot></div>
</div>
</template>
<script>
export default {
data () {
return {
showingModal: false,
}
},
methods: {
showModal() {
this.showingModal = true;
},
}
}
</script>
我觉得有更好的选择,但我无法弄清楚。
答案 0 :(得分:5)
是的,您可以从组件外部调用方法!
父组件
<template>
<div>
<modal ref="modal"></modal>
<button @click="openModal">Open Modal</button>
</div>
</template>
<script>
import modal from './child.vue'
export default {
components: { modal }
methods: {
openModal() { this.$refs.modal.show() }//executing the show method of child
}
}
</script>
子组件
<template>
<div v-if="showModal">
<div id="modal">
<p>Hello i am a modal
</p>
<button @click="hide">Close</button>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showModal: false
}
},
methods: {
show() {
this.showModal = true
},
hide(){
this.showModal = false
}
}
}
</script>
答案 1 :(得分:1)
我更喜欢在这里使用vue plugin(对于单实例模态)。
以下是一个演示:
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()
}
}
})
&#13;
.my-modal-class {
position:absolute;
top:50px;
left:20px;
width:100px;
height:100px;
background-color:red;
z-index:9999;
}
&#13;
<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>
&#13;
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()
答案 2 :(得分:0)
当然,接受模态组件的属性:
props: ['open']
然后传入:
<modal :open="boolToOpenModal"> ... </modal>
然后:
<div v-if="showingModal || open"><slot></slot></div>
答案 3 :(得分:0)
没有(简单,支持)方法来调用组件中的方法,但您可以修改子项中的属性(例如data want ;
infile "C:\Users\komal\Desktop\&b" dsd firstobs=5 obs=14 truncover ;
input ID Gender $ Age Height Weight Year ;
run;
)(请参阅Passing Data to Child Components with Props)或使用事件(请参阅Custom Events,$emit和$refs)。使用事件您还可以使用event bus。基于事件的解决方案当然更适合更复杂的交互。
答案 4 :(得分:0)
我只是将v-on="$listeners"
添加到子组件(modal.vue)中:
// modal.vue
<template>
<div :show="show" v-on="$listeners">
...
</div>
</template>
<script>
export default {
props: {
show: {
type: Boolean,
default: false
}
},
...
现在,您可以轻松地从其父级打开或关闭模式:
//parent.vue
<modal @close="showModal = false" :show="showModal" />