1

I am learning Vue.js and I tried the keep-alive and component mechanism which allows to dynamically switch between components. As far as I have understood, I can do something like this:

<template>
  <section>
    <button @click="setSelectedTab('section-a')">Section A</button>
    <button @click="setSelectedTab('section-b')">Section B</button>
  </section>

  <keep-alive>
    <component :is="selectedTab"></component>
  </keep-alive>
</template>

export default defineComponent({
  name: "SomeComponent",
  components: {
    SectionA,
    SectionB,
  },
  data() {
    return {
      selectedTab: 'section-a',
    };
  },
  methods: {
    setSelectedTab(tab: string): void {
      this.selectedTab = tab;
    },
  },
});
</script>

The above code will show either SectionA or SectionB component according to which button is clicked, while also making sure that the component which is not shown stays alive, keeping its internal state.

In Angular, I would have to do the following:

import { Component } from '@angular/core';

@Component({
  selector: 'app-some',
  template: `
    <section>
      <button (click)="setSelectedTab('section-a')">Section A</button>
      <button (click)="setSelectedTab('section-b')">Section B</button>
    </section>
    
    <app-section-a *ngIf="selectedTab === 'section-a'"></app-section-a>
    <app-section-b *ngIf="selectedTab === 'section-b'"></app-section-b>
  `,
  styleUrls: ['./resources.component.scss']
})
export class SomeComponent {
  selectedTab = 'section-a';
  
  setSelectedTab(tab: string): void {
    this.selectedTab = tab;
  }
}

I guess if I wanted to keep the internal state of the component, I should use the following:

<app-section-a [ngStyle]="{ display: selectedTab !== 'section-a' ? 'none' : 'block' }"></app-section-a>
<app-section-b [ngStyle]="{ display: selectedTab !== 'section-b' ? 'none' : 'block' }"></app-section-b>

Is there a better way to achieve Vue.js behaviour in Angular?

Michael
  • 876
  • 9
  • 29
  • in angular you should use a behavior subject which will keep state for your components data using rxjs - its a bit of a wonky work around but it works well. – chris burd Aug 06 '21 at 05:18

1 Answers1

0

Keep Alive, When wrapped around a dynamic component, caches the inactive component instances without destroying them. Important point is when such components are toggled Vue calls the life cycle events activated and deactivated (alternative to mounted and unmounted).

In Angular, there is no way of caching the components which are inside the templates. However there is a way to cache router based component. See https://medium.com/swlh/how-to-toggle-caching-for-routing-components-in-angular-5a327ea87310. This however will not suite to what you need.

Coming to your use case, it depends, if the need is to invoke life cycle methods (OnInit, OnChanges etc) between tab switch, *ngIf approach will be the preferred choice as it removes the component from DOM tree and constructs it again when needs to be shown.

Changing the display will just cause the component to be invisible however the component the DOM tree will be still there in the DOM.

Ritesh Waghela
  • 3,474
  • 2
  • 19
  • 25