Share via


Simplificar la adición de elementos web con entradas preconfiguradas

Los elementos web más complejos del lado cliente de SharePoint Framework probablemente tienen muchas propiedades que el usuario debe configurar. Puede ayudar a los usuarios si agrega entradas de propiedades preconfiguradas para escenarios específicos. Una entrada preconfigurada inicializa el elemento web con valores preestablecidos.

Nota:

Antes de seguir los pasos que se indican en el artículo, asegúrese de configurar el entorno de desarrollo del elemento web del lado cliente de SharePoint.

Advertencia

Las soluciones SPFx destinadas a SharePoint Server 2016 se limitan a establecer solo una propiedad de elemento web como una entrada preconfigurada. Para obtener más información, vea issue #5260.

Entradas preconfiguradas de elementos web

Cada elemento web del lado cliente de SharePoint Framework se compone de dos partes:

  • El manifiesto que describe el elemento web
  • El código del elemento web

Una de las propiedades especificadas en el manifiesto del elemento web es la propiedad preconfiguredEntries.

{
  "$schema": "https://developer.microsoft.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",

  "id": "6737645a-4443-4210-a70e-e5e2a219133a",
  "alias": "GalleryWebPart",
  "componentType": "WebPart",
  "version": "0.0.1",
  "manifestVersion": 2,

  "preconfiguredEntries": [{
    "groupId": "1edbd9a8-0bfb-4aa2-9afd-14b8c45dd489", // Discovery
    "group": { "default": "Under Development" },
    "title": { "default": "Gallery" },
    "description": { "default": "Shows items from the selected list" },
    "officeFabricIconFontName": "Page",
    "properties": {
      "description": "Gallery"
    }
  }]
}

La propiedad preconfiguredEntries proporciona información sobre su elemento web para su uso en el cuadro de herramientas del elemento web. Cuando los usuarios agregan elementos web a la página, la información de la propiedad preconfiguredEntries se utiliza para mostrar el elemento web en el cuadro de herramientas y definir su configuración predeterminada cuando se agrega a la página.

Si ha creado elementos web clásicos con soluciones de plena confianza, puede pensar en cada entrada de la preconfiguredEntries matriz como correspondiente a un archivo *.webpart . Al igual que un archivo *.webpart , cada entrada de la preconfiguredEntries propiedad está vinculada al código del elemento web y especifica información básica sobre el elemento web, como su título o descripción, y los valores predeterminados para sus propiedades.

Propiedades de un elemento de matriz preconfiguredEntries

Cada elemento de la matriz preconfiguredEntries consta de varias propiedades. La tabla siguiente explica la finalidad de cada propiedad.

Nombre de propiedad Tipo de valor Necesario Finalidad Valor de ejemplo
title ILocalizedString El título del elemento web que se muestra en el cuadro de herramientas. "title": { "default": "Weather", "nl-nl": "Weerbericht" }
description ILocalizedString La descripción del elemento web que se muestra en la información sobre herramientas del cuadro de herramientas. "description": { "default": "Shows weather in the given location", "nl-nl": "Toont weerbericht voor de opgegeven locatie" }
officeFabricIconFontName string no El icono del elemento web que se muestra en el cuadro de herramientas. Su valor debe ser uno de los nombres de icono de Office UI Fabric. Si esta propiedad tiene un valor, se omite la propiedad iconImageUrl. "officeFabricIconFontName": "Sunny"
iconImageUrl string no Icono del elemento web que se muestra en el cuadro de herramientas y que está representado por una dirección URL de imagen. La imagen de la dirección URL debe medir exactamente 40 x 28 px. Si la propiedad officeFabricIconName no tiene un valor, esta propiedad debe tenerlo. "iconImageUrl": "https://cdn.contoso.com/weather.png"
groupId string Identificador de grupo para determinar qué grupo moderno contiene el elemento web en la página moderna del sitio. SharePoint Framework reserva identificadores de grupo para grupos predefinidos. El desarrollador puede seleccionar uno de esos grupos. Si el desarrollador rellena un identificador y no lo hace en los grupos predefinidos, se revierte al grupo Otros. "groupId": "1edbd9a8-0bfb-4aa2-9afd-14b8c45dd489"
group ILocalizedString no Nombre del grupo en el selector de elementos web que va a contener el elemento web en la página clásica. Si no se proporciona ningún valor, el elemento web se muestra en el grupo Varios. "group": { "default": "Content", "nl-nl": "Inhoud" }
properties TProperties Objeto de par clave-valor con valores predeterminados para las propiedades de elementos web. "properties": { "location": "Redmond", "numberOfDays": 3, "showIcon": true }

Algunas propiedades de elementos web tienen un valor de tipo ILocalizedString. Este tipo es un objeto de par clave-valor que permite a los desarrolladores especificar cadenas para las diferentes configuraciones regionales. Como mínimo, un valor de tipo ILocalizedString debe contener el valor default.

De forma opcional, los desarrolladores pueden proporcionar las traducciones de dicho valor para las distintas configuraciones regionales que admite su elemento web. Si el elemento web se coloca en una página con una configuración regional que no aparece en la cadena traducida, en su lugar se usará el valor predeterminado.

Valores válidos ILocalizedString:

"title": {
  "default": "Weather",
  "nl-nl": "Weerbericht"
}
"title": {
  "default": "Weather"
}

Un valor ILocalizedString que no es válido porque falta la clave default predeterminada:

"title": {
  "en-us": "Weather"
}

Grupos modernos predefinidos

Hay siete grupos prediseñados, como se muestra en la tabla siguiente. Use el identificador de grupo en la propiedad groupId.

Nombre del grupo Identificador El grupo incluye...
Texto, multimedia y contenido cf066440-0614-43d6-98ae-0b31cf14c7c3 Elementos web que muestran texto, elementos multimedia, documentos, información de la Web y otro contenido enriquecido.
Descubrimiento 1edbd9a8-0bfb-4aa2-9afd-14b8c45dd489 Elementos web que organizan, agrupan y filtran contenido para ayudar a los usuarios a descubrir información.
Comunicación y colaboración 75e22ed5-fa14-4829-850a-c890608aca2d Elementos web que facilitan el uso compartido de la información, el trabajo en equipo y las interacciones sociales.
Planeamiento y procesos 1bc7927e-4a5e-4520-b540-71305c79c20a Elementos web que impulsan la productividad en equipo con el uso de herramientas de planeamiento y procesos.
Empresa e inteligencia 4aca9e90-eff5-4fa1-bac7-728f5f157b66 Elementos web para realizar un seguimiento de datos y analizarlos, y para integrar el flujo empresarial con las páginas.
Herramientas de sitio 070951d7-94da-4db8-b06e-9d581f1f55b1 Elementos web para la administración y la información del sitio.
Otro 5c03119e-3074-46fd-976b-c60198311f70 Elementos web que no se encuentran en otros grupos.

Si el desarrollador rellena un identificador y no lo hace en la lista anterior, el elemento web se revierte al grupo Otros.

Para ver cómo puede utilizar entradas preconfiguradas al compilar elementos web, va a crear un elemento web de la galería de ejemplo. Mediante el uso de varias propiedades, los usuarios pueden configurar este elemento web para mostrar los elementos de una lista seleccionada de una manera específica. Para mayor brevedad, omita la implementación real de la lógica del elemento web y céntrese en el uso de la propiedad preconfiguredEntries para proporcionar versiones preconfiguradas del elemento web de la galería.

Panel de propiedad del elemento web que muestra las diferentes propiedades que los usuarios deben configurar para que el elemento web funcione

Crear un proyecto de elementos web

  1. Empiece por crear una carpeta para el proyecto.

    md react-preconfiguredentries
    
  2. Vaya a la carpeta del proyecto.

    cd react-preconfiguredentries
    
  3. Cree un nuevo proyecto ejecutando el generador de SharePoint Yeoman desde el nuevo directorio que creó:

    yo @microsoft/sharepoint
    

    El generador de SharePoint Yeoman le hará una serie de preguntas. Para todas las preguntas, acepte las opciones predeterminadas excepto para las siguientes preguntas:

    • ¿Cuál es el tipo de componente del lado cliente que se va a crear? WebPart
    • ¿Cómo se llama su elemento web? Galería
    • ¿Qué plantilla desea usar? React
  4. Abra la carpeta del proyecto en el editor de código. En los pasos y capturas de pantalla de este artículo se usa Visual Studio Code, pero puede emplear el editor que prefiera.

Agregar propiedades de elementos web

En el manifiesto de elemento web, agregue propiedades de elementos web para que los usuarios puedan configurar el elemento web de la galería.

  1. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.manifest.json.

  2. Reemplace la sección properties por el siguiente JSON:

    {
      //...
      "preconfiguredEntries": [{
        //...
        "properties": {
          "listName": "",
          "order": "",
          "numberOfItems": 10,
          "style": ""
        }
      }]
    }
    

    Tenga en cuenta lo siguiente en relación con este código:

    • listName: especifica el nombre de la lista desde la que se deben mostrar los elementos de lista.
    • order: especifica el orden en el que se deben mostrar los elementos, es decir, en orden cronológico o cronológico inverso.
    • numberOfItems: especifica cuántos elementos se deben mostrar.
    • style: especifica cómo se deben mostrar los elementos: como miniaturas, que resulta útil para mostrar imágenes, o como una lista, que es más apropiado para documentos.

    Las propiedades de elementos web especificadas en el manifiesto también deben agregarse a la interfaz de propiedades de elementos web.

  3. En el editor de código, abra el archivo ./src/webparts/gallery/IGalleryWebPartProps.ts. Cambie su código por:

    export interface IGalleryWebPartProps {
      listName: string;
      order: string;
      numberOfItems: number;
      style: string;
    }
    

    Al compilar elementos web del lado cliente de SharePoint Framework con React, después de cambiar la interfaz de propiedades del elemento web, debe actualizar el método render() del elemento web que usa esta interfaz para crear una instancia del componente principal de React.

  4. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.ts. Cambie el método render() del elemento web por:

    export default class GalleryWebPart extends BaseClientSideWebPart<IGalleryWebPartProps> {
      // ...
      public render(): void {
        const element: React.ReactElement<IGalleryProps> = React.createElement(Gallery, {
          listName: this.properties.listName,
          order: this.properties.order,
          numberOfItems: this.properties.numberOfItems,
          style: this.properties.style
        });
    
        ReactDom.render(element, this.domElement);
      }
      // ...
    }
    
  5. Actualice el componente principal de React para mostrar los valores de las propiedades. Si no se ha configurado el elemento web, muestre el marcador de posición estándar del elemento web. En el editor de código, abra el archivo ./src/webparts/gallery/components/Gallery.tsx y cambie su código por:

    import * as React from 'react';
    import styles from './Gallery.module.scss';
    import { IGalleryProps } from './IGalleryProps';
    
    export default class Gallery extends React.Component<IGalleryProps, void> {
      public render(): JSX.Element {
        if (this.needsConfiguration()) {
          return <div className="ms-Grid" style={{ color: "#666", backgroundColor: "#f4f4f4", padding: "80px 0", alignItems: "center", boxAlign: "center" }}>
            <div className="ms-Grid-row" style={{ color: "#333" }}>
              <div className="ms-Grid-col ms-u-hiddenSm ms-u-md3"></div>
              <div className="ms-Grid-col ms-u-sm12 ms-u-md6" style={{ height: "100%", whiteSpace: "nowrap", textAlign: "center" }}>
                <i className="ms-fontSize-su ms-Icon ms-Icon--ThumbnailView" style={{ display: "inline-block", verticalAlign: "middle", whiteSpace: "normal" }}></i><span className="ms-fontWeight-light ms-fontSize-xxl" style={{ paddingLeft: "20px", display: "inline-block", verticalAlign: "middle", whiteSpace: "normal" }}>Gallery</span>
              </div>
              <div className="ms-Grid-col ms-u-hiddenSm ms-u-md3"></div>
            </div>
            <div className="ms-Grid-row" style={{ width: "65%", verticalAlign: "middle", margin: "0 auto", textAlign: "center" }}>
              <span style={{ color: "#666", fontSize: "17px", display: "inline-block", margin: "24px 0", fontWeight: 100 }}>Show items from the selected list</span>
            </div>
            <div className="ms-Grid-row"></div>
          </div>;
        }
        else {
          return (
            <div className={styles.gallery}>
              <div className={styles.container}>
                <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
                  <div className='ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1'>
                    <span className="ms-font-xl ms-fontColor-white">
                      Welcome to SharePoint!
                    </span>
                    <p className='ms-font-l ms-fontColor-white'>
                      Customize SharePoint experiences using web parts.
                    </p>
                    <p className='ms-font-l ms-fontColor-white'>
                      List: {this.props.listName}<br />
                      Order: {this.props.order}<br />
                      Number of items: {this.props.numberOfItems}<br />
                      Style: {this.props.style}
                    </p>
                    <a href="https://aka.ms/spfx" className={styles.button}>
                      <span className={styles.label}>Learn more</span>
                    </a>
                  </div>
                </div>
              </div>
            </div>
          );
        }
      }
    
      private needsConfiguration(): boolean {
        return Gallery.isEmpty(this.props.listName) ||
          Gallery.isEmpty(this.props.order) ||
          Gallery.isEmpty(this.props.style);
      }
    
      private static isEmpty(value: string): boolean {
        return value === undefined ||
          value === null ||
          value.length === 0;
      }
    }
    
  6. Actualice la interfaz del componente React principal para que coincida con la interfaz de propiedades del elemento web, ya que estamos desviando todas las propiedades del elemento web a este componente. En el editor de código, abra el archivo ./src/webparts/gallery/components/IGalleryProps.ts y cambie su código por:

    import { IGalleryWebPartProps } from '../IGalleryWebPartProps';
    
    export interface IGalleryProps extends IGalleryWebPartProps { }
    

Representar propiedades de elementos web en el panel de propiedades

Para que un usuario pueda utilizar las propiedades recién definidas para configurar el elemento web, deben mostrarse las propiedades en el panel de propiedades del elemento web.

  1. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.ts. En la sección superior del archivo, cambie la instrucción de importación @microsoft/sp-webpart-base por:

    import {
      BaseClientSideWebPart
    } from '@microsoft/sp-webpart-base';
    import {
      IPropertyPaneConfiguration,
      PropertyPaneDropdown,
      PropertyPaneSlider,
      PropertyPaneChoiceGroup
    } from '@microsoft/sp-property-pane';
    
  2. Cambie el propertyPaneSettings a:

    export default class GalleryWebPart extends BaseClientSideWebPart<IGalleryWebPartProps> {
      // ...
      protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
        return {
          pages: [
            {
              header: {
                description: strings.PropertyPaneDescription
              },
              groups: [
                {
                  groupName: strings.BasicGroupName,
                  groupFields: [
                    PropertyPaneDropdown('listName', {
                      label: strings.ListNameFieldLabel,
                      options: [{
                        key: 'Documents',
                        text: 'Documents'
                      },
                      {
                        key: 'Images',
                        text: 'Images'
                      }]
                    }),
                    PropertyPaneChoiceGroup('order', {
                      label: strings.OrderFieldLabel,
                      options: [{
                        key: 'chronological',
                        text: strings.OrderFieldChronologicalOptionLabel
                      },
                      {
                        key: 'reversed',
                        text: strings.OrderFieldReversedOptionLabel
                      }]
                    }),
                    PropertyPaneSlider('numberOfItems', {
                      label: strings.NumberOfItemsFieldLabel,
                      min: 1,
                      max: 10,
                      step: 1
                    }),
                    PropertyPaneChoiceGroup('style', {
                      label: strings.StyleFieldLabel,
                      options: [{
                        key: 'thumbnails',
                        text: strings.StyleFieldThumbnailsOptionLabel
                      },
                      {
                        key: 'list',
                        text: strings.StyleFieldListOptionLabel
                      }]
                    })
                  ]
                }
              ]
            }
          ]
        };
      }
    }
    

En una situación real, recuperaría la lista de listas del sitio de SharePoint actual. Para mayor brevedad, en este ejemplo se usa una lista fija en su lugar.

Agregar etiquetas de localizaci?n

  1. En el editor de código, abra el archivo ./src/webparts/gallery/loc/mystrings.d.ts. Cambie su código por:

    declare interface IGalleryStrings {
      PropertyPaneDescription: string;
      BasicGroupName: string;
      ListNameFieldLabel: string;
      OrderFieldLabel: string;
      OrderFieldChronologicalOptionLabel: string;
      OrderFieldReversedOptionLabel: string;
      NumberOfItemsFieldLabel: string;
      StyleFieldLabel: string;
      StyleFieldThumbnailsOptionLabel: string;
      StyleFieldListOptionLabel: string;
    }
    
    declare module 'galleryStrings' {
      const strings: IGalleryStrings;
      export = strings;
    }
    
  2. Agregue las cadenas de recursos que faltan. Para ello, abra el archivo ./src/webparts/gallery/loc/en-us.js y cambie su c?digo por:

    define([], function() {
      return {
        "PropertyPaneDescription": "Description",
        "BasicGroupName": "Group Name",
        "ListNameFieldLabel": "List",
        "OrderFieldLabel": "Items order",
        "OrderFieldChronologicalOptionLabel": "chronological",
        "OrderFieldReversedOptionLabel": "reversed chronological",
        "NumberOfItemsFieldLabel": "Number of items to show",
        "StyleFieldLabel": "Items display style",
        "StyleFieldThumbnailsOptionLabel": "thumbnails",
        "StyleFieldListOptionLabel": "list"
      }
    });
    
  3. Para confirmar que el proyecto se está compilando, ejecute el comando siguiente:

    gulp serve
    
  4. En el explorador web, agregue el elemento web al lienzo y abra su panel de propiedades. Debería ver todas las propiedades disponibles para que los usuarios las configuren.

    Panel de propiedad del elemento web que muestra las diferentes propiedades que los usuarios deben configurar para que el elemento web funcione

Como no ha especificado los valores predeterminados del elemento web, cada vez que los usuarios agreguen el elemento web a la página, tendrán que configurarlo. Puede simplificar esta experiencia si proporciona valores predeterminados para los escenarios más comunes.

Especificar los valores predeterminados del elemento web

Imagine que los usuarios usan a menudo el elemento web de la galería para mostrar las últimas cinco imágenes agregadas. En lugar de solicitar que los usuarios configuren el elemento web manualmente cada vez, puede proporcionarles una versión preconfigurada con la configuración correcta.

  1. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.manifest.json. Cambie la entrada existente en la propiedad preconfiguredEntries a:

    {
      // ...
      "preconfiguredEntries": [{
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Recent images" },
        "description": { "default": "Shows 5 most recent images" },
        "officeFabricIconFontName": "Picture",
        "properties": {
          "listName": "Images",
          "order": "reversed",
          "numberOfItems": 5,
          "style": "thumbnails"
        }
      }]
    }
    
  2. Empiece a depurar el proyecto ejecutando el comando siguiente:

    gulp serve
    

    Nota:

    Si ya estaba depurando el proyecto, detenga la depuración y vuelva a iniciarla. Los cambios realizados en el manifiesto del elemento web no se reflejan automáticamente en Workbench mientras se depura; tiene que recompilar el proyecto para poder verlos.

  3. Cuando abra el cuadro de herramientas del elemento web para agregar el elemento web al lienzo, verá que su nombre y su icono han cambiado para reflejar las opciones preconfiguradas.

    Cuadro de herramientas del elemento web que muestra la versión preconfigurada del mismo

  4. Después de agregar el elemento web a la página, este funciona inmediatamente con las opciones preconfiguradas.

    Elemento web preconfigurado que funciona inmediatamente después de agregarlo a la página

Especificar varias entradas preconfiguradas de elementos web

Imagine que otro grupo de usuarios utiliza a menudo el elemento de web de la galería para mostrar documentos agregados recientemente a su sitio. Para ayudarles a utilizar el elemento web, puede agregar otro conjunto de ajustes preestablecidos que satisfaga sus necesidades de configuración.

  1. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.manifest.json. Cambie la propiedad preconfiguredEntries a:

    {
      // ...
      "preconfiguredEntries": [{
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Recent images" },
        "description": { "default": "Shows 5 most recent images" },
        "officeFabricIconFontName": "Picture",
        "properties": {
          "listName": "Images",
          "order": "reversed",
          "numberOfItems": 5,
          "style": "thumbnails"
        }
      },
      {
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Recent documents" },
        "description": { "default": "Shows 10 most recent documents" },
        "officeFabricIconFontName": "Documentation",
        "properties": {
          "listName": "Documents",
          "order": "reversed",
          "numberOfItems": 10,
          "style": "list"
        }
      }]
    }
    
  2. Observe que la entrada preconfigurada anterior se mantiene intacta, y agregue otra junto a esta con diferentes valores para las propiedades.

  3. Para ver el resultado, empiece a depurar el proyecto mediante el comando siguiente:

    gulp serve
    
  4. Cuando abra el cuadro de herramientas del elemento web para agregar el elemento web al lienzo, verá que puede elegir entre dos elementos web.

    Cuadro de herramientas del elemento web que muestra la versión preconfigurada de dos elementos web

  5. Después de agregar el elemento web Documentos recientes a la página, este funciona inmediatamente con sus opciones específicas preconfiguradas.

    Elemento web de documentos recientes preconfigurado que funciona inmediatamente después de agregarlo a la página

Especificar una instancia no configurada del elemento web

Al compilar elementos web, existen a menudo escenarios específicos con los que el elemento web debe ser compatible. Si proporciona entradas preconfiguradas para esos escenarios, facilita a los usuarios el uso del elemento web.

Según cómo compile su elemento web, puede que este admita también otros escenarios imprevistos. Si únicamente proporciona entradas preconfiguradas específicas, los usuarios quizá no se den cuenta de que pueden usar el elemento web para un escenario diferente. Ser?a conveniente proporcionar tambi?n una variante gen?rica no configurada del elemento web.

  1. En el editor de código, abra el archivo ./src/webparts/gallery/GalleryWebPart.manifest.json. Cambie la propiedad preconfiguredEntries a:

    {
      // ...
      "preconfiguredEntries": [{
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Recent images" },
      "description": { "default": "Shows 5 most recent images" },
        "officeFabricIconFontName": "Picture",
        "properties": {
          "listName": "Images",
          "order": "reversed",
          "numberOfItems": 5,
          "style": "thumbnails"
        }
      },
      {
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Recent documents" },
        "description": { "default": "Shows 10 most recent documents" },
        "officeFabricIconFontName": "Documentation",
        "properties": {
          "listName": "Documents",
          "order": "reversed",
          "numberOfItems": 10,
          "style": "list"
        }
      },
      {
        "groupId": "6737645a-4443-4210-a70e-e5e2a219133a",
        "group": { "default": "Content" },
        "title": { "default": "Gallery" },
        "description": { "default": "Shows items from the selected list" },
        "officeFabricIconFontName": "CustomList",
        "properties": {
          "listName": "",
          "order": "",
          "numberOfItems": 5,
          "style": ""
        }
      }]
    }
    
  2. Observe que la versión genérica no configurada del elemento web se agrega junto a las configuraciones destinadas a escenarios específicos. De este modo, si no hay ninguna configuración específica que aborde las necesidades de los usuarios, siempre pueden usar la versión genérica y configurarla según sus requisitos.

  3. Para ver el resultado, empiece a depurar el proyecto mediante el comando siguiente:

    gulp serve
    
  4. Cuando abra el cuadro de herramientas del elemento web para agregar el elemento web al lienzo, verá que ahora los usuarios pueden elegir entre tres elementos web.

    Cuadro de herramientas del elemento web que muestra la versión preconfigurada de tres elementos web