简体   繁体   中英

Using vue-js-modal, how do I access the data passed to the modal?

In my vue.js app, I need to show custom data inside a modal. I am using vue-js-modal to be able to show a modal from anywhere inside my app: https://www.npmjs.com/package/vue-js-modal

I have created a very simple custom modal template to try it out, called ItemModal.vue :

<template>
    <modal name="item-modal">
        <b>{{item.name}}</b>
    </modal>
</template>
<script>
    export default {
        name: 'item-modal',
        props: [ 'item' ]
    }
</script>

And I am able to successfully call it from inside my ItemList.vue component:

<template>
    <div id="content">
        <item-modal></item-modal>
        <li v-for="item in items">
            <a v-on:click="showModal( item )">
                <span>{{item.name}}</span>
            </a>
        </li>
    </div>
</template>
<script>
    import ItemModal from './ItemModal.vue';
    import Items from '@/api/items';

    export default {
        name: 'items',
        asyncComputed: {
            items: {
                async get() {
                    const items = await Items.getAll();
                    return items.data;
                },
                default: []
            }
        },
        methods: {
            showModal( item ) {
                this.$modal.show('item-modal', { item: item } );
            }
        },
        components: {
            ItemModal
        }
    }
</script>

However, the modal comes up empty.

What am I missing in ItemModal.vue to be able to use the data that I'm passing to it within the showModal function?

You should register the plugin in the main.js file of your project, in this way:

import VModal from 'vue-js-modal'
Vue.use(VModal)

Then you would be able to call the show function in any place of your project:

this.$modal.show('the-name-you-asigned-in-your-modal');

If you need to pass params to the modal you can easy receive them in the beforeOpen event handler:

//In the template    
<modal name="hello-world" @before-open="beforeOpen"/>


methods: {
  beforeOpen (event) {
    console.log(event.params.foo);
  }
}

I know you are pretty close to make it work, so I provide you with a working example so you can take it as reference:

1- Include plugin in your main.js file.

// The Vue build version to load with the `import` command
// (runtime-only or standalone) has been set in webpack.base.conf with an alias.
import Vue from 'vue'
import App from './App'

import VModal from 'vue-js-modal'

Vue.config.productionTip = false
Vue.use(VModal)

/* eslint-disable no-new */
new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})

2- Create a component that contains the modal (Let's call it Modal.vue )

<template>
  <modal name="hello-world" @before-open="beforeOpen">
    <div class="wrapper">
      <p>{{ itemToShow }}</p>
    </div>
  </modal>
</template>

<script>
  export default {
    name: 'HelloWorld',

    data: function () {
      return {
          item: ''
      }
    },

    computed: {
      itemToShow: function () {
        return this.item
      }
    },

    methods: {
      beforeOpen (event) {
        this.item = event.params.item;
      }
    }
  }
</script>

<style scoped>
  .wrapper {
    height: 100%;
    width: 100%;
    background-color: black;
  }
</style>

3- Show the modal component

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <Modal />
    <button @click="onClick">
      CLICK HERE!
    </button>
  </div>
</template>

<script>
  import Modal from './components/Modal'

  export default {
    name: 'app',
    components: {
      Modal: Modal
    },
    methods: {
      onClick() {
        this.$modal.show('hello-world', {item: 'Hello world'});
      }
    }
  }
</script>

<style>
  #app {
    font-family: 'Avenir', Helvetica, Arial, sans-serif;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    text-align: center;
    color: #2c3e50;
    margin-top: 60px;
  }
</style>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM