
Maskjs - est un balisage | modèle | Moteur HMVC modulaire pour les applications modernes et rapides Web ( navigateur ), serveur ( NodeJS ) ou mobile ( PhoneGap ). L'architecture basée sur les composants simplifie la définition, la mise en œuvre et la composition d'éléments indépendants couplés de manière lâche dans une seule application.
Ressources:
? Atma.js
? Masque
Wiki
Exemples
Outils
1 Marquage1.1 Masque1.2 HTML2 bibliothèques2.1 composants2.2 Backings2.3 JMASK2.4 jQuery2.5 Injection de dépendance3 performances4 nodejs5 Prise en charge du navigateur6 plugins7 Démarrage rapide8 contribuer8.1 construire8.2 Test9 Changelog1 Marquage Nous prenons en charge la syntaxe mask et html pour écrire vos modèles. Et vous pouvez même les mélanger dans un modèle, car chacun d'eux a ses avantages.
1.1 Syntaxe de masque[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 Syntaxe HTMLVoici rien de nouveau pour vous. Old bonne syntaxe HTML pour définir les modèles. Mais nous encourageons fortement à utiliser la syntaxe du masque, car les modèles sont plus petits, plus propres et avec des fonctionnalités supplémentaires.
< h4 > ~[name] </ h4 >
< Dialog >
< div > Hello Foo </ div >
</ Dialog > 1.3 HTML dans le masqueVous pouvez même utiliser des blocs HTML dans une syntaxe de masque
ul {
< li > Foo
< li > Bar
}MaskJS a une API extrêmement extensible en fonction des interfaces et des contrats. Il prend en charge les gestionnaires de balises personnalisées , les gestionnaires d'attribut personnalisés , les utilisateurs de modèles.
MaskJS Build par défaut contient des sous-projets:
CompoJS,Bindings,jMask.
2 libaires? Tous les packages sont déjà intégrés dans des sources MaskJS.
2.1 composants? En savoir plus ... ↵
Noyau du moteur HMVC. Échantillon de compo simple:
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 Backings ? En savoir plus ... ↵ IE9+
MaskJS prend en charge les interpolations simples. Cela signifie que les modèles ne sont accessibles que lorsqu'ils sont rendus, mais avec cette fonctionnalité, vous pouvez définir des liaisons uniques ou doubles. Comme MaskJS est un moteur basé sur DOM, les liaisons sont instantanées.
Échantillon de liaisons simples:
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 JMASK? En savoir plus ... ↵
JMASK propose une syntaxe de jQuery-Alike pour les manipulations dynamiques du masque.
2.4 jQueryMaskJS est agité avec la bibliothèque DOM, comme jQuery-Zepto-Kimbo. Cela signifie qu'il ne dépend d'aucune bibliothèque DOM, mais il est fortement recommandé d'en utiliser un. De plus, il y a des extensions, comme
$ . fn . appendMask
$ . fn . prependMask
$ . fn . beforeMask
$ . fn . afterMask
$ . fn . emptyAndDispose
$ . fn . removeAndDispose
//e.g.
$ ( '.foo' ) . appendMask ( 'h4 > "~[title]"' , { title : 'Hello' } ) ;Vous n'auriez donc jamais besoin d'utiliser le HTML.
2.5 Injection de dépendance? En savoir plus ... ↵
Vous pouvez annoter les arguments pour define la déclaration ou pour son constructeur et si vous ne fournissez pas les valeurs sur l'initialisation MaskJS le fera pour vous en utilisant un conteneur IOC enregistré.
La bibliothèque n'est pas incluse, vous pouvez utiliser n'importe quelle autre bibliothèque DI. MaskJS nécessite uniquement un conteneur IOC avec une seule méthode: .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 performancesNous faisons complètement attention aux performances, en particulier sur le CPU mobile. L'approche DOM basée sur DOM et Shadow Dom est le moyen le plus rapide de créer une structure de composants hiérarchiques.
Quelques repères:
4 node.jsMaskjs sur le serveur
? Mask.node ↵ Server.lib ↵
server , client ou both5 Prise en charge du navigateur6 pluginsIl existe déjà de nombreux plugins, composants et utilitaires utiles. Certains d'entre eux valent la peine de vérifier:
7 Démarrage rapideLa plupart des maskjjs simples pour montrer d'où vous pourriez commencer:
<!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 contribuer8.1 construire $ git submodule init && git submodule update
$ npm install
$ npm run build8.2 Test $ npm install
$ npm test9 Changelog ? Afficher la liste complète ... ↵ @latest
0.64.0
Propriétés
div [style .backgroundColor ] = 'red'; @latest
0.60.0
Attendre les déclarations, les composants et aussi les modules
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
Décorateurs pour les méthodes et les nœuds
[ IsAuthorized ]
div > ' Hello ~ user '
[ LogCall ]
function doSmth () {
// ...
} Méthodes asynchrones et privées. Pour les navigateurs qui ne prennent pas encore en charge la fonction async/await ES2017, veuillez utiliser le plugin postmask-babel .
slot private async upload () {
await MyService . doSmth ();
} 0.57.13
Modules
Routage de l'espace de noms
import FooService from services;
h4 > ' ~ FooService.doSmth () ' Vous pouvez également configurer le chemin de base pour le routage, par exemple mask.Module.cfg('baseNs', '/src/')
Si le module n'est pas chargé ou n'est pas défini sur le référentiel d'espace de noms, nous le chargerons pour vous par le chemin résolu, par exemple
'/src/services/FooService.js'
Routage préfixe
import MyButton from ' @controls/MyButton ' ;
MyButton x-tap = ' clicked ' ;Vous devez d'abord configurer le préfixe, par exemple:
mask . Module . cfg ( 'prefixes.controls' , '/src/controls/{0}/{1}.mask' ) ; 0.57.0
Typa Annotations pour les arguments: (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
Portée de la fonction: importations et définir les arguments
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 '
} Les importations sync , car le chargement d'importation pour de meilleures performances est parallèle, mais les bundles doivent être chargés en synchronisation, car ils enregistrent alors toutes les ressources.
import sync from ' ./MyComponentsBundle ' ;
import FooCompo from ' ./Foo ' ;
// ... 0.55.1
0.55.0
Importations asynchrones.
import async Foo from ' ./Foo.mask ' ;
h4 > ' MyHeader '
await Foo ; L'en-tête h4 est rendu pendant le Foo peut encore être chargé.
define et let les arguments de soutien
define Foo (user) {
h4 > ' ~ user.name '
}
Foo ( me ) ; mask . render ( template , { me : { name : 'TestUser' } } ) ;© ️ MIT - Projet 2021 atma.js