Componentes inspirados en la cuchilla de Laravel para posthtml
npm i -D posthtml-componentEste complemento Posthtml proporciona una sintaxis amigable con HTML para usar componentes en sus plantillas HTML. Si está familiarizado con Blade, React, Vue o similar, encontrará que la sintaxis es familiar, ya que este complemento está inspirado en ellos.
Consulte también la primera interfaz de usuario de bootstrap posthtml usando este complemento y verifique también la plantilla de inicio aquí.
| Nombre | Tipo | Por defecto | Descripción |
|---|---|---|---|
| raíz | String | './' | Ruta de la raíz donde buscar componentes. |
| carpetas | String[] | [''] | Matriz de rutas relativas a options.root Root o espacios de nombres definidos. |
| fileExtension | String|String[] | 'html' | Extensiones de archivo de componentes a buscar. |
| tagprefix | String | 'x-' | Etiqueta prefijo. |
| etiqueta | String|Boolean | false | Etiqueta de componentes. Úselo con options.attribute . Booleano solo false . |
| atributo | String | 'src' | Atributo a usar para definir el archivo de ruta al componente. |
| espacios de nombres | String[] | [] | Variedad de rutas de raíz del espacio de nombres, rutas de respaldo y rutas de anulación personalizadas. |
| espacio de nombres | String | '::' | Separador de espacio de nombres para nombres de etiquetas. |
| producir | String | 'yield' | Nombre de la etiqueta para inyectar contenido del componente principal. |
| ranura | String | 'slot' | Nombre de la etiqueta para ranuras |
| llenar | String | 'fill' | Nombre de la etiqueta para ranuras de llenado. |
| slotseparator | String | ':' | Separador de nombre para <slot> y <fill> etiquetas. |
| pila | String | 'stack' | Nombre de la etiqueta para <stack> . |
| empujar | String | 'push' | Nombre de la etiqueta para <push> . |
| propsscriptattribute | String | 'props' | Atributo en <script props> para recuperar accesorios de componentes. |
| propictext | String | 'props' | Nombre del objeto dentro del script para procesar accesorios. |
| TrayTribute | String | 'props' | Nombre del atributo para definir los accesorios como JSON en una etiqueta de componente. |
| holgazán | String | 'props' | Se utiliza para recuperar accesorios pasados a la ranura a través de $slots.slotName.props . |
| parseroptaciones | Object | {recognizeSelfClosing: true} | Pase las opciones a posthtml-parser . |
| expresiones | Object | {} | Pase opciones a posthtml-expressions . |
| complementos | Array | [] | Los complementos posthtml se aplicarán a cada componente analizado. |
| pareja | Object | [{tag: options.tagPrefix}] | Matriz de objetos utilizados para hacer coincidir las etiquetas. |
| attrsparserrules | Object | {} | Reglas adicionales para el complemento analizador de atributos. |
| estricto | Boolean | true | Alternar el lanzamiento de excepción. |
| mermelada | Function | function | Devolución de llamada para Lodash mergeWith para fusionar options.expressions.locals y accesorios. |
| utilidades | Object | {merge: _.mergeWith, template: _.template} | Métodos de utilidad pasados a <script props> . |
| elementattributes | Object | {} | Objeto con nombres de etiquetas y modificadores de función de valid-attributes.js . |
| safelistattributes | String[] | ['data-*'] | Matriz de nombres de atributos para agregar a atributos válidos predeterminados. |
| Blocklistattributes | String[] | [] | Matriz de nombres de atributos para eliminar de los atributos válidos predeterminados. |
Crea el componente:
<!-- src/button.html -->
< button type =" button " class =" btn " >
< yield > </ yield >
</ button >Úselo:
<!-- src/index.html -->
< html >
< body >
< x-button type =" submit " class =" btn-primary " > Submit </ x-button >
</ body >
</ html >Init posthtml:
// index.js
const posthtml = require ( 'posthtml' )
const components = require ( 'posthtml-component' )
const { readFileSync , writeFileSync } = require ( 'node:fs' )
posthtml ( [
components ( { root : './src' } )
] )
. process ( readFileSync ( 'src/index.html' , 'utf8' ) )
. then ( result => writeFileSync ( 'dist/index.html' , result . html , 'utf8' ) )Resultado:
<!-- dist/index.html -->
< html >
< body >
< button type =" submit " class =" btn btn-primary " > Submit </ button >
</ body >
</ html > Es posible que haya notado que el componente src/button.html contiene atributos type y class , y que también pasamos esos atributos cuando lo usamos en src/index.html .
El resultado es que ese type fue anulado y class se fusionó.
Por defecto, los atributos class y style se fusionan, mientras que todos los atributos se anulan todos los demás. También puede anular los atributos class y style prependiendo override: al atributo de clase.
Por ejemplo:
< x-button override:class =" btn-custom " > Submit </ x-button >
<!-- Output -->
< button type =" button " class =" btn-custom " > Submit </ button > Todos los atributos que pase al componente se agregarán al primer nodo de su componente o al nodo con un atributo llamado attributes , solo si no se definen como props a través de <script props> o si no son "atributos conocidos" (consulte válidos-atributos.js).
También puede definir qué atributos se consideran válidos, a través de las opciones del complemento.
Más detalles sobre esto en la sección de atributos.
La etiqueta <yield> es donde se inyectará el contenido que pase a un componente.
El complemento configura el analizador posthtml para reconocer las etiquetas de cierre autocipulante, por lo que también puede escribir es como <yield /> .
Para la brevedad, usaremos etiquetas de cierre autocipulante en los ejemplos.
Por defecto, el complemento busca componentes con la extensión .html . Puede cambiar esto pasando una variedad de extensiones a la opción fileExtension .
Cuando se usa una matriz, si dos archivos con el mismo nombre coinciden con ambas extensiones, se utilizará el archivo que coincida con la primera extensión en la matriz.
const posthtml = require ( 'posthtml' )
const components = require ( 'posthtml-component' )
posthtml ( [
components ( {
root : './src' , // contains layout.html and layout.md
fileExtension : [ 'html' , 'md' ]
} )
] )
. process ( `<x-layout />` )
. then ( result => console . log ( result . html ) ) // layout.html content Consulte también la carpeta docs-src donde puede encontrar más ejemplos.
Puede clonar este repositorio y ejecutar npm run build para compilarlos.
Puede usar los componentes de múltiples maneras, o también una combinación de ellos.
Si desea usar componentes como 'Incluye', puede definir los nombres de atributos de etiqueta y src .
Usando nuestro ejemplo de componente de botón anterior, podemos definir los nombres de la etiqueta y los atributos y luego usarla así:
Init posthtml:
// index.js
require ( 'posthtml' ) (
require ( 'posthtml-component' ) ( {
root : './src' ,
tag : 'component' ,
attribute : 'src'
} ) )
. process ( /* ... */ )
. then ( /* ... */ ) Si necesita más control sobre la coincidencia de etiquetas, puede pasar una matriz de matcher o objeto único a través de options.matcher .
// index.js
const options = {
root : './src' ,
matcher : [
{ tag : 'a-tag' } ,
{ tag : 'another-one' } ,
{ tag : new RegExp ( `^app-` , 'i' ) } ,
]
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( /* ... */ )
. then ( /* ... */ ) Con posthtml-components no necesita especificar el nombre de la ruta cuando está utilizando la sintaxis x-tag-name .
Configuración posthtml:
// index.js
const options = {
root : './src' ,
tagPrefix : 'x-'
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( /* ... */ )
. then ( /* ... */ )Usar:
<!-- src/index.html -->
< html >
< body >
< x-button > Submit </ x-button >
</ body >
</ html > Si sus componentes están en una subcarpeta, puede usar dot para acceder a él:
<!-- src/components/forms/button.html -->
< x-forms .button > Submit </ x-forms .button > Si sus componentes están en una subcarpeta con múltiples archivos, para evitar escribir el nombre del archivo principal, puede usar index.html sin especificarlo.
Aquí hay un ejemplo:
<!-- src/components/modals/index.html -->
< x-modal .index > Submit </ x-modal .index >
<!-- You may omit "index" part since the file is named "index.html" -->
< x-modal > Submit </ x-modal > Puede pasar opciones a posthtml-parser a través de options.parserOptions .
// index.js
const options = {
root : './src' ,
parserOptions : { decodeEntities : true }
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( 'some HTML' , options . parserOptions )
. then ( /* ... */ ) Importante
Las parserOptions que pasa al complemento también deben aprobarse en el método process en su código, de lo contrario su compilación Posthtml utilizará los valores predeterminados posthtml-parser y anulará todo lo que haya pasado a posthtml-component .
El complemento admite etiquetas de cierre de autocuidado de forma predeterminada, pero debe asegurarse de habilitarlas en el método process en su código también, pasando recognizeSelfClosing: true en el objeto Opciones:
// index.js
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( { root : './src' } ) )
. process ( 'your HTML...' , { recognizeSelfClosing : true } )
. then ( /* ... */ ) Si no agrega esto al process , PostHTML utilizará los valores predeterminados posthtml-parser y no admitirá etiquetas de componentes autocuidas. Esto dará como resultado todo después de que una etiqueta de cierre autocipulante no se emita.
Tiene control total sobre dónde existen sus archivos de componentes. Una vez que configura la ruta de la raíz base de sus componentes, puede configurar varias carpetas.
Por ejemplo, si su raíz es ./src y luego tiene varias carpetas donde tiene sus componentes, por ejemplo ./src/components y ./src/layouts , puede configurar el complemento como a continuación:
// index.js
const options = {
root : './src' ,
folders : [ 'components' , 'layouts' ]
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( /* ... */ )
. then ( /* ... */ )Con los espacios de nombres, puede definir una ruta de raíz de nivel superior a sus componentes.
Puede ser útil para manejar temas personalizados, donde define una raíz de nivel superior específica con una raíz respaldo de cuando no se encuentra un componente y una raíz personalizada para la anulación.
Esto permite crear estructuras de carpetas como esta:
src (carpeta raíz)components (carpeta para componentes como modal, botón, etc.)layouts (carpeta para componentes de diseño como diseño base, encabezado, pie de página, etc.)theme-dark (Carpeta de espacio de nombres para Temo-Dark)components (carpeta para componentes para el tema oscuro)layouts (carpeta para componentes de diseño para tema oscuro)theme-light (carpeta de espacio de nombres para la luz del tema)components (carpeta para componentes para el tema de la luz)layouts (carpeta para componentes de diseño para tema oscuro)custom (carpeta personalizada para anular los temas de su espacio de nombres)theme-dark (carpeta personalizada para anular el tema oscuro)components (carpeta para anular componentes del tema oscuro)layouts (carpeta para anular componentes de diseño del tema oscuro)theme-light (carpeta personalizada para anular el tema de la luz)components (carpeta para anular componentes del tema oscuro)layouts (carpeta para anular componentes de diseño del tema oscuro)Y las opciones serían como:
// index.js
const options = {
// Root for component without namespace
root : './src' ,
// Folders is always appended in 'root' or any defined namespace's folders (base, fallback or custom)
folders : [ 'components' , 'layouts' ] ,
namespaces : [ {
// Namespace name will be prepended to tag name (example <x-theme-dark::button>)
name : 'theme-dark' ,
// Root of the namespace
root : './src/theme-dark' ,
// Fallback root when a component is not found in namespace
fallback : './src' ,
// Custom root for overriding, the lookup happens here first
custom : './src/custom/theme-dark'
} , {
// Light theme
name : 'theme-light' ,
root : './src/theme-light' ,
fallback : './src' ,
custom : './src/custom/theme-light'
} , {
/* ... */
} ]
} ;Use el espacio de nombres de componentes:
<!-- src/index.html -->
< html >
< body >
< x-theme-dark : :button >Submit</ theme-dark : :button >
< x-theme-light : :button >Submit</ theme-light : :button >
</ body >
</ html >Los componentes pueden definir ranuras que se pueden llenar con contenido cuando se usan.
Por ejemplo:
<!-- src/modal.html -->
< div class = " modal " >
< div class = " modal-header " >
< slot : header />
</ div >
< div class = " modal-body " >
< slot : body />
</ div >
< div class = " modal-footer " >
< slot : footer />
</ div >
</ div >Use el componente:
<!-- src/index.html -->
< x-modal >
< fill : header >Header content</ fill : header >
< fill : body >Body content</ fill : body >
< fill : footer >Footer content</ fill : footer >
</ x-modal >Resultado:
<!-- dist/index.html -->
< div class =" modal " >
< div class =" modal-header " >
Header content
</ div >
< div class =" modal-body " >
Body content
</ div >
< div class =" modal-footer " >
Footer content
</ div >
</ div >De manera predeterminada, se reemplaza el contenido de la ranura, pero también puede preparar o agregar el contenido, o mantener el contenido predeterminado al no llenar la ranura.
Agregue un contenido predeterminado en el componente:
<!-- src/modal.html -->
< div class = " modal " >
< div class = " modal-header " >
< slot : header >Default header</ slot : header >
</ div >
< div class = " modal-body " >
< slot : body >content</ slot : body >
</ div >
< div class = " modal-footer " >
< slot : footer >Footer</ slot : footer >
</ div >
</ div > <!-- src/index.html -->
< x-modal >
< fill : body prepend>Prepend body</ fill : body >
< fill : footer append>content</ fill : footer >
</ x-modal >Resultado:
<!-- dist/index.html -->
< div class =" modal " >
< div class =" modal-header " >
Default header
</ div >
< div class =" modal-body " >
Prepend body content
</ div >
< div class =" modal-footer " >
Footer content
</ div >
</ div >Puede empujar el contenido a pilas con nombre que se pueden representar en otro lugar, como en otro componente. Esto puede ser particularmente útil para especificar cualquier JavaScript o CSS requerido por sus componentes.
Primero, agregue una etiqueta <stack> a su HTML:
<!-- src/index.html -->
<html>
<head>
+ <stack name="styles" />
</head>
<body>
<x-modal>
<fill:header>Header content</fill:header>
<fill:body>Body content</fill:body>
<fill:footer>Footer content</fill:footer>
</x-modal>
+ <stack name="scripts" />
</body>
</html>Luego, en componentes modales o en cualquier otro componente infantil, puede llevar contenido a esta pila:
<!-- src/modal.html -->
< div class = " modal " >
< div class = " modal-header " >
< slot : header />
</ div >
< div class = " modal-body " >
< slot : body />
</ div >
< div class = " modal-footer " >
< slot : footer />
</ div >
</ div >
< push name = " styles " >
< link href = " https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css " rel = " stylesheet " >
</ push >
< push name = " scripts " >
< script src = " https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js " ></ script >
</ push >La salida será:
<!-- dist/index.html -->
< html >
< head >
< link href =" https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css " rel =" stylesheet " >
</ head >
< body >
< div class =" modal " >
< div class =" modal-header " >
Header content
</ div >
< div class =" modal-body " >
Body content
</ div >
< div class =" modal-footer " >
Footer content
</ div >
</ div >
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js " > </ script >
</ body >
</ html > El atributo once le permite presionar el contenido solo una vez por ciclo de renderizado.
Por ejemplo, si está representando un componente dado dentro de un bucle, es posible que desee presionar solo el JavaScript y CSS la primera vez que se representa el componente.
Ejemplo.
<!-- src/modal.html -->
< div class =" modal " >
<!-- ... -->
</ div >
<!-- The push content will be pushed only once in the stack -->
< push name =" styles " once >
< link href =" https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css " rel =" stylesheet " >
</ push >
< push name =" scripts " once >
< script src =" https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js " > </ script >
</ push > Por defecto, el contenido se presiona en la pila en el orden dado. Si desea preparar contenido al comienzo de una pila, puede usar el atributo prepend :
< push name =" scripts " >
<!-- This will be second -->
< script src =" /example.js " > </ script >
</ push >
<!-- Later... -->
< push name =" scripts " prepend >
<!-- This will be first -->
< script src =" /example-2.js " > </ script >
</ push > props se pueden pasar a los componentes en los atributos HTML. Para usarlos en un componente, deben definirse en la etiqueta <script props> del componente.
Por ejemplo:
<!-- src/alert.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
{{ title }}
</ div >Usar:
< x-alert title =" Hello world! " />La salida será:
< div >
Hello world!
</ div > Si no se pasa ningún atributo title al componente, se utilizará el valor predeterminado.
< x-my-alert />La salida será:
< div >
Default title
</ div > Inside <script props> Tiene acceso a los accesorios aprobados a través de un objeto llamado props .
Aquí hay un ejemplo de lo que puede hacer con él:
<!-- src/modal.html -->
< script props >
module . exports = {
title : props . title || 'Default title' ,
size : props . size ? `modal- ${ props . size } ` : '' ,
items : Array . isArray ( props . items ) ? props . items . concat ( [ 'first' , 'second' ] ) : [ 'first' , 'second' ]
}
</ script >
< div class =" modal {{ size }} " >
< div class =" modal-header " >
{{ title }}
</ div >
< div class =" modal-body " >
< each loop =" item in items " > < span > {{ item }} </ span > </ each >
</ div >
</ div >Usar:
< x-modal
size =" xl "
title =" My modal title "
items =' ["third", "fourth"] '
class =" modal-custom "
/>La salida será:
< div class =" modal modal-custom modal-xl " >
< div class =" modal-header " >
My modal title
</ div >
< div class =" modal-body " >
< span > first </ span >
< span > second </ span >
< span > third </ span >
< span > fourth </ span >
</ div >
</ div > Observe cómo el atributo class que pasamos al componente se fusiona con el valor del atributo de class del primer nodo dentro de él.
Puede cambiar cómo se fusionan los atributos con accesorios globales definidos a través de opciones, al pasar una función de devolución de llamada.
Por defecto, todos los accesorios están alcanzados al componente y no están disponibles para componentes anidados. Sin embargo, puede cambiar esto en consecuencia a su necesidad.
Crear un componente:
<!-- src/child.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
Prop in child: {{ title }}
</ div > Cree un componente <x-parent> que use <x-child> :
<!-- src/parent.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
Prop in parent: {{ title }}
< x-child />
</ div >Úselo:
< x-parent title =" My title " />La salida será:
< div >
Prop in parent: My title
< div >
Prop in child: Default title
</ div >
</ div > Como puede ver, title en el componente <x-child> representa el valor predeterminado y no el establecido a través de <x-parent> .
Para cambiar esto, debemos prepender el aware: del atributo para pasar los accesorios a los componentes anidados.
< x-parent aware:title =" My title " />La salida ahora será:
< div >
Prop in parent: My title
< div >
Prop in child: My title
</ div >
</ div > Puede pasar cualquier atributo a sus componentes y se agregarán al primer nodo de su componente, o al nodo con un atributo llamado attributes .
Si está familiarizado con Vue.js, este es lo mismo que el llamado atributo de caída. O, con la cuchilla Laravel, sus componentes atributos.
Por defecto, class y style se fusionan con el atributo class y style existentes. Todos los demás atributos se anulan de forma predeterminada.
Si pasa un atributo que se define como un prop , no se agregará al nodo del componente.
Aquí hay un ejemplo:
<!-- src/button.html -->
< script props >
module . exports = {
label : props . label || 'A button'
}
</ script >
< button type =" button " class =" btn " >
{{ label }}
</ button >Use el componente:
<!-- src/index.html -->
< x-button type =" submit " class =" btn-primary " label =" My button " />Resultado:
<!-- dist/index.html -->
< button type =" submit " class =" btn btn-primary " > My button </ button > Si necesita anular los valores de class y el atributo style (en lugar de fusionarlos), simplemente prependa override: al nombre del atributo:
<!-- src/index.html -->
< x-button type =" submit " override:class =" btn-custom " label =" My button " />Resultado:
<!-- dist/index.html -->
< button type =" submit " class =" btn-custom " > My button </ button > Si desea que los atributos se pasen a un nodo determinado, use el atributo attributes :
<!-- src/my-component.html -->
< div class =" first-node " >
< div class =" second-node " attributes >
Hello world!
</ div >
</ div >Use el componente:
<!-- src/index.html -->
< x-my-component class =" my-class " />Resultado:
<!-- dist/index.html -->
< div class =" first-node " >
< div class =" second-node my-class " >
Hello world!
</ div >
</ div >Puede agregar reglas personalizadas para definir cómo se analizan los atributos: usamos posthtml-attrs-parser para manejarlos.
Si las configuraciones predeterminadas para atributos válidos no son adecuados para usted, puede configurarlas como se explica a continuación.
// index.js
const { readFileSync , writeFileSync } = require ( 'fs' )
const posthtml = require ( 'posthtml' )
const components = require ( 'posthtml-component' )
const options = {
root : './src' ,
// Add attributes to specific tag or override defaults
elementAttributes : {
DIV : ( defaultAttributes ) => {
/* Add new one */
defaultAttributes . push ( 'custom-attribute-name' ) ;
return defaultAttributes ;
} ,
DIV : ( defaultAttributes ) => {
/* Override all */
defaultAttributes = [ 'custom-attribute-name' , 'another-one' ] ;
return defaultAttributes ;
} ,
} ,
// Add attributes to all tags, use '*' as wildcard for attribute name that starts with
safelistAttributes : [
'custom-attribute-name' ,
'attribute-name-start-with-*'
] ,
// Remove attributes from all tags that support it
blocklistAttributes : [
'role'
]
}
posthtml ( components ( options ) )
. process ( readFileSync ( 'src/index.html' , 'utf8' ) )
. then ( result => writeFileSync ( 'dist/index.html' , result . html , 'utf8' ) ) Puede trabajar con <slot> y <fill> o puede crear un componente para cada bloque de su componente, y también puede admitirlos.
Puede encontrar un ejemplo de este interior docs-src/components/modal . El siguiente es una breve explicación de ambos enfoques.
Supongamos que queremos crear un componente para Bootstrap Modal.
El código requerido es:
<!-- Modal HTML -->
< div class =" modal fade " id =" exampleModal " tabindex =" -1 " aria-labelledby =" exampleModalLabel " aria-hidden =" true " >
< div class =" modal-dialog " >
< div class =" modal-content " >
< div class =" modal-header " >
< h1 class =" modal-title fs-5 " id =" exampleModalLabel " > Modal title </ h1 >
< button type =" button " class =" btn-close " data-bs-dismiss =" modal " aria-label =" Close " > </ button >
</ div >
< div class =" modal-body " >
...
</ div >
< div class =" modal-footer " >
< button type =" button " class =" btn btn-secondary " data-bs-dismiss =" modal " > Close </ button >
< button type =" button " class =" btn btn-primary " > Save changes </ button >
</ div >
</ div >
</ div >
</ div >Hay casi tres bloqueos de código: el encabezado, el cuerpo y el pie de página.
Para que pudiéramos crear un componente con tres ranuras:
<!-- Modal component -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
- <h1 class="modal-title fs-5" id="exampleModalLabel">Modal title</h1>
+ <slot:header />
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
+ <slot:body />
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
+ <slot:footer />
- <button type="button" class="btn btn-primary">Save changes</button>
</div>
</div>
</div>
</div>Entonces podemos usarlo así:
< x-modal
id =" exampleModal "
aria-labelledby =" exampleModalLabel "
>
< slot:header >
< h5 class =" modal-title " id =" exampleModalLabel " > My modal </ h5 >
</ slot:header >
< slot:body >
Modal body content goes here...
</ slot:body >
< slot:footer close =" false " >
< button type =" button " class =" btn btn-primary " > Confirm </ button >
</ slot:footer >
</ x-modal >Otro enfoque es dividir el componente en componentes más pequeños, pasando atributos a cada uno de ellos.
Entonces creamos un componente principal y luego tres componentes más pequeños diferentes:
<!-- Main modal component -->
< div class =" modal fade " tabindex =" -1 " aria-hidden =" true " >
< div class =" modal-dialog " >
< div class =" modal-content " >
< yield />
</ div >
</ div >
</ div > <!-- Header modal component -->
< div class =" modal-header " >
< yield />
</ div > <!-- Body modal component -->
< div class =" modal-body " >
< yield />
</ div > <!-- Footer modal component -->
< div class =" modal-footer " >
< yield />
</ div >Y luego puedes usarlo así:
< x-modal
id =" exampleModal "
aria-labelledby =" exampleModalLabel "
>
< x-modal .header >
< h5 class =" modal-title " id =" exampleModalLabel " > My modal </ h5 >
</ x-modal .header >
< x-modal .body >
Modal body content goes here...
</ x-modal .body >
< x-modal .footer >
< button type =" button " class =" btn btn-primary " > Confirm </ button >
</ x-modal .footer >
</ x-modal >Como se dijo de esta manera, puede pasar atributos a cada uno de ellos, sin definir accesorios.
También puede combinar ambos enfoques y luego usarlos con ranuras o con componentes pequeños:
<!-- Modal -->
< div
class =" modal fade "
tabindex =" -1 "
aria-hidden =" true "
aria-modal =" true "
role =" dialog "
>
< div class =" modal-dialog " >
< div class =" modal-content " >
< if condition =" $slots.header?.filled " >
< x-modal .header >
< slot:header />
</ x-modal .header >
</ if >
< if condition =" $slots.body?.filled " >
< x-modal .body >
< slot:body />
</ x-modal .body >
</ if >
< if condition =" $slots.footer?.filled " >
< x-modal .footer close =" {{ $slots.footer?.props.close }} " >
< slot:footer />
</ x-modal .footer >
</ if >
< yield />
</ div >
</ div > <!-- /.modal-dialog -->
</ div > <!-- /.modal -->Ahora puede usar su componente con ranuras o con componentes pequeños.
Como puede notar, mediante el uso de ranuras, ya puede usar también sus componentes pequeños, por lo que también puede pasar accesorios a través de $slots que tienen todos los props pasados por ranura, y también verifique si se llena la ranura.
Si está migrando de posthtml-extend y/o posthtml-modules , para seguir actualizaciones aquí: Posthtml-Componentes/problemas/16.
Consulte las directrices y la guía de contribución posthtml.
Gracias a todos los contribuyentes de Posthtml y especialmente a los contribuyentes posthtml-extend y posthtml-modules , como parte del código es robado Inspirado desde estos complementos. Muchas gracias también al motor de plantilla de Blade Laravel.