Vue js передает функцию из дочернего chile в другой дочерний компонент при событии щелчка

#javascript #vue.js #nuxt.js

#javascript #vue.js #nuxt.js

Вопрос:

Я пытаюсь передать функцию при нажатии кнопки, кнопка нажимается в дочернем элементе, затем передается через родительский элемент в другой дочерний компонент, и я не хочу использовать для этого хранилище, как я могу это сделать?

components/footer/footer.vue — здесь нажимается кнопка

 <template>
    <div class="footer-bottom-header-menu-bar mob"  @click="showMenu">
        <img src="~/assets/svg/menubar.svg" alt=" " />
    </div>
</template>

<script>
export default {
    methods: {
        showMenu() {
            this.$emit("show-menu");
        }
    }
}
</script>
 

layouts/default.vue
—Это родительский компонент, который получает функцию щелчка и должен передать ее в app-header

 <template>
    <div>
        <app-header />
        <Nuxt />
        <app-footer @show-menu="showMenu()"/>
    </div>
</template>

<script>
import header from "~/components/header/header";
import footer from "~/components/footer/footer";

export default {
    components: {
        'app-header': header,
        'app-footer': footer
    },
    methods: {
        showMenu() {
            console.log("clicked");
        }
    }
}
</script>
 

компоненты/заголовок/header.vue
— Я хочу, чтобы функция щелчка выполняла действие внутри этого компонента

 <script>
export default {
    data() {
        return {
            showMenuBar: false
        }
    },
}
</script>
 

Комментарии:

1. … передать его через шину событий?

2. @vector почти такой же, как store tbh.

3. Если вы не хотите использовать хранилище для этого, вам нужно сделать это другим способом: emit listener и запустить некоторые методы. PS: передача функции вниз или вверх является анти-шаблоном в Vue (это распространено в React tho).

Ответ №1:

Почему вы беспокоитесь о передаче функции?

Когда вы emit show-menu событие, просто переключите часть данных в вашем родительском компоненте следующим образом:

 <template>
    <div>
        <app-header :showMenuBar="showMenuBar" />
        <Nuxt />
        <app-footer @show-menu="showMenu"/>
    </div>
</template>

<script>
import header from "~/components/header/header";
import footer from "~/components/footer/footer";

export default {
    components: {
        'app-header': header,
        'app-footer': footer
    },
    data() {
      return {
        showMenuBar: false;
      };
    },
    methods: {
        showMenu() {
            // I would make this more dynamic than always
            // hardcoding it to true, but you get the idea
            this.showMenuBar = true;
        }
    }
}
</script>
 

Затем в вашем AppHeader случае просто используйте его в качестве опоры:

 <script>
export default {
    props: {
      showMenuBar: { 
        type: Boolean, 
        default: false,
    },
}
</script>
 

Ответ №2:

Вы можете объявить любой атрибут в своем родительском компоненте:

 data() {
    return { toBeWatched: 0 };
}
 
  • Затем передает ее как реквизит от родительского элемента к дочернему элементу заголовка:
    <app-header :Trigger="toBeWatched" />
  • Когда вы прослушиваете @show-menu событие (исходящее от дочернего элемента нижнего колонтитула), внесите любые изменения в свой атрибут:
    <app-footer @show-menu="toBeWatched " />
  • Наконец, вы можете отслеживать это изменение в своем дочернем заголовке и запускать свою функцию.
 <script>
export default {
    data() {
      return {
        showMenuBar: false
      };
    },
    props: ['Trigger'],
    watch: {
      Trigger() {
        this.showMenuBar = !this.showMenuBar; // or do whatever you want
        console.log('showMenuBar : '   this.showMenuBar);
      }
    }
};
</script>