source

하위 구성 요소에서 $emit을 사용하여 상위 구성 요소로 데이터를 보내는 것은 Vue에서 작동하지 않음

factcode 2022. 7. 21. 23:32
반응형

하위 구성 요소에서 $emit을 사용하여 상위 구성 요소로 데이터를 보내는 것은 Vue에서 작동하지 않음

탭 구성 요소를 쓰고 있습니다.

데이터를 전송하려고 합니다.sendTabsData()method는 내 코드에 있으며, 어떤 이유로 인해 이 방법은 사용할 수 없습니다.$emit.

탭 구성 요소 코드는 다음과 같습니다.

<template>
    <div id="tabs">
        <div id="tabs-cont">
            <div class="tabbable-panel">
                <div class="tabbable-line">
                    <ul class="nav nav-tabs" role="tablist"> 
                    </ul>
                    <div class="tab-content">
                        <slot></slot>
                    </div>
                </div>
            </div>
        </div> 
    </div> 
</template>

<script>
export default {
    name: 'DashboardTabs',
    props: {
        tabs: {
            type: Object,
            required: true,
            default: {}
        }
    },
    data() {
        return {
            displayed:      '',
            tabName:        '',
            $tabsContainer: null,
            navTabs:        null, 
            tabContent:     null
        }
    },
    created() {
    },
    mounted() {
        this.init();
    },
    watch: {
    },
    methods: {
        init: function() {
            // Fetch UI elements 
            this.$tabsContainer = $('#tabs');
            this.navTabs        = this.$tabsContainer.find('.nav-tabs');
            this.tabContent     = this.$tabsContainer.find('.tab-content');

            this.createTabs(this.tabs);
        },
        // Create tabs by result
        createTabs: function(tabs) {
            if ( this.tabs !== undefined || this.tabs.length > 0 ) {
                this.setTabsBtns(tabs);
            }
        },
        // 
        tabClick: function(e) {
            this.changeDisplayNames(e);         
            this.sendTabsData();
        },
        // Change display names
        changeDisplayNames: function(e) {

            let liItem = e['target']['dataset']['displaytable'];

            if (liItem) {
                // Update variable table name
                this.displayed = liItem;
                // Remove the '$' and 'Table' text
                let tableCategory   = this.displayed.replace('Table', '');
                tableCategory       =  tableCategory.replace('$', '');
                // Update "global" variable of the current table
                this.tabName        = tableCategory.charAt(0).toUpperCase() + tableCategory.slice(1);
            }
        }, 
        // Set tabs li btns 
        setTabsBtns: function(tabs) {

            for (let key in tabs) {
                this.navTabs.append(`<li class="nav-item" @click="this.tabClick"> <a href="#tab_default_${key}" class="nav-link" data-toggle="tab" data-displayTable="${tabs[key]}"> ${tabs[key]} </a> </li>`);
            }

            this.navTabs.find('li:first a').addClass('active');
            this.displayed  = this.tabs[0];
            this.tabName    = this.tabs[0];
        }, 
        // Set tabs content divs - not relevant if you don't want to load extra data to the DOM
        setTabsContent: function(tabs) {

            for (let key in tabs) {
                this.tabContent.append(`<div class="tab-pane" id="tab_default_${key}"> <table class="aTable hover display" id="${tabs[key]}"> </table> </div>`);
            }

            this.tabContent.find('.tab-pane').first().addClass('active');
        },
        hideTabs: function() {
            this.$tabsContainer.slideUp('slow');
        },
        showTabs: function() {
            this.$tabsContainer.slideDown('slow');
        },
        // Send tab data to parent
        sendTabsData: function(){
            let data = {
                'tabDisplayed': this.displayed,
                'tabName':      this.tabName            
            };
            this.$emit('tabsData', data);
        }
    }
};
</script>   

부모 컴포넌트는 다음과 같습니다.

<script>
    // import ProgressBar      from "../components/ProgressBar.vue";
    // import _                from 'lodash';
    import DashboardForm    from "../components/DashboardForm.vue";
    import DashboardTabs    from "../components/DashboardTabs.vue";

    export default {
        name: 'testcomponent',
        components: {
            // ProgressBar,
            DashboardForm, 
            DashboardTabs
        },
        // mixins: [GF],
        data() {
            return {
            };
        },
        created() {
        },
        mounted() {
        },
        destroyed() {
        },
        watch: {
        },
        methods: {
            // Submit form
            formSubmit: function(data) {
                console.log('Submit form here');
                console.log(data);
            }, 
            // Tabs data 
            fetchTabsData: function(data) {
                console.log('tab was clicked');
                console.log(data);
            }
        }
    }
</script>

<!-- Template -->
<template>

    <div id="testcomponent">

        <!-- DashboardForm -->
        <DashboardForm 
            :useGroupFilter="true"
            :useDateRange="true"
            @submit="formSubmit"
        />

        <!-- Main Data Container -->
        <div id="data-container">
            <div id="chart-container"></div>
            <!-- Dashboard Tabs and Tab Container -->
            <DashboardTabs
                :tabs="{ 0: 'potato', 1: 'banana' }"
                @tabsData="fetchTabsData"
            >
                <!-- Datatable -->
                <!-- <DashboardDatatable/> -->
            </DashboardTabs>


        </div> 
        <!-- END data-container -->

    </div>
</template>

보시다시피, 제 부모 컴포넌트에는, 데이터를 취득하는 송신 송신 기능이 있습니다(또, 정상적으로 동작합니다).

탭 구성 요소와 양식 구성 요소의 유일한 차이점은 탭 구성 요소가 다음을 생성한다는 것입니다.<li>클릭 이벤트가 바인드되어 있다.

내 질문을 확실히 하자면:

이 경우 클릭 이벤트가 바인드된 요소(onClick == > 상위 구성요소로 데이터를 전송/수신)가 동적으로 생성되고 "static"이 아닌 $disponent를 사용하여 하위 구성요소에서 부모 구성요소로 데이터를 전송하려면 어떻게 해야 합니까?

편집: v-for를 사용하여 요청된 결과를 얻을 수 없습니다.

<li class="nav-item" @click="this.tabClick" v-for="(tab,index) in tabs">
<a :href="`#tab_default_${index}`" class="nav-link" data-toggle="tab" :data-displayTable="`${tab}`"> ${tab} </a>
</li>

다음과 같은 에러가 표시됩니다.

렌더 오류: "TypeError: 정의되지 않은 속성 '탭 클릭'을 읽을 수 없습니다."

@click을 추가할 수 없는 것 같습니다.

편집 2:

테스트 완료@click.native="this.tabClick"v-for - 오류는 발생하지 않지만 더미 콘솔.dummy console.dummy가 나타나지 않습니다.클릭 이벤트가 정기적으로 실행되지 않습니다.

컴포넌트가 방출하는 것은tabs이벤트(this.$emit('tabs', data)) 。따라서 부모님께서도 들으셔야 합니다.tabs이벤트:@tabs="tabsData"복종하는 대신

언급URL : https://stackoverflow.com/questions/55340617/using-emit-from-child-component-to-send-data-to-the-parent-component-doesnt-wo

반응형