Vue2 - 从组件内部的主实例调用方法

时间:2018-06-03 16:44:13

标签: vue.js vuejs2

我有 Vue 主要实例:

// Components
import Service from './components/Service.vue'
import Modal from './components/Modal.vue'
import EventMessages from './components/EventMessages.vue'
import Media from './components/Media.vue'
import ClinicsList from './components/ClinicsList.vue'

let adminVue = new Vue({
    el: '#admin-app',
    mixins: [Form],
    components: {
        adminService: Service,
        adminMedia: Media,
        adminModal: Modal,
        adminAlerts: EventMessages,
        adminClinicsList: ClinicsList
    },
    methods: {
        notWorking(day){
            $('[data-hoursday=' + day + '] input[type=text]')
                .prop('readOnly', (i, v) => { return !v } )
                .val('00:00')
        },
        generateRandomString(){
            $('input[role=random-string]').val(Math.random().toString(36).substring(2, 10) + Math.random().toString(36).substring(2, 10))
        },
        selectAll(element){
            $('input[role=selectAll').prop('checked', element.checked)
        },
        deleteEntry(element){

            let table = $('.table-content')
            let text  = table.data('text')
            let id    = !Array.isArray(element) ? element.dataset.id : element
            let url   = table.data("url") + '/' + id

            this.$dialog.confirm('Are you sure you want to delete this ' + text +'?', {
                loader: true
            }).then((dialog) => {

                axios.post(url)
                .then((response) => {

                    let data = response.data

                    this.removeElement(id)

                    dialog.close()

                    Event.$emit('message:show', {
                        messageTitle: data.messageTitle,
                        messageText: data.messageText
                    }, data.class)
                })
                .catch((error) => {
                    console.log(error);

                    alert('Something went wrong. Please try again a bit later')
                })

            })
            .catch((error) => {
                console.log('Delete aborted')
            });
        },
        deleteMultiple(){

            let selected = $("input[role=selectAll]:checked").map(function () {
                return $(this).val();
            }).get().filter(element => element !== 'null')

            if(selected.length){
                this.deleteEntry(selected)

                $('input[role=selectAll]').prop('checked', false)
            }

        },
        removeElement(elemenID){

            if(Array.isArray(elemenID)){
                elemenID.forEach((id) => {
                    $('#entryid-' + id).slideUp('fast', () => {
                        $(this).remove()
                    })
                })
            } else {
                $('#entryid-' + elemenID).slideUp('fast', () => {
                    $(this).remove()
                })
            }

        }
    },
    mounted(){
        Event.$on('form:errors:show', (form, errors) => {
            Form.showErrors(form, errors)
        })
    }
})

还有一个组件:

<template>
    <div class="col-md-6">
        <div class="box box-primary">
            <div class="box-header with-border">
                <h3 class="box-title">Service List</h3>

                <div class="box-tools pull-right">
                    <div class="has-feedback">
                    <input type="text" class="form-control input-sm" placeholder="Search Services">
                    <span class="glyphicon glyphicon-search form-control-feedback"></span>
                    </div>
                </div>
            </div>

            <div class="box-body no-padding">

                <div class="mailbox-controls">
                <!-- Check all button -->
                <button type="button" class="btn btn-default btn-sm checkbox-toggle"><i class="fa fa-square-o"></i>
                </button>
                <div class="btn-group">

                  <button type="button"
                    class="btn btn-default btn-sm"
                    @click="deleteMultiple">
                      <i class="fa fa-trash-o"></i>
                  </button>

                </div>
                <!-- /.btn-group -->
                <button type="button" class="btn btn-default btn-sm"><i class="fa fa-refresh"></i></button>

                <div class="pull-right"></div>
                <!-- /.pull-right -->
              </div>

            </div>

            <div class="table-responsive">

                <table id="practice_table"
                  class="table table-bordered table-striped table-content"
                  data-url="/admin/services/destroy"
                  data-text="clinic"
                >

                    <thead>
                        <tr>
                            <td width="35">
                            <input type="checkbox"
                            role="selectAll"
                            value=null
                            @click="selectAll($event.target)">
                            </td>
                            <th>Name</th>
                            <th>Count</th>
                            <th width="150">Action</th>
                        </tr>
                    </thead>

                    <tbody>
                        <tr :id="'entryid-' + service.id"
                            v-for="(service, index) in services" :key="service.id">
                            <td>
                                <input
                                type="checkbox"
                                name="selected[]"
                                :value="service.id"
                                role="selectAll">
                            </td>
                            <td>{{ service.name }}</td>
                            <td>{{ service.count }}</td>
                        </tr>
                    </tbody>

                </table>
            </div>
        </div>


    </div>
</template>

<script>
export default {
    data(){
        return {
            services: []
        }
    },
    methods: {
        getAll(){
            axios.get('/admin/services/all', {})
            .then((response) => {
                this.services = response.data
            })
        },
        openModal(action){

            let url;
            let data = {}

            switch (action) {
                case 'store':
                    url = '/admin/services/create'
                    this.getData(url)
                    break;

                case 'edit':
                    url = '/admin/services/edit/' + event.target.dataset.id
                    this.getData(url)
                    break;

                case 'delete':
                    let serviceID = event.target.dataset.id
                    url = '/admin/services/destroy/' + serviceID

                    this.$dialog.confirm('Are you sure you want to delete this service?',{
                        loader: true
                    })
                    .then((dialog) => {

                        axios.post(url, {
                            id: serviceID
                        })
                        .then((response) => {

                            let data = response.data
                            dialog.close()

                            let serviceIndex = this.services.findIndex(service => serviceID)

                            Vue.delete(this.services, serviceIndex);

                            Event.$emit('message:show', {
                                messageTitle: data.messageTitle,
                                messageText:  data.messageText
                            }, data.class)
                        })
                        .catch((error) => {

                            alert('Something went wrong. Please try again a bit later')
                            dialog.close()
                        })

                    })
                    .catch(() => {
                        alert('Something went wrong. Please try again a bit later')
                    });
                    break;
            }
        },
        save(){

            let form  = $('#service-store')
            let action = form.data('action')

            axios.post(form.attr('action'), {
                name: form.find('#name').val()
            })
            .then((response) => {

               let data = response.data

               switch (action) {
                   case 'store':
                        this.services.unshift({id : data.service.id, name : data.service.name, count: 0})
                       break;

                    case 'update':

                        let serviceIndex = this.services.findIndex(service => service.id === data.service.id)

                        this.services[serviceIndex].name = data.service.name

                       break;
               }

               Event.$emit('modal:hide')

               Event.$emit('message:show', {
                                messageTitle: data.messageTitle,
                                messageText:  data.messageText
                        }, data.class)
            })
            .catch((error) => {
                Event.$emit('form:errors:show', form, error.response.data.errors)
            })
        },
        getData(url){
            axios.get(url, {})
            .then((response) => {
               Event.$emit('modal:show', response.data)
            })
        }
    },
    mounted(){
        this.getAll()

        Event.$on('service:save', () => {
            this.save()
        })
    }
}
</script>

我有办法从组件中调用 @ click = deleteMultiple 吗?

1 个答案:

答案 0 :(得分:0)

您要查找的内容名为event bus,您可以将其创建为从儿童活动中发起parent个事件。

  

它应该支持道具,事件向上(从父母到孩子)。

在您的情况下,例如:

const EventBus = new Vue();

关于您的子组件:

@click="$bus.$emit('deleteMultiple')"

并在父母:

created () {
    this.$bus.$on('deleteMultiple', ($event) => {
        this.deleteMultiple();
    })
  }

互联网上有很多关于不同类型的总线和插件的教程,如:https://medium.com/@andrejsabrickis/https-medium-com-andrejsabrickis-create-simple-eventbus-to-communicate-between-vue-js-components-cdc11cd59860http://vuetips.com/global-event-bus

希望它有所帮助!