Vue this. $ Emit ('eventName') события в компоненте A не вызывают это. $ On ('eventName', callbackFunc) в компоненте B, я не поместил обработчик? - PullRequest
3 голосов
/ 25 сентября 2019

По сути, у меня есть компоненты, которые запускают событие при их создании, и специализированный компонент-счетчик, который считает созданные компоненты, этот второй компонент существует параллельно с первым.Однако, когда я пытаюсь запустить приложение, компонент counter считает только себя, кажется, что он обнаруживает только событие создания, запускаемое там.

Я пытался переместить операцию this. $ On () вдругие ловушки жизненного цикла, такие как mount (), но не удалось.

Компонент A:

Vue.component('counter-component',{
    template: `
        <div class="card">
            <div class="card-header">
                Components:
            </div>
            <div class="card-body">
                <p>Count: {{ totalCount }}</p>
                <p>Enabled Count: {{ totalEnabledCount }}</p>
                <p>Diabled Count: {{ totalDisabledCount }}</p>
            </div>
        </div>`,

    created(){
        this.$on('component-created', this.componentCreated),
        this.$on('component-disabled', this.componentDisabled),
        this.$on('component-enabled', this.componentEnabled),

        this.$emit('component-created', 'counter-component');
    },

    data(){
        return {
            totalCount: 0,
            totalDisabledCount: 0,
        }
    },

    computed: {
        totalEnabledCount(){
            return this.totalCount - this.totalDisabledCount;
        },
    },

    methods: {
        componentCreated(data){
            this.totalCount++;
        },
        componentDisabled(data){
            this.totalDisabledCount++;
        },
        componentEnabled(data){
            this.totalDisabledCount--;
        }
    }
});

Компонент B:

Vue.component('regular-component',{
    template: `
    <div class="my-2">
        <div class="card" v-show="isVisible">
            This is visible
        </div>

        <div class="card" v-show="!isVisible">
            This is invisible
        </div>
    </div>`,

    created(){
        this.$emit('component-created', 'message-component');
    },

    data: () => {
        return ({
            isVisible: true,
        });
    },

    methods: {
        toggleVisibility(){
            this.isVisible = !this.isVisible;

            if(this.isVisible){
                this.$emit('component-enabled','message-component');
            } else {
                this.$emit('component-disabled','message-component');
            }
        }
    },
});

Я ожидал, что оба компонента будутк сожалению, учитывается только компонент, содержащий обработчик.

Ответы [ 2 ]

1 голос
/ 26 сентября 2019

Кажется, вы ожидаете, что будет глобальная шина событий, на которую вы сможете emit подписаться.
Это не так по умолчанию в Vue, вместо этого Vue использует строго иерархический подход, при котором события генерируются.от потомка к родителю и свойства передаются от родителя к потомку.Взаимодействие между одноуровневыми компонентами по умолчанию не предусмотрено.

Правильный подход для вашего случая - это ввести родительский компонент, который прослушивает событие, удерживает totalCount как состояние и передает его как свойство своему счетчику.-дисплей:

<parent>
  <regular-component v-on:component-created="totalCount++"/>
  ...
  <counter-component v-bind:count="totalCount"/>
</parent>
0 голосов
/ 25 сентября 2019

Используйте, пожалуйста vuex.Это поможет вам уменьшить количество спагетти кода.

https://vuex.vuejs.org/

...