Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug: vue, cannot wrap tab button in custom component #25919

Open
4 of 7 tasks
DoloreMentale opened this issue Sep 12, 2022 · 5 comments
Open
4 of 7 tasks

bug: vue, cannot wrap tab button in custom component #25919

DoloreMentale opened this issue Sep 12, 2022 · 5 comments
Labels
package: vue @ionic/vue package type: bug a confirmed bug report

Comments

@DoloreMentale
Copy link

DoloreMentale commented Sep 12, 2022

Prerequisites

Ionic Framework Version

  • v4.x
  • v5.x
  • v6.x
  • Nightly

Current Behavior

All ion-tab-buttons in my case are rendered using v-for.
tabState.activeTab and tabState.tabs are empty.

Found similar issue, seems it has been fixed in previos version, but problem still appears:
#22847

image

ion-tab-button click causes an error:
image

Expected Behavior

ion-tab-button click should push to another route

Steps to Reproduce

Just use v-for on ion-tab-button

ion-tabs:

<template>
    <ion-tabs>
      <ion-router-outlet />

      <ion-tab-bar ref="tabBar" slot="bottom" :translucent="true">
        <tab-entity v-for="(tab, index) in tabs" :key="index" :tab="tab" />
      </ion-tab-bar>
    </ion-tabs>
</template>

<script>
import { IonTabBar, IonTabs, IonRouterOutlet } from '@ionic/vue';
import TabEntity from '@/components/tabs/tab.entity';

export default {
  name: 'TabsEntity',
  components: { IonTabBar, IonTabs, IonRouterOutlet, TabEntity },
  props: {
    tabs: {
      type: Array,
      default: () => []
    }
  },
}
</script>

ion-tab-button:

<template>
  <ion-tab-button :tab="tab.name" :href="tab.href">
    <ion-icon :icon="tab.icon" />
    <ion-label v-if="tab.value">{{ tab.value }}</ion-label>
  </ion-tab-button>
</template>

<script>
import { IonTabButton, IonIcon, IonLabel } from '@ionic/vue'

export default {
  name: 'TabEntity',
  components: { IonTabButton, IonIcon, IonLabel },
  props: {
    tab: {
      type: Object,
      default: () => {}
    },
  },
}
</script>

Code Reproduction URL

https://github.com/DoloreMentale/ion-tabs-bug-reproduction

Ionic Info

Ionic:

Ionic CLI : 6.19.0 (C:\nvm\v16.14.0\node_modules@ionic\cli)
Ionic Framework : @ionic/vue 6.2.6

Capacitor:

Capacitor CLI : 4.2.0
@capacitor/android : not installed
@capacitor/core : 4.2.0
@capacitor/ios : not installed

Utility:

cordova-res : not installed globally
native-run : 1.7.0

System:

NodeJS : v16.14.0 (C:\Program Files\nodejs\node.exe)
npm : 8.7.0
OS : Windows 10

Additional Information

No response

@ionitron-bot ionitron-bot bot added the triage label Sep 12, 2022
@liamdebeasi liamdebeasi added the ionitron: needs reproduction a code reproduction is needed from the issue author label Sep 12, 2022
@ionitron-bot
Copy link

ionitron-bot bot commented Sep 12, 2022

Thanks for the issue! This issue has been labeled as needs reproduction. This label is added to issues that need a code reproduction.

Please reproduce this issue in an Ionic starter application and provide a way for us to access it (GitHub repo, StackBlitz, etc). Without a reliable code reproduction, it is unlikely we will be able to resolve the issue, leading to it being closed.

If you have already provided a code snippet and are seeing this message, it is likely that the code snippet was not enough for our team to reproduce the issue.

For a guide on how to create a good reproduction, see our Contributing Guide.

@ionitron-bot ionitron-bot bot removed the triage label Sep 12, 2022
@DoloreMentale
Copy link
Author

Reproduction can be found here: https://github.com/DoloreMentale/ion-tabs-bug-reproduction

Besides that, the problem seems to be quite usual. I discovered that the issue is with wrapper component for ion-tab-button. Although the component is rendered without any additional tags, something that gets buttons inside ion-tab-bar cannot do that.

Steps for recreation are the same:

  1. yarn / npm install
  2. yarn / npm run serve
  3. Click on any ion-tab-button and check the console for error logs

@amandaejohnston amandaejohnston added triage and removed ionitron: needs reproduction a code reproduction is needed from the issue author labels Sep 14, 2022
@liamdebeasi liamdebeasi changed the title bug: @ionic/vue, ion-tab-button click does not work bug: vue, cannot wrap tab button in custom component Sep 14, 2022
@liamdebeasi liamdebeasi added package: vue @ionic/vue package type: bug a confirmed bug report labels Sep 14, 2022
@ionitron-bot ionitron-bot bot removed the triage label Sep 14, 2022
@liamdebeasi
Copy link
Member

Thanks. The problem here is that we expect the IonTabBar to pass _getTabState to child IonTabButton elements:

const tabs = this.$data.tabVnodes = getTabs((currentInstance.subTree.children || []) as VNode[]);
tabs.forEach(child => {
tabState.tabs[child.props.tab] = {
originalHref: child.props.href,
currentHref: child.props.href,
ref: child
}
/**
* Passing this prop to each tab button
* lets it be aware of the state that
* ion-tab-bar is managing for it.
*/
child.component.props._getTabState = () => tabState;

Since IonTabButton is wrapped in a custom Vue component and not a direct child, this function is not passed down. As a result, the click handler throws an error because it is missing required data. As a temporary workaround, you can update your app to ensure that IonTabButton is always a direct child of IonTabBar.

@DoloreMentale
Copy link
Author

@liamdebeasi thanks for your reply!

@g5becks
Copy link

g5becks commented Dec 19, 2023

Thanks. The problem here is that we expect the IonTabBar to pass _getTabState to child IonTabButton elements:

const tabs = this.$data.tabVnodes = getTabs((currentInstance.subTree.children || []) as VNode[]);
tabs.forEach(child => {
tabState.tabs[child.props.tab] = {
originalHref: child.props.href,
currentHref: child.props.href,
ref: child
}
/**
* Passing this prop to each tab button
* lets it be aware of the state that
* ion-tab-bar is managing for it.
*/
child.component.props._getTabState = () => tabState;

Since IonTabButton is wrapped in a custom Vue component and not a direct child, this function is not passed down. As a result, the click handler throws an error because it is missing required data. As a temporary workaround, you can update your app to ensure that IonTabButton is always a direct child of IonTabBar.

It would be really nice if this were stated in the docs. Spent a half an hour trying to figure out why I was getting this error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package: vue @ionic/vue package type: bug a confirmed bug report
Projects
None yet
Development

No branches or pull requests

4 participants