Компоненты, вдохновленные лезвием Laravel, для PosTHTML
npm i -D posthtml-componentЭтот плагин PosTHTML обеспечивает синтаксис для HTML для использования компонентов в ваших шаблонах HTML. Если вы знакомы с Blade, React, Vue или аналогичным, вы найдете синтаксис быть знакомым, так как этот плагин вдохновлен ими.
См. Также первый пользовательский интерфейс Bootstrap, используя этот плагин, и проверьте также шаблон стартера здесь.
| Имя | Тип | По умолчанию | Описание |
|---|---|---|---|
| корень | String | './' | Корневый путь, где искать компоненты. |
| папки | String[] | [''] | Массив путей относительно options.root или определенные пространства имен. |
| FileExtension | String|String[] | 'html' | Расширения файлов компонентов для поиска. |
| tagprefix | String | 'x-' | Tag Prefix. |
| ярлык | String|Boolean | false | Тег компонента. Используйте с options.attribute . Логин только false . |
| атрибут | String | 'src' | Атрибут для использования для определения пути к файлу компонента. |
| Пространства имен | String[] | [] | Массив корневых путей пространства имен, отступления и траектории переопределения. |
| namespacesparator | String | '::' | Разделитель пространства имен для имен тегов. |
| урожай | String | 'yield' | Имя тега для инъекции содержимого основного компонента. |
| слот | String | 'slot' | Имя тега для слотов |
| наполнять | String | 'fill' | Имя тега для заполнения слотов. |
| Slotseparator | String | ':' | Имя сепаратора для <slot> и <fill> тегов. |
| куча | String | 'stack' | Имя тега для <stack> . |
| толкать | String | 'push' | Имя тега для <push> . |
| propsscriptattribute | String | 'props' | Атрибут в <script props> для получения компонентов. |
| реквизит | String | 'props' | Название объекта внутри скрипта для обработки реквизита. |
| Propsattribute | String | 'props' | Имя атрибута для определения реквизита как JSON на теге компонента. |
| репутация | String | 'props' | Используется для получения реквизита, передаваемых в слот через $slots.slotName.props . |
| Парицеропции | Object | {recognizeSelfClosing: true} | Пропустите варианты в posthtml-parser . |
| выражения | Object | {} | Пропустить параметры на posthtml-expressions . |
| плагины | Array | [] | Плагины PosTHTML для применения к каждому проанализированному компоненту. |
| маттер | Object | [{tag: options.tagPrefix}] | Массив объектов, используемых для совпадения тегов. |
| ATTRSPARSERRULES | Object | {} | Дополнительные правила для атрибутов плагина анализатора. |
| строгий | Boolean | true | Переключить исключение. |
| MergeCustomizer | Function | function | Обратный вызов для Lodash mergeWith для слияния options.expressions.locals . |
| коммунальные услуги | Object | {merge: _.mergeWith, template: _.template} | Методы полезности переданы <script props> . |
| elementattributes | Object | {} | Объект с именами тегов и модификаторами функций valid-attributes.js . |
| Safelistattributes | String[] | ['data-*'] | Массив имен атрибутов для добавления в действительные атрибуты по умолчанию. |
| BlockListattributes | String[] | [] | Массив имен атрибутов для удаления из допустимых атрибутов по умолчанию. |
Создайте компонент:
<!-- src/button.html -->
< button type =" button " class =" btn " >
< yield > </ yield >
</ button >Используйте его:
<!-- 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' ) )Результат:
<!-- dist/index.html -->
< html >
< body >
< button type =" submit " class =" btn btn-primary " > Submit </ button >
</ body >
</ html > Возможно, вы заметили, что компонент src/button.html содержит type и атрибуты class , и что мы также передали эти атрибуты, когда мы использовали его в src/index.html .
Результатом является то, что type был переопределен, и class был объединен.
По умолчанию атрибуты class и style объединены, в то время как все другие атрибуты переопределены. Вы также можете переопределить атрибуты class и style , предположив override: к атрибуту класса.
Например:
< x-button override:class =" btn-custom " > Submit </ x-button >
<!-- Output -->
< button type =" button " class =" btn-custom " > Submit </ button > Все атрибуты, которые вы передаете в компонент, будут добавлены в первый узел вашего компонента или к узлу с атрибутом с именем attributes , только если они не определены как props через <script props> или если они не являются «известными атрибутами» (см. Valid-ttributes.js).
Вы также можете определить, какие атрибуты считаются действительными, через параметры плагина.
Более подробная информация об этом в разделе «Атрибуты».
Тег <yield> - это то, где будет введен контент, который вы передаете компоненту.
Плагин настраивает анализатор PosTHTML для распознавания самозакрывающихся тегов, так что вы также можете просто написать, как <yield /> .
Для краткости мы будем использовать самозакрывающие теги в примерах.
По умолчанию плагин ищет компоненты с расширением .html . Вы можете изменить это, передавая массив расширений в опцию fileExtension .
При использовании массива, если два файла с одинаковым именем соответствуют обоим расширениям, будет использоваться файл, соответствующий первым расширению в массиве.
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 Смотрите также папку docs-src , где вы можете найти больше примеров.
Вы можете клонировать этот репо и запустить npm run build чтобы скомпилировать их.
Вы можете использовать компоненты несколькими способами или также их комбинацией.
Если вы хотите использовать компоненты в качестве «включения», вы можете определить имена атрибутов TAG и src .
Используя наш предыдущий пример компонента кнопки, мы можем определить имена тега и атрибутов, а затем использовать его так:
Init posthtml:
// index.js
require ( 'posthtml' ) (
require ( 'posthtml-component' ) ( {
root : './src' ,
tag : 'component' ,
attribute : 'src'
} ) )
. process ( /* ... */ )
. then ( /* ... */ ) Если вам нужно больше контроля над соответствием тегов, вы можете передать массив сочетания или отдельного объекта через 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 ( /* ... */ ) С posthtml-components вам не нужно указывать имя пути, когда вы используете синтаксис x-tag-name .
Настройка PosTHTML:
// index.js
const options = {
root : './src' ,
tagPrefix : 'x-'
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( /* ... */ )
. then ( /* ... */ )Использовать:
<!-- src/index.html -->
< html >
< body >
< x-button > Submit </ x-button >
</ body >
</ html > Если ваши компоненты находятся в подпапке, вы можете использовать dot для доступа к ней:
<!-- src/components/forms/button.html -->
< x-forms .button > Submit </ x-forms .button > Если ваши компоненты находятся в подразделе с несколькими файлами, то чтобы не записать основное имя файла, вы можете использовать index.html без указания его.
Вот пример:
<!-- 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 > Вы можете перенести параметры в posthtml-parser через options.parserOptions .
// index.js
const options = {
root : './src' ,
parserOptions : { decodeEntities : true }
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( 'some HTML' , options . parserOptions )
. then ( /* ... */ ) Важный
parserOptions которые вы передаете в плагин, также должны быть переданы в методе process в вашем коде, в противном случае ваша сборка PosTHTML будет использовать по умолчанию posthtml-parser и будет переопределять все, что вы передали в posthtml-component .
Плагин поддерживает самостоятельные теги по умолчанию, но вам необходимо убедиться, что они также включили их в метод process в вашем коде, пропустив recognizeSelfClosing: true в объекте параметров:
// index.js
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( { root : './src' } ) )
. process ( 'your HTML...' , { recognizeSelfClosing : true } )
. then ( /* ... */ ) Если вы не добавите это в process , PosTHTML будет использовать по умолчанию posthtml-parser и не будет поддерживать самостоятельные компоненты. Это приведет к тому, что все после того, как самозакрывающаяся тег не будет выходить.
У вас есть полный контроль над тем, где существуют ваши компонентные файлы. После того, как вы установите базовый корневой путь ваших компонентов, вы можете установить несколько папок.
./src/layouts , ./src/components ваш корень ./src
// index.js
const options = {
root : './src' ,
folders : [ 'components' , 'layouts' ]
} ;
require ( 'posthtml' ) ( require ( 'posthtml-component' ) ( options ) )
. process ( /* ... */ )
. then ( /* ... */ )С помощью пространств имен вы можете определить корневой путь верхнего уровня к своим компонентам.
Это может быть полезно для обработки пользовательских тем, где вы определяете определенный корень верхнего уровня с помощью резервного корня, когда компонент не найден, и пользовательский корень для переоценки.
Это позволяет создавать такие структуры папок, как это:
src (корневая папка)components (папка для компонентов, таких как модальная, кнопка и т. Д.)layouts (папка для компонентов макета, таких как базовый макет, заголовок, нижний колонтитул и т. Д.)theme-dark (папка пространства имен для тематического тема)components (папка для компонентов для темы Dark)layouts (папка для компонентов макета для темной темы)theme-light (папка пространства имен для темы)components (папка для компонентов для легкой темы)layouts (папка для компонентов макета для темной темы)custom (пользовательская папка для переопределения тем и имен.theme-dark (пользовательская папка для переопределения темной темы)components (папка для переопределения компонентов темы Dark)layouts (папка для компонентов переопределения компонентов темной темы)theme-light (пользовательская папка для темы переопределения света)components (папка для переопределения компонентов темы Dark)layouts (папка для компонентов переопределения компонентов темной темы)И варианты будут похожи на:
// 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'
} , {
/* ... */
} ]
} ;Используйте пространство имен компонентов:
<!-- src/index.html -->
< html >
< body >
< x-theme-dark : :button >Submit</ theme-dark : :button >
< x-theme-light : :button >Submit</ theme-light : :button >
</ body >
</ html >Компоненты могут определять слоты, которые могут быть заполнены контентом при использовании.
Например:
<!-- 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 >Используйте компонент:
<!-- 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 >Результат:
<!-- 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 >По умолчанию содержимое слота заменяется, но вы также можете добавить или добавить контент или сохранить содержание по умолчанию, не заполняя слот.
Добавьте немного контента по умолчанию в компонент:
<!-- 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 >Результат:
<!-- 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 >Вы можете подтолкнуть контент к названным стекам, которые можно отображать где -то еще, как в другом компоненте. Это может быть особенно полезно для указания любых JavaScript или CSS, требуемых вашим компонентами.
Во -первых, добавьте тег <stack> в свой 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>Затем, в модальных компонентах или в любых других дочерних компонентах, вы можете подтолкнуть контент в этот стек:
<!-- 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 >Вывод будет:
<!-- 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 > Атрибут once позволяет вам нажимать на содержание только один раз на цикл рендеринга.
Например, если вы выполняете заданный компонент в цикле, вы можете только выдвинуть JavaScript и CSS при первом витрине компонента.
Пример.
<!-- 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 > По умолчанию контент толкоруется в стеке в данном порядке. Если вы хотите подготовить контент в начало стека, вы можете использовать атрибут 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 могут быть переданы компонентам в атрибутах HTML. Чтобы использовать их в компоненте, они должны быть определены в теге компонента <script props> .
Например:
<!-- src/alert.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
{{ title }}
</ div >Использовать:
< x-alert title =" Hello world! " />Вывод будет:
< div >
Hello world!
</ div > Если в компонент не передается атрибут title , значение по умолчанию будет использоваться.
< x-my-alert />Вывод будет:
< div >
Default title
</ div > Inside <script props> у вас есть доступ к передаваемом реквизитам через объект с именем props .
Вот пример того, что вы можете с этим сделать:
<!-- 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 >Использовать:
< x-modal
size =" xl "
title =" My modal title "
items =' ["third", "fourth"] '
class =" modal-custom "
/>Вывод будет:
< 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 > Обратите внимание, как атрибут class , который мы передали в компонент, объединяется со значением атрибута class первого узла внутри него.
Вы можете изменить то, как атрибуты объединяются с глобальными реквизитами, определенными с помощью опций, путем выполнения функции обратного вызова.
По умолчанию все реквизиты подключены к компоненту и недоступны для вложенных компонентов. Однако вы можете изменить это соответственно на вашу потребность.
Создайте компонент:
<!-- src/child.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
Prop in child: {{ title }}
</ div > Создайте компонент <x-parent> , который использует <x-child> :
<!-- src/parent.html -->
< script props >
module . exports = {
title : props . title || 'Default title'
}
</ script >
< div >
Prop in parent: {{ title }}
< x-child />
</ div >Используйте его:
< x-parent title =" My title " />Вывод будет:
< div >
Prop in parent: My title
< div >
Prop in child: Default title
</ div >
</ div > Как вы можете видеть, title в <x-child> компонент отображает значение по умолчанию, а не то, что установлено через <x-parent> .
Чтобы изменить это, мы должны подготовить aware: к имени атрибута, чтобы передать реквизиты вложенных компонентам.
< x-parent aware:title =" My title " />Вывод теперь будет:
< div >
Prop in parent: My title
< div >
Prop in child: My title
</ div >
</ div > Вы можете передать любые атрибуты вашим компонентам, и они будут добавлены в первый узел вашего компонента или в узел с атрибутом с именем attributes .
Если вы знакомы с Vue.js, это то же самое, что и так называемый атрибут осеннего. Или, с лезвием Laravel, это компонентные атрибуты.
По умолчанию class и style объединены с существующим атрибутом class и style . Все остальные атрибуты переопределены по умолчанию.
Если вы передаете атрибут, который определяется как prop , он не будет добавлен в узел компонента.
Вот пример:
<!-- src/button.html -->
< script props >
module . exports = {
label : props . label || 'A button'
}
</ script >
< button type =" button " class =" btn " >
{{ label }}
</ button >Используйте компонент:
<!-- src/index.html -->
< x-button type =" submit " class =" btn-primary " label =" My button " />Результат:
<!-- dist/index.html -->
< button type =" submit " class =" btn btn-primary " > My button </ button > Если вам нужно переопределить значения атрибутов class и style (вместо их объединения), просто приготовьте override: к имени атрибута:
<!-- src/index.html -->
< x-button type =" submit " override:class =" btn-custom " label =" My button " />Результат:
<!-- dist/index.html -->
< button type =" submit " class =" btn-custom " > My button </ button > Если вы хотите, чтобы атрибуты были переданы в определенный узел, используйте атрибут attributes :
<!-- src/my-component.html -->
< div class =" first-node " >
< div class =" second-node " attributes >
Hello world!
</ div >
</ div >Используйте компонент:
<!-- src/index.html -->
< x-my-component class =" my-class " />Результат:
<!-- dist/index.html -->
< div class =" first-node " >
< div class =" second-node my-class " >
Hello world!
</ div >
</ div >Вы можете добавить пользовательские правила, чтобы определить, как анализируются атрибуты-мы используем PosTHTML-ATTRS-Parser для их обработки.
Если конфигурации по умолчанию для действительных атрибутов не подходят для вас, вы можете настроить их, как описано ниже.
// 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' ) ) Вы можете работать с <slot> и <fill> или вы можете создать компонент для каждого блока вашего компонента, и вы также можете поддерживать их обоих.
Вы можете найти пример этого внутри docs-src/components/modal . Ниже приведено короткое объяснение обоих подходов.
Предположим, мы хотим создать компонент для начальной загрузки.
Требуемый код:
<!-- 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 >Есть почти три блока кода: заголовок, тело и нижний колонтитул.
Таким образом, мы могли бы создать компонент с тремя слотами:
<!-- 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>Затем мы можем использовать это так:
< 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 >Другой подход заключается в разделении компонента на небольших компонентах, передавая атрибуты каждому из них.
Таким образом, мы создаем основной компонент, а затем три разных меньших компонента:
<!-- 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 >И тогда вы можете использовать его так:
< 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 >Как сказано таким образом, вы можете передать атрибуты каждому из них, не определяя реквизит.
Вы также можете объединить оба подхода, а затем использовать их с слотами или с небольшими компонентами:
<!-- 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 -->Теперь вы можете использовать свой компонент с помощью слотов или с небольшими компонентами.
Как вы можете заметить, используя слоты, вы уже можете использовать также свои небольшие компоненты, и поэтому вы также можете пройти реквизит через $slots , в которых все props проходят через слот, а также проверить, заполняется ли слот.
Если вы мигрируете из posthtml-extend и/или posthtml-modules пожалуйста, следуйте обновлениям здесь: POSTHTML-Components/Проблемы/16.
См. Руководство по руководству и вкладу.
Благодаря всем участникам PosTHTML и особенно вкладчике posthtml-extend и posthtml-modules , как часть кода украденный Вдохновлен от этих плагинов. Огромная благодарность также шаблонному двигателю Laravel Blade.