UI生成用のJSフレームワークを見つける







どういうわけか、私は1つの小さなクライアントサーバーアプリケーションを実装しようとしたかったのです。 アイデアの実装は次のとおりです。クライアント側では何らかのJSフレームワークを使用してウィンドウを描画し、サーバー側ではGoなどで作成されたコンパイル済みアプリケーションを使用してクライアントからの呼び出しを処理します。







宣言型インターフェースを提供するフレームワークを取り上げ始めました。 私の見解では、入力時にフォームの内容の説明を可能限りシンプルに (たとえば、YAML、JSON、 BEMJSON 、XML、さらにはINF形式で) 受け取り 、出力で、動作するコントロールを使用してブラウザに美しいフォームを描画する必要があります。







専門的には、私はウェブ開発に関与していないため、この段階で長い間行き詰まるとは思っていませんでした。







また、記事を書くつもりはありませんでしたが、初心者にとっても、最新のWebテクノロジーの新鮮な外見はコミュニティにとって興味深いかもしれないと考えました。 再びフィードバックを得る機会...







HTMLおよびCSSテンプレート



私が見つけたものはすべて、思い通りに機能しませんでした。 レイアウトとスタイルについて何も知りたくありません。 また、 BootstrapSkeletonMDLなどのフレームワークを適用するときに行われるため、HTMLを埋めたくありません。







Bootstrapを使用したサンプルコード:







<div class="input-group mb-3"> <div class="input-group-prepend"> <div class="input-group-text"> <input type="checkbox" aria-label="Checkbox for following text input"> </div> </div> <input type="text" class="form-control" aria-label="Text input with checkbox"> </div> <button type="button" class="btn btn-primary btn-lg btn-block">Block level button</button>
      
      





入力に適用したいものはすべて次のようになります。







 { "main": { "prop":{}, "elements": [ { "type":"checkbox", "name":" -", "style":"classic", "checked": true }, { "type":"button", "name":"", "style":"outline", "onclick":"btnsave_onclick" } } }
      
      





さて、グループ内の要素を組み合わせて、要素をグループ内に配置する方法(垂直または水平)を指定できるようにします。 そこのデザインはどうなるでしょう、それは私にとって特に重要ではありません。 ある種の視覚的なウィンドウエディタでさえ見つけることを期待していましたが、見つかりませんでした。







技術の組み立て



それから私はいくつかの技術アセンブリを探しました-誰かが長い道のりを何度も舗装したに違いありません。







そして、私は私が必要とするものに似たものを見つけました: BEM技術のフルスタック上のゼロからサイト







BEMJSONの例:







 ({ block: 'page', title: 'Hello, World!', styles: [ { elem: 'css', url: 'index.min.css' } ], scripts: [ { elem: 'js', url: 'index.min.js' } ], content: [ 'Hello, World!' ] })
      
      





テキストの20番目の画面をスクロールし、スライダーがまだ上部にあるとき、この短いパスはなんとなく長いと思いました。 うまくいきません。







ところで、私はこのBEMについて読みました -私はその本質が好きで、それはよく説明されています。 さまざまなチートシートがあります。たとえば、私はこのチートシートが好きでした。 また、情報を探しましたが、誰もが技術を気に入っているわけではないことがわかりました(たとえば、 herehere )。 そして、 ここで 、私の意見では、論争の的となっている点の本質が述べられています。







興味深いのは、BEM以外の検索を長期間使用すると、これ以上の代替技術が見つからなかったことです。 ただし、それらは次のとおりです。OOCS (同じBEMのようなもの、より単純なもの)、 SMACSSAtomicCSSCSsinJSここにあります )。







Node.js



元のアイデアを捨てて、サーバー部分をスクリプト言語で実装できる、つまり単純にnodejsを使用できると考えました。 ファッショナブルでスタイリッシュ、若々しいだけでなく、すべてのレイヤーに1つの言語で書く機会でもあります。 再び多くの記事(クイックスタートについてこの記事が気に入った)。 私が正しく理解していれば、ほぼすべてのタスクについて、無数のNPMパッケージが作成されています。 このビジネスにはまだElectronのような深刻な問題があります。







Electronを使用したページコードのサンプル:







 <head> <meta charset="utf-8"> <link rel="stylesheet" href="assets/css/variables.css"> <link rel="import" href="sections/about.html"> </head> <body> <nav class="nav js-nav"> <header class="nav-header"> <h1 class="nav-title">Electron <strong>API Demos</strong></h1> </header> <div class="nav-item u-category-windows"> </div> <footer class="nav-footer"> <button type="button" id="button-about" data-modal="about" class="nav-footer-button">About</button> </footer> </nav> <main class="content js-content"></main> <script> require('./assets/normalize-shortcuts') </script> </body> </html>
      
      





Goを使用して、生産性の高いものを作成できる唯一のマイナスnodejs。

nodejsを使用したいとします。 NPMパッケージのカタログがあるため、自分に合ったものを選択できます。







formsというパッケージがあります 。 サンプルコードを次に示します。







 var forms = require('forms'); var fields = forms.fields; var validators = forms.validators; var reg_form = forms.create({ username: fields.string({ required: true }), password: fields.password({ required: validators.required('You definitely want a password') }), confirm: fields.password({ required: validators.required('don\'t you know your own password?'), validators: [validators.matchField('password')] }), email: fields.email() });
      
      





これはコマンドreg_form.toHTML();



によってフォームにアセンブルされreg_form.toHTML();



。 興味深いオプションですが、そうではありません。







ElementRiotTotalJSiViewもあります。 これは、Bootstrap、MDLなどからリストに追加できます。







要素を使用したページコードの例:







 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- import CSS --> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> </head> <body> <div id="app"> <el-button @click="visible = true">Button</el-button> <el-dialog :visible.sync="visible" title="Hello world"> <p>Try Element</p> </el-dialog> </div> </body> <!-- import Vue before Element --> <script src="https://unpkg.com/vue/dist/vue.js"></script> <!-- import JavaScript --> <script src="https://unpkg.com/element-ui/lib/index.js"></script> <script> new Vue({ el: '#app', data: function() { return { visible: false } } }) </script> </html>
      
      





Blueprintsjsもあります。 これはおそらく私が探していたものに最も似ています。 コントロールを互いに別々に構成することが可能です。







コードは次のようになります。







ブループリントを使用した多くのコード
 /* * Copyright 2018 Palantir Technologies, Inc. All rights reserved. * * Licensed under the terms of the LICENSE file distributed with this project. */ import * as React from "react"; import { FormGroup, H5, InputGroup, Intent, Switch } from "@blueprintjs/core"; import { Example, handleBooleanChange, handleStringChange, IExampleProps } from "@blueprintjs/docs-theme"; import { IntentSelect } from "./common/intentSelect"; export interface IFormGroupExampleState { disabled: boolean; helperText: boolean; inline: boolean; intent: Intent; label: boolean; requiredLabel: boolean; } export class FormGroupExample extends React.PureComponent<IExampleProps, IFormGroupExampleState> { public state: IFormGroupExampleState = { disabled: false, helperText: false, inline: false, intent: Intent.NONE, label: true, requiredLabel: true, }; private handleDisabledChange = handleBooleanChange(disabled => this.setState({ disabled })); private handleHelperTextChange = handleBooleanChange(helperText => this.setState({ helperText })); private handleInlineChange = handleBooleanChange(inline => this.setState({ inline })); private handleLabelChange = handleBooleanChange(label => this.setState({ label })); private handleRequiredLabelChange = handleBooleanChange(requiredLabel => this.setState({ requiredLabel })); private handleIntentChange = handleStringChange((intent: Intent) => this.setState({ intent })); public render() { const { disabled, helperText, inline, intent, label, requiredLabel } = this.state; const options = ( <> <H5>Props</H5> <Switch label="Disabled" checked={disabled} onChange={this.handleDisabledChange} /> <Switch label="Inline" checked={inline} onChange={this.handleInlineChange} /> <Switch label="Show helper text" checked={helperText} onChange= {this.handleHelperTextChange} /> <Switch label="Show label" checked={label} onChange={this.handleLabelChange} /> <Switch label="Show label info" checked={requiredLabel} onChange= {this.handleRequiredLabelChange} /> <IntentSelect intent={intent} onChange={this.handleIntentChange} /> </> ); return ( <Example options={options} {...this.props}> <FormGroup disabled={disabled} helperText={helperText && "Helper text with details..."} inline={inline} intent={intent} label={label && "Label"} labelFor="text-input" labelInfo={requiredLabel && "(required)"} > <InputGroup id="text-input" placeholder="Placeholder text" disabled={disabled} intent={intent} /> </FormGroup> <FormGroup disabled={disabled} helperText={helperText && "Helper text with details..."} inline={inline} intent={intent} label={label && "Label"} labelFor="text-input" labelInfo={requiredLabel && "(required)"} > <Switch id="text-input" label="Engage the hyperdrive" disabled={disabled} /> <Switch id="text-input" label="Initiate thrusters" disabled={disabled} /> </FormGroup> </Example> ); } }
      
      





結果は次のようになります。







たとえ最後の部分のみを考慮したとしても:すべて同じで、どういうわけかそれほど簡潔ではありません。







metadata.js



また、Webで面白いものを見つけました: metadatajs 。 クイックスタート- こちら 。 このライブラリには冗長な機能があり、記事では、私の意見では、最も重要なことはそうではありません-ライブラリ自体の説明です。 ここにあります







フォームを次のように説明します。







metadata.jsを使用したフォームの説明
 { "enm": {}, "cat": { "": { "form": { "selection": { "fields": [ "is_folder", "id", "", "_t_.name as presentation", "`cat_`.name as ``", "`cat_`.name as ``" ], "cols": [ {"id": "id", "width": "120", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "150", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "presentation", "width": "*", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "70", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "170", "type": "ro", "align": "left", "sort": "server", "caption": " "} ] } } }, "": { "form": { "selection": { "fields": [ "is_folder", "id", "_t_.name as presentation", "`enm_`.synonym as ``", "`cat_`.name as ``" ], "cols": [ {"id": "presentation", "width": "*", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "150", "type": "ro", "align": "left", "sort": "server", "caption": " "}, {"id": "", "width": "150", "type": "ro", "align": "left", "sort": "server", "caption": ""} ] } } } }, "doc": { "": { "form": { "selection": { "fields": [ "date", "number_doc", "", "", "posted", "", "" ], "cols": [ {"id": "date", "width": "120", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "number_doc", "width": "120", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "170", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "120", "type": "ron", "align": "right", "sort": "server", "caption": ""}, {"id": "", "width": "100", "type": "ro", "align": "left", "sort": "server", "caption": ""}, {"id": "", "width": "*", "type": "ro", "align": "left", "sort": "server", "caption": ""} ] }, "obj": { "head": { " ": ["number_doc", "date", "", "", "", ""], "": ["", "", ""], "": ["", "", "", "", "", "", "", {"id": "", "path": "o.", "synonym": " ", "type": "ro"} ] }, "tabular_sections": { "": { "fields": ["row","","","","","","","","","","","","",""], "headers": "№,,,.,,,% ,,% ,,,.,,", "widths": "40,*,*,70,50,70,70,70,70,70,70,70,70,80", "min_widths": "40,200,140,70,50,70,70,70,70,70,70,70,70,80", "aligns": "", "sortings": "na,na,na,na,na,na,na,na,na,na,na,na,na,na", "types": "cntr,ref,ref,calck,refc,calck,calck,ron,refc,ron,ron,dhxCalendar,ref,txt" } } } } } }, "ireg": {}, "areg": {}, "dp": {}, "rep": {}, "cch": {}, "cacc": {} }
      
      





これは、必要なものと非常に似ています。 ただし、疑問が生じます。ボタンセットはデフォルトで設定されているように見えますか? 変更できますか? 構文の説明はどこにありますか(「enm」、「cat」など)。

プロジェクトに多くの努力が注がれていることがわかりますが、ライブラリはまだ湿っています。







おわりに



推測しましょう。 フォームはサーバー上で事前に描画され、コンパイルされ、クライアント側に準備済みのhtml / css / js-codeに送信されます。 この場合、まったく異なるものを探す必要があります。 しかし、ユーザーに1つのブラウザーウィンドウで作業してもらい、このウィンドウにWebアプリケーションの子ウィンドウが表示されるようにする場合、クライアントでcss / jsコードをキャッシュするのは論理的ではありません。顧客リソースを犠牲にしてそれらを描画しますか?







同僚、宣言型インターフェイスフレームワークをどこで隠しますか? )







彼に違いない! なぜ彼が見つからないのですか?








All Articles