美文网首页让前端飞
Angular React Vue 比较 – 组件篇之动态组件

Angular React Vue 比较 – 组件篇之动态组件

作者: 比较编程网 | 来源:发表于2024-03-07 09:03 被阅读0次

应用可能会需要在运行期间加载一些新的组件,这个时候我们就用到了动态组件。本章我们将通过一个动态广告条的示例来介绍三大框架是如何动态添加组件的。

Angular中的动态组件

下面的例子展示了如何构建动态广告条。

指令

在添加组件之前,先要定义一个锚点来告诉 Angular 要把组件插入到什么地方。广告条使用一个名叫 AdDirective 的辅助指令来在模板中标记出有效的插入点。AdDirective 注入了 ViewContainerRef 来获取对容器视图的访问权,这个容器就是那些动态加入的组件的宿主。

ad.directive.ts 文件

import { Directive, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[adHost]',
})
export class AdDirective {
  constructor(public viewContainerRef: ViewContainerRef) { }
}

加载组件

在下的代码中 <ng-template> 元素就是刚才制作的指令将应用到的地方。通过使用 adHost 指令,Angular 就知道该把组件动态加载到哪里了。

要把广告组件添加到模板中,我们可以调用 ViewContainerRef 的 createComponent()。

ad.banner.component.ts 文件

import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { AdDirective } from './ad.directive';
import { AComponent, BComponent, CComponent } from './ads.component';

@Component({
  selector: 'app-ad-banner',
  template: `
    <div class="ad-banner-example">
      <h3>动态广告条</h3>
      <ng-template adHost></ng-template>
    </div>
  `
})
export class AdBanner3Component implements OnInit, OnDestroy {
  ads = [AComponent, BComponent, CComponent];
  currentAdIndex = -1;
  @ViewChild(AdDirective, {static: true}) adHost!: AdDirective;

  private clearTimer: VoidFunction | undefined;

  ngOnInit(): void {
    this.loadComponent();
    this.getAds();
  }

  ngOnDestroy() {
    this.clearTimer?.();
  }

  loadComponent() {
    this.currentAdIndex = (this.currentAdIndex + 1) % this.ads.length;
    const adItem = this.ads[this.currentAdIndex];

    const viewContainerRef = this.adHost.viewContainerRef;
    viewContainerRef.clear();
    viewContainerRef.createComponent(adItem);
  }

  getAds() {
    const interval = setInterval(() => {
      this.loadComponent();
    }, 3000);
    this.clearTimer = () => clearInterval(interval);
  }
}

广告条

在广告条中,我们列出了三个广告组件,这三个组件就是上面代码中动态加载的组件。

ads.component.ts 文件

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

@Component({
  template: `
    <div class="ad-a">
      <p>Ad A</p>
    </div>
  `
})
export class AComponent {

}

@Component({
  template: `
    <div class="ad-b">
      <p>Ad B</p>
    </div>
  `
})
export class BComponent {

}

@Component({
  template: `
    <div class="ad-c">
      <p>Ad C</p>
    </div>
  `
})
export class CComponent {

}

React中的动态组件

在 React 中,并没有提出动态组件的概念,不过由于 React 的模板使用的是 JSX 语法,我们通过对状态设置成不同的组件值来实现动态添加组件的功能。

下面的例子展示了如何构建动态广告条。

import React from "react";
import { useState, useEffect } from 'react';

export default function AdBannerComponent() {
    const [ component, setComponent ] = useState( '' );
    const ads = [ <AdComponentA />, <AdComponentB />, <AdComponentC /> ];
    let currentAdIndex = -1;

    useEffect(() => {
      const interval = setInterval(() => {
        loadComponent();
      }, 3000);

      return () => clearInterval(interval);
    }, []);

    function loadComponent() {
      currentAdIndex = (currentAdIndex + 1) % ads.length;
      setComponent( ads[currentAdIndex] );
    }

    return (
      <div>
        <h2>动态广告条</h2>
        { component }
      </div>
    )
}

function AdComponentA() {
  return (
    <p>Ad A</p>
  )
}

function AdComponentB() {
  return (
    <p>Ad B</p>
  )
}

function AdComponentC() {
  return (
    <p>Ad C</p>
  )
}

Vue中的动态组件

在 Vue 中,提供了 <component> 元素和特殊的 is attribute 来实现动态组件。

下面的例子展示了如何构建动态广告条。

AdBanner.vue 文件

<script setup>
import { shallowRef, onMounted, onUnmounted } from 'vue';

import AdComponentA from './components/AdComponentA.vue';
import AdComponentB from './components/AdComponentB.vue';
import AdComponentC from './components/AdComponentC.vue';


const adItem = shallowRef(AdComponentA);
const ads = [ AdComponentA, AdComponentB, AdComponentC]; 
let currentAdIndex = -1;
let interval;

onMounted(() => {
  interval = setInterval(() => {
    loadComponent();
  }, 3000);
});

onUnmounted(() => {
  clearInterval(interval);
});

function loadComponent() {
  currentAdIndex = (currentAdIndex + 1) % ads.length;
  adItem.value = ads[currentAdIndex];
}

</script>

<template>

  <h2>动态广告条</h2>
  <component :is="adItem" />
</template>

AdComponentA.vue 文件

<script setup>
</script>

<template>
  <p>Ad A</p>
</template>

AdComponentB.vue 文件

<script setup>
</script>

<template>
  <p>Ad B</p>
</template>

AdComponentC.vue 文件

<script setup>
</script>

<template>
  <p>Ad C</p>
</template>

小结

本章介绍了三大框架的动态组件,对如何加载动态组件做了说明。

Angular 使用 ViewContainerRef 类中的 createComponent() 方法来创建组件。通过 createComponent() 方法返回的引用,我们还可以设置它的属性或调用它的方法。

React 的模板使用的是 JSX 语法,通过对状态设置成不同的组件值就可以实现动态组件的功能。

Vue 提供了一个用于渲染动态组件或元素的“元组件” <component> 。

文章参考链接:

相关文章

  • 如何开发vue、react、angular的组件库教程

    关键词:vue,react,angular,开发,封装,ui组件,组件库,常用组件 目标:开发相应的组件库vue-...

  • 从数据看vue组件

    三大前端框架 Vue 、react 和 angular,都提到了一个概念——组件,那么什么是组件——组件(Comp...

  • 《Vue3.0抢先学》系列之:组件生命周期

    在组件化的框架中,比如Angular、React或Vue,都为组件定义了生命周期这个概念,每个组件实例在被创建时都...

  • 浅谈Vue常用的UI组件库

    如果提到Angular与Vue的比较,不得不提的是Angular组件库的匮乏,相比之下,Vue的组件库可选择的面就...

  • React组件一

    组件化开发一 目前,前端三大框架(Vue,React,Angular)都在使用组件化的我形式进行开发。19年最火的...

  • vue介绍以及项目的搭建

    一,vue是什么? vue,Angular,React都是前端框架。 1,基于单页面框架 2,基于模块化、组件化开...

  • React 组件化开发

    无论是 vue、React 还是 Angular,主流框架都支持并提倡组件化开发,因为组件化开发不仅可以增强代码的...

  • 简单情况

    Vue和Angular、React都是前端框架 1、单页面框架 2、基于模块化组件化的开发模式 Vue简单 灵活 ...

  • Angular动态组件&响应式表单的实现[附源码]

    本文将通过一个简单的例子简单展示Angular动态组件+响应式表单的使用。【关键字】: Angular,动态组件,...

  • Vue 构建单页应用 1

    简介和对比 Vue Angular React 都是基于 “单页面组件化” 思想的前端框架。 安装脚手架 必须安装...

网友评论

    本文标题:Angular React Vue 比较 – 组件篇之动态组件

    本文链接:https://www.haomeiwen.com/subject/dkuszdtx.html