Vue.js勉強メモ(1) - 簡易Todoリストの作成

公式ガイドの、コンポーネントの詳細の手前まで読み終えたので、この時点でTodoリストっぽいものを作ってみる。データベースを用意しないため、厳密にはTodoリストではない。 コンポーネントについてはまだ学んでいないため、これから書くコードにはまだ改善の余地があるだろう。 準備 index.htmlを用意する。 1 2 3 4 5 6 7 8 9 10 11 <!DOCTYPE html> <html lang="ja"> <head> <meta charet="utf-8"> <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> </head> <body> <h1>Todo List</h1> <script src="script.js"></script> </body> </html> 以下の部分でVue.jsを読み込んでいる。 1 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> script.jsを作成しておく。中身はまだ空。 実装する機能 初めにも述べたが、データベースは用意しない。以下の簡単な機能だけ実装する。 入力エリア Todoリスト表示エリア 各要素に削除ボタンをつける。 勉強を兼ねて、いくらか遠回りしながら作っていく。 配列の要素をli要素として表示 index.htmlに追記する。 1 2 3 4 5 <div id="app"> <ul> <li v-for="todo in todos">{{ todo }}</li> </ul> </div> Vue.jsが用意したテンプレート構文をHTMLに埋め込むことによって、データとDOMを結びつけることができる。v-という接頭辞がついた属性はディレクティブと呼ばれる。今回のv-forディレクティブは、その名の通りfor文を実現する。構文から分かると思うが、JSとかPythonで使われているfor-in文と同じ文法。 式の埋め込みは{{ 式 }}で行う。ガイドではMustache(口髭)構文と呼んでいる。良いネーミングだなと思ったけど、{{ }}の書式をそう呼ぶのはわりと一般的みたい? ...

2020-02-16 · (updated 2020-02-16) · 2 min · 306 words

JavaScript/Elm ビット演算のときにはまったこと

結論 JavaScriptにおいて、>>>以外のビット演算は32ビット符号付き整数値として扱われる。 → 例えば&|^~の計算前に、オペランドに型変換が起こる(ソース)。 JSにおいて数字はNumberという型しかないが、ビット演算のときだけ32ビット整数値に変換されるっぽい JavaScriptにおいて、x >>> 0を使うと符号なし整数になる。 負数を2で割り続けても、コンピュータにおける2進表現にはならない。 これはすごく当たり前だった コンピュータにおける2進数表現にしたいなら,論理シフトを使うこと。 ElmはJavaScriptに変換されるので、上の事実はすべてElmでも当てはまる。 各種ビット演算は、JSの演算をそのまま使っているっぽい(ソース) 検証コード $ elm init src/MyBitwise.elmを作成し、内容を以下のようにする。 1 2 3 4 5 6 7 8 9 10 11 12 13 module MyBitwise exposing (..) import Bitwise toBinaryString : Int -> String toBinaryString x = let bit = Bitwise.and x 1 rem = Bitwise.shiftRightZfBy 1 x in if rem > 0 then (toBinaryString rem) ++ (String.fromInt bit) else String.fromInt bit elm replを起動し、試す。まず必要なモジュールをimportする。 $ elm repl > import Bitwise > import MyBitwise exposing (..) 232-1 = 4294967295を2進表示すると、1が32個並んだ数になる。32ビット整数の2の補数表現では、-1と4294967295は同じ表現方法になる。 > toBinaryString 4294967295 "11111111111111111111111111111111" : String > toBinaryString -1 "11111111111111111111111111111111" : String Bitwise.andの計算結果は符号付き整数値とみなされるので、以下では4294967295ではなく-1と出力される。 ...

2019-12-31 · (updated 2019-12-31) · 3 min · 440 words

Elm/JavaScript ローカルサーバーで通信する際にハマったこと

今回たまたまクライアント側でElmを使ったけど、これはElmに限ったことではない。 結論 Client側での留意点 urlはlocalhost:[port]ではなくhttp://localhost:[port]と指定しなければならない。つまり、URLにはちゃんとスキーム名を指定する。 Server側での留意点 Access-Control-Allow-Originに関連するヘッダーをちゃんと設定する。 成功コード プログラムの内容 サーバーは{ "msg" : "Hello, World!" }という内容のJSONを送ってくるので、クライアントはその値を受け取って"Success: Hello, World!“を出力する。それだけ。 Client: Elm 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 module Main exposing (..) import Browser exposing (..) import Json.Decode exposing (..) import Http exposing (..) import Html exposing (..) import Html.Attributes exposing (..) main = Browser.element { init = init , update = update , view = view , subscriptions = subscriptions } type Model = Loading | Failed | Success String init : () -> (Model, Cmd Msg) init _ = ( Loading, getServer ) type Msg = GotData (Result Http.Error String) update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of GotData result -> case result of Ok str -> (Success str, Cmd.none) Err _ -> (Failed, Cmd.none) getServer : Cmd Msg getServer = Http.get { url = "http://localhost:3000" , expect = Http.expectJson GotData dataDecoder } dataDecoder : Decoder String dataDecoder = field "msg" string view : Model -> Html Msg view model = case model of Failed -> p [] [ text "Failed!" ] Loading -> p [] [ text "Loading..." ] Success str -> p [] [ text ("Success : " ++ str) ] subscriptions : Model -> Sub Msg subscriptions _ = Sub.none Server: JavaScript (Node.js) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 const http = require('http'); const server = http.createServer(); server.on('request', (req, res) => { res.writeHead(200, { 'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json' }); const body = { msg: 'Hello, World!' }; res.write(JSON.stringify(body)) res.end(); }); server.listen(3000); 失敗と解決までの流れ Http.getの引数 初めはサーバー側で次のようにしていた。 ...

2019-12-19 · (updated 2019-12-19) · 3 min · 602 words

D3.js 01信号の可視化

信号に関する授業を聴いていたらふと思い立ったのでやってみた。 コード index.html 個人的テンプレを書く。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>0-1 Signal</title> </head> <body> <h1>0-1 Signale</h1> <svg> </svg> <script src="https://d3js.org/d3.v5.min.js"></script> <script src="script.js"></script> </body> </html> script.js JavaScriptでflatMap使うのはこれが初めてかも。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 const format = (data, w) => { const pairs = d3.pairs(data); const deltas = pairs.flatMap(e => { let sig = e.toString() if (sig == '0,0') { return [[1,0]]; } else if (sig == '0,1') { return [[1,0],[0,-1]]; } else if (sig == '1,0') { return [[1,0],[0,1]]; } else if (sig == '1,1') { return [[1,0]]; } else { throw new Error('invalid element.'); } }); const points = deltas.reduce((acc, e) => { const back = acc[acc.length - 1].slice(); back[0] += w * e[0]; back[1] += w * e[1]; return acc.concat([back]) }, [[0,0]]); return points; }; const [svgWidth, svgHeight] = [800, 800]; const svg = d3.select('svg') .attr('width', svgWidth) .attr('height', svgHeight); const pad = 70; const render = (data) => { svg.selectAll('*').remove(); svg.append('path') .datum(data) .attr('transform', `translate(${pad}, ${pad})`) .attr('stroke', 'black') .attr('fill', 'none') .attr('d', d3.line() .x(d => d[0]) .y(d => d[1])); }; render(format([0,0,1,0,1,0,1,1,1,1,0,0], 50)); 実行結果 説明 format 01の情報を、path用の頂点データに変換する関数。 ...

2019-12-17 · (updated 2019-12-26) · 2 min · 231 words