
MaskJs - ist ein Markup | Vorlage | Modulare HMVC -Engine für moderne und schnelle Web ( Browser ), Server ( NODEJS ) oder Mobile ( PhoneGAP ). Komponentenbasierte Architektur vereinfacht das Definieren, Implementieren und Komponieren locker gekoppelter unabhängiger Elemente in eine einzelne Anwendung.
Ressourcen:
? Atma.js
? Maskfiddle
Wiki
Beispiele
Werkzeuge
1 Markup1.1 Maske1.2 HTML2 Bibliotheken2.1 Komponenten2.2 Bindungen2.3 Jask2.4 jQuery2.5 Abhängigkeitsinjektion3 Leistung4 Nodejs5 Browserunterstützung6 Plugins7 Schnellstart8 beitragen8.1 Build8.2 Test9 Changelog1 Markup Wir unterstützen mask und html -Syntax für das Schreiben Ihrer Vorlagen. Und Sie können sie sogar innerhalb einer Vorlage mischen, da jeder von ihnen seine Vorteile hat.
1.1 Maskensyntax[Template → Mask AST → Shadow DOM → Live DOM][Template → Mask AST → HTML] import CustomComponent from ' Foo.mask '
.container {
h4 > ' Title '
section .content {
span > ' Hello ~ name ! '
if ( admins . includes (name) ) {
em > ' Admin '
}
}
CustomComponent {
button x-tap = ' changeName ' >
' ~[ bind: name ] '
for ( tag of tags ) {
h4 > ' ~ tag.title '
}
}
}1.2 HTML -SyntaxHier ist nichts Neues für Sie. Alte gute HTML -Syntax, um die Vorlagen zu definieren. Wir ermutigen jedoch dringend, die Maskensyntax zu verwenden, da die Vorlagen kleiner, sauberer und zusätzliche Funktionen sind.
< h4 > ~[name] </ h4 >
< Dialog >
< div > Hello Foo </ div >
</ Dialog > 1.3 HTML innerhalb der MaskeSie können sogar HTML -Blöcke in einer Maskensyntax verwenden
ul {
< li > Foo
< li > Bar
}MaskJS hat eine extrem erweiterbare API auf der Grundlage von Schnittstellen und Verträgen. Es unterstützt benutzerdefinierte Tag -Handler, benutzerdefinierte Attributhandler, Modell -Utils .
MaskJS Standard Build enthält Unterprojekte:
CompoJS,Bindings,jMask.
2 Libies? Alle Pakete sind bereits in Maskjs -Quellen eingebettet.
2.1 Komponenten? Lesen Sie mehr ... ↵
Kern des HMVC -Motors. Einfache Compo -Beispiel:
export class CustomComponentCtr {
// slots example
@ mask . deco . slot ( )
onRefreshDate ( ) {
this . model . date = new Date ( ) ;
}
@ mask . deco . slot ( )
domInsert ( ) {
alert ( this . $ . innerWidth ( ) ) ;
}
// events example
@ mask . deco . event ( 'click: button' )
onButtonClicked ( ) {
alert ( this . model . date ) ;
}
onRenderStart ( model , ctx ) {
// override model
this . model = { date : new Date ( ) ; }
}
onRenderEnd: function ( elements , model , ctx ) {
this . $ // is a domLibrary (jQuery-lite, jQuery/Zepto/Kimbo) wrapper over `elements`
}
dispose ( ) {
// do some cleanup
}
} ; import ' ./CustomComponent.less '
import CustomComponentCtr from ' ./CustomComponentCtr.ts '
define CustomComponent extends CustomComponentCtr {
h1 {
' Date ~[ bind: _ . formatDate (date) ] '
}
button .btn x-tap = ' onRefreshDate ' {
i .material-icons > ' update '
' Refresh '
}
}2.2 Bindungen ? Lesen Sie mehr ... ↵ IE9+
Maskjs selbst unterstützt einfache Interpolationen. Dies bedeutet, dass die Modelle nur beim Rendern zugegriffen werden, aber mit dieser Funktion können Sie einzelne oder zwei Bindungen definieren. Da MaskJs ein DOM -basierter Motor ist, sind die Bindungen sofort.
Einfache Bindungen Probe:
h4 > ' ~[ bind: fooDate . getSeconds () * barAge ] '
input type = date >
dualbind value = ' fooDate ' ;
input type = number >
dualbind value = ' barAge ' ;
/*
* `dualbind` component also supports much more properties and configurations
*/2.3 Jask? Lesen Sie mehr ... ↵
Jmask bietet JQuery-Alike-Syntax für die dynamischen Maskdom-Manipulationen.
2.4 jQueryMaskjs ist lose mit der DOM-Bibliothek wie JQuery-Septo-Kimbo verbunden. Es bedeutet, dass es nicht von einer DOM -Bibliothek abhängt, aber es wird dringend empfohlen, eine zu verwenden. Zusätzlich gibt es einige Erweiterungen wie
$ . fn . appendMask
$ . fn . prependMask
$ . fn . beforeMask
$ . fn . afterMask
$ . fn . emptyAndDispose
$ . fn . removeAndDispose
//e.g.
$ ( '.foo' ) . appendMask ( 'h4 > "~[title]"' , { title : 'Hello' } ) ;Sie müssten also niemals die HTML verwenden.
2.5 Abhängigkeitsinjektion? Lesen Sie mehr ... ↵
Sie können Argumente für define der Erklärung oder für den Konstruktor kommentieren. Wenn Sie die Werte für InitialisierungsmaskJs nicht angeben, werden Sie dies mit einem registrierten IOC -Container für Sie ausführen.
Die Bibliothek ist nicht enthalten, Sie können jede andere DI -Bibliothek verwenden. MaskJs benötigt nur einen IOC -Behälter mit einer einzelnen Methode: .resolve(Type):Any .
import * as IStore from services;
define UserList (store: IStore) {
foreach ( user of store . getUsers () ) {
div > ' ~ user.username '
}
// or in constructor
function constructor ( store : IStore ) {
this . store = store;
}
}3 LeistungWir achten sehr auf die Leistung, insbesondere auf die mobile CPU. Der DOM -basierte und der Shadow DOM -Ansatz ist der schnellste Weg, um eine hierarchische Komponentenstruktur zu erstellen.
Einige Benchmarks:
4 Node.jsMaskJs auf dem Server
? Mask.node ↵ Server.lib ↵
server , client oder both5 Browserunterstützung6 PluginsEs gibt bereits viele Plugins, Komponenten und nützliche Dienstprogramme. Einige von ihnen lohnt sich zu überprüfen:
7 SchnellstartDie meisten einfachen MaskJs -Beispiele, um anzuzeigen, woher Sie beginnen können:
<!DOCTYPE html >
< html >
< body >
< script type =' text/mask ' data-run =' auto ' >
import Counter from './Counter' ;
h4 > 'Counter with 1 second step'
Counter x - interval = 1 ;
h4 > 'Counter with 5 seconds step'
Counter x - interval = 5 ;
</ script >
< script src =' https://unpkg.com/maskjs ' > </ script >
</ body >
</ html > // Create the file `Counter.mask`
define Counter {
var meta = {
attributes : {
' x-interval ' : ' number '
}
};
var scope = {
counter : 0 ,
timer : null
};
slot domInsert () {
this . scope . timer = setTimeout (() => {
++ this . scope . counter ;
}, this . xInterval )
}
function dispose () {
clearTimeout ( this . scope . timer );
}
div > ' ~[ bind: this . scope . counter ]
}8 beitragen8.1 Build $ git submodule init && git submodule update
$ npm install
$ npm run build8.2 Test $ npm install
$ npm test9 Changelog ? Vollständige Liste anzeigen ... ↵ @latest
0.64.0
Eigenschaften
div [style .backgroundColor ] = 'red'; @latest
0.60.0
Warten Sie Aussagen, Komponenten und auch Module
define Foo {
function async onRenderStart () {
this . model = await LoadUserExample ();
}
h4 > ' ~ userName '
}
// Component
await Foo {
@progress > i > ' Loading user ' ;
}
// Promises
await ( this . getCurrentUser () ) {
@progress > i > ' Loading user ' ;
@done ( user ) {
h4 > ' ~ user.userName '
}
@fail ( error ) {
.danger > ' ~ error.message '
}
}
// Modules
import async Foo from ' ./Foo ' ;
heading > ' Some heading '
await Foo {
@progress > ' Loading and initilizing the module '
} 0.58.0
Dekorateure für Methoden und Knoten
[ IsAuthorized ]
div > ' Hello ~ user '
[ LogCall ]
function doSmth () {
// ...
} Asynchronen und private Methoden. Für Browser, die async/await -Funktion der ES2017 noch nicht unterstützen, verwenden Sie bitte postmask-babel -Plugin.
slot private async upload () {
await MyService . doSmth ();
} 0.57.13
Module
Namespace Routing
import FooService from services;
h4 > ' ~ FooService.doSmth () ' Sie können auch den Basispfad für die Routing, z. B. mask.Module.cfg('baseNs', '/src/') konfigurieren.
Wenn das Modul nicht geladen oder nicht auf das Namespace -Repository eingestellt ist, laden wir es für Sie auf dem aufgelösten Pfad, z. B.
'/src/services/FooService.js'
Präfix -Routing
import MyButton from ' @controls/MyButton ' ;
MyButton x-tap = ' clicked ' ;Sie müssen zuerst das Präfix konfigurieren, z. B.:
mask . Module . cfg ( 'prefixes.controls' , '/src/controls/{0}/{1}.mask' ) ; 0.57.0
Typa -Anmerkungen für Argumente: (argumentName: argumentType, ...)
import * as IFoo from ' /service/IFoo.js ' ;
import * as IBar from ' /service/IBar.js ' ;
define MyCompo (foo: IFoo) {
function constructor ( bar : IBar ) {
this . bar = bar;
}
span > `~[foo .someMethod ()]`
} 0.56.5
Funktionsumfang: Importieren und Definieren von Argumenten
import * as Service from ' /services/UserService.js ' ;
define UserEditor (user) {
slot save () {
Service
. changeUserName ( user . id , user . name )
. then (() => console . log ( ' saved! ' ));
}
input > dualbind value = ' user.name ' ;
button x-tap = save > ' Save '
} sync , da die Importlade für eine bessere Leistung parallel ist, aber die Bündel sollten synchron geladen werden, da sie dann alle Ressourcen registrieren.
import sync from ' ./MyComponentsBundle ' ;
import FooCompo from ' ./Foo ' ;
// ... 0.55.1
0.55.0
Asynchronen Importe.
import async Foo from ' ./Foo.mask ' ;
h4 > ' MyHeader '
await Foo ; h4 -Header wird während des Foo möglicherweise noch geladen.
define und let Argumente unterstützen
define Foo (user) {
h4 > ' ~ user.name '
}
Foo ( me ) ; mask . render ( template , { me : { name : 'TestUser' } } ) ;© ️ MIT - 2021 ATMA.JS -Projekt