20210505のvue.jsに関する記事は25件です。

配列構文で2つのstyleを適用させる

【1】文章内の標準フォントサイズ 60px 【2】文字赤背景色青 この2つを配列で適応さえる。 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :style="[styleObject, baseStyles]">HELLO<h1> </div> new Vue({ el: '#app', data: { styleObject: { color: 'red', 'background-color': 'blue' }, baseStyles: { fontSize: '60px' } } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CSSとの連動(bindingで色を変化させる)

【1】 .red { color: red; } .bg-blue{ background-color: blue; } <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 class="red bg-blue">HELLO<h1> 【2】Viewでtrue or falseで表現 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 v-bind:class="{red: true 'bg-blue': false}">HELLO<h1> もしくは <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :class="{red: true 'bg-blue': false}">HELLO<h1> *cssは変わらず *bg-blueのハイフンを使ったケバブケースについてはシングルコーテーションで囲う 【3】Vueインスタンス内で表現 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :class="{red: isActive, 'bg-blue': !isActive}">HELLO<h1> !isActiveは否定=falseになる new Vue({ el: '#app', data: { isActive: true } }) (4)ボタンで逆にする <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :class="{red: isActive, 'bg-blue': !isActive}">HELLO<h1> <button @click="isActive=!isActive">切り替え</button> (5)computedを使用して書く <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :class="classObject">HELLO<h1> <button @click="isActive=!isActive">切り替え</button> new Vue({ el: '#app', data: { isActive: true }, computed: { classObject: function() { return { red: this.isActive, 'bg-blue': !this.isActive } } } }) computedからdata{ },にアクセスする際は、isActiveにthis.をつける。 (6)配列を使用して書く <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :class="[color, bg]">HELLO<h1> new Vue({ el: '#app', data: { color: 'red', bg: 'bg-blue' } }) (7)styleを使ってかく <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :style="{color: textColor, 'background-color': bgColor}">HELLO<h1> new Vue({ el: '#app', data: { textColor: 'red', bgColor: 'blue' } }) (8)Vueインスタンス内にstyleを書く <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <h1 :style="styleObject">HELLO<h1> new Vue({ el: '#app', data: { styleObject: { color: 'red', 'background-color': 'blue' } } })
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Nuxt.jsで新規作成をするとBabelで大量のWARNが出てくるときの解消法

新しくNuxt.jsのversion 2.14.6でプロジェクトを立ち上げようとし、yarn create nuxt-app <project-naem>し、 インストール完了後、yarn devで立ち上げたらコチラのWARNが大量に発生しました。 WARN Though the "loose" option was set to "false" in your @babel/preset-env config, it will not be used for @babel/plugin-proposal-private-methods since the "loose" mode option was set to "true" for @babel/plugin-proposal-class-properties.The "loose" option must be the same for @babel/plugin-proposal-class-properties, @babel/plugin-proposal-private-methods and @babel/plugin-proposal-private-property-in-object (when they are enabled): you can silence this warning by explicitly adding ["@babel/plugin-proposal-private-methods", { "loose": true }] to the "plugins" section of your Babel config. WARNの内容を読んで見る とりあえず翻訳してみる。 babel/preset-env 設定で "loose" オプションが "false" に設定されていますが、@babel/plugin-proposal-class-properties の "loose" モードオプションが "true" に設定されているため、@babel/plugin-proposal-private-methods では使用されません。 babel/plugin-proposal-class-properties、@babel/plugin-proposal-private-methods、および @babel/plugin-proposal-private-property-in-object (それらが有効な場合) では、"loose" オプションは同じでなければなりません。 をBabel設定の "plugins "セクションに追加してください。 Babelに何か関係がありそうです。 "loose" オプションが "false" に設定されているから"true"にしてくださいのような感じで書かれています。 nuxt.config.jsに記入する Babelの設定を変えるには公式サイトに書いてあります。 https://ja.nuxtjs.org/docs/2.x/configuration-glossary/configuration-build/#presets これを参考に対応してみます。 nuxt.config.js build: { babel: { presets({ isServer }, [preset, options]) { options.loose = true }, }, }, build内にbabelの設定をします。optionに先程のwarnの内容のlooseをtrueに設定します。 再度yarn devすると、warnが消えました。 eslintでエラー warnは消えたのですが、eslintを入れているとソース上にエラーが出てきます。 エラー内容を読んで見るとこのような内容が出てきます。 isServerやpresetを何も宣言してないので不要ですね。 var isServer: any 'isServer' が宣言されていますが、その値が読み取られることはありません。ts(6133) 'isServer' is defined but never used. Allowed unused args must match /^_/u.eslint@typescript-eslint/no-unused-vars) @babel/plugin-proposal-private-methodsの設定で対応する @babel/plugin-proposal-private-methodsのlooseオプションをtrueにするだけなのでこちらに書き換えてみました。 nuxt.config.js build: { babel: { plugins: [['@babel/plugin-proposal-private-methods', { loose: true }]], }, }, これでWARNもソース内のエラー両方消えました。 Nuxtの2.14.6のバージョンを新規でインストールしたときにbabelのloose optionがwarnになるようですね。 2.14.6以降で新規に作成するときは参考にしてみてください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

( )括弧いるいらない?

①はvue.jsの仕様としてメソッドの名前を指定するとなっている ②インラインメソッドハンドラ・・メソッド名を直接指定する代わりに、インライン JavaScript 式でメソッドを指定することもできます: ③二重中間の中ではcomputedプロパティは( )を付けない ④二重中間の中ではメッソドの呼び出しは( )をつける <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <button @click="countUp">+1</button> #① <button @click="countUp()">+1</button>#② <p>{{ counterComputed }}</p>#③ <p>{{ counterMethod() }}</p>#④ </div> <script> new Vue({ el: '#app', data: { counter: 0 }, computed: { counterComputed: function() { return this.counter *2; } }, methods: { countUp: function() { this.counter += 1; }, counterMethod: function() { return this.counter *2; } } }) </script> </body>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

watcherを使ってx秒後にカウンターをゼロにする

watchは非同期処理によく使う *ちなみにreturnは非同期処理では使えない。 *thisも非同期処理では使えない.vmを設定してvmを使って指定します。 *vm(ViewModelの略)をVueインスタンスの変数名としてよく使います。 setTimeoutは、 指定された処理を指定された時間後に1回実行します。 第一引数にはコード文字列か関数オブジェクトを指定します。第二引数には処理待ち時間もしくは実行間隔をmsecで指定します。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ lessThanThree }}</p> </div> <script> new Vue({ el: '#app', data: { counter: 0 }, computed: { lessThanThree: function() { console.log('Computed'); return this.counter > 3 ? '3以上' : '3以下' } }, watch: { counter: function() { var vm = this; setTimeout(function() { vm.counter = 0 }, 3000) } } }) </script> </body> 3秒経ったらカウンターはゼロに戻りました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

computedプロパティとメソッドの違い

computedは関連したイベントが発火しない限り発生しない。 メソッドは画面が何度も描画する度に計算している。 (1)カウンター「counter」と別のカウンター「otherCouner」を設置する。 (2)どちらもcomputedもメソッドもreturn this.counterとしてcounterのみに連動。 カウンターやアザーカウンターを両方別々にいくつか押してみると <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ otherCounter }}</p> <button @click="otherCounter += 1">別の+1</button> <p>{{ lessThanThreeComputed }}</p> <p>{{ lessThanThreeMethod() }}</p> </div> <script> new Vue({ el: '#app', data: { counter: 0, otherCounter: 0 }, computed: { lessThanThreeComputed: function() { console.log('Computed'); return this.counter > 3 ? '3以上' : '3以下' } }, methods: { lessThanThreeMethod: function() { console.log('Method'); return this.counter > 3 ? '3以上' : '3以下' } } }) </script> </body> 結果 +1を押した場合 別の+1を何度か押した場合 メソッドのみ挙動を確認 computedは関連したMODのイベントでした発火しない。 メソッドはこれとは違い二重中括弧の中にメソッドを書くと描画されるたびに実行される。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

computedプロパティ

<body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ counter > 3 ? '3以上' : '3以下'}}</p> </div> <script> new Vue({ el: '#app', data: { counter: 0 } }) </script> </body> 三項演算子・・・ifを用いない条件分岐の書き方 if文でブロックを分けたくない場合に、コンパクトに条件分岐を書くことができるとても便利な構文です。 条件式 ? 条件がtrueの場合の処理 : 条件がfalseの場合の処理 (重要) Vueインスタンス内のデータには初期値となるデータしかかけない。動的なデータは扱えません。 そこで computedプロパティ <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>{{ counter }}</p> <button @click="counter += 1">+1</button> <p>{{ lessThanThree }}</p> </div> <script> new Vue({ el: '#app', data: { counter: 0 }, computed: { lessThanThree: function() { return this.counter > 3 ? '3以上' : '3以下' } } }) </script> </body> 同じように表現できました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS CloudFront FunctionsでSPAのルーティング処理

緊急事態宣言で暇を持て余していた2021年のGWに、AWSからナイスな機能がリリースされました。 その名も「CloudFront Functions」。CloudFrontでクライアントからのアクセス時にJavaScriptで書かれた処理をかますことができる機能です。 今回は、このCloudFront Functionsを使って、SPA特有の「すべてのアクセスをindex.htmlに向ける」処理を書いてみましたのでご紹介します。 CloudFront Functionsとは? https://aws.amazon.com/jp/about-aws/whats-new/2021/05/cloudfront-functions/ https://aws.amazon.com/jp/blogs/aws/introducing-cloudfront-functions-run-your-code-at-the-edge-with-low-latency-at-any-scale/ 詳しくは以上のAWS公式サイトをご覧いただければと思いますが、要約すると「CloudFrontがリクエストをOriginに転送する前に、1ms以下の実行時間の比較的軽い処理を挟むことができる」という機能です。 同じような機能としてすでにLambda@Edgeが存在しますが、こちらはより軽量版といったところでしょうか。 実行時間が最大1msとかなり厳しく、できる処理はURL・ヘッダーの書き換えだったりとか、リダイレクトとかに限られますが、その代わり高速にレスポンスが返せます。 料金は、100万リクエスト当たり$0.10とのことです。Lambda@Edgeよりも安いですね。 index.htmlへのルーティングをCloudFront Functionsで実装してみる React/Vue/Angular等で作られたシングルページアプリケーション(SPA)は、ルーティングの処理をブラウザで実行されるJSで行うため、サーバー側でルーティングを行う必要がありません。すべての(静的ファイルへのリクエストを除く)リクエストは、index.htmlに向けられる必要があります。でないと、/hogeのようなサブページへのルーティングが404になってしまいます。 下準備 まず、/hogeというサブページを持つAngularアプリケーションを用意しました。 私がAngularの使い手というだけなので、これはVueでもReactでも何でもいいと思います。 用意したSPAアプリケーションを、CloudFront+S3の形でアップロードして公開します。 ここまでで、<ドメイン>/直下、つまりTOPページは正しく表示されます。 しかし、アドレスバーに直接<ドメイン>/hogeと入れて、サブページを表示しようとすると、Access Deniedのエラーが返ってきます。 これは、S3がhogeという名前のファイルを返そうとしているためです。そのようなファイル実体は存在しないので、S3は404を返し、こちらに書かれているようにCloudFrontは403を返します。 なので、/hogeのようなファイル実体が存在しないパスにルーティングしようとした際は、JSでルーティング処理を行わせるために、index.htmlを返す必要があるというわけです。 ということで、ここでCloudFront Functionsの出番です。 CloudFront Functionsの設定 CloudFrontの左側メニューの中に「Functions」が追加されていますので、クリックします。 「Create Function」をクリックします。 適切な名称を入力します。 手順としては4段階、ステージは2つに分かれています。 まず「Build」。コードを書いて保存すると、「Development」ステージに反映されます。この段階では本番反映ではありません。 var indexPage = "index.html" function handler(event) { console.log(event); var request = event.request; var currentUri = request.uri; var doReplace = request.method === "GET" && currentUri.indexOf(".") === -1; if(doReplace) { var indexPath = `/${indexPage}`; request.uri = indexPath; } return request; } 以上のコードを入力して「Save」してください。 やっていることは、リクエストメソッドがGETかつ、URIにドットが入っていない(=拡張子がない)場合、index.htmlを返すように変更するというものです。 console.log()を含めていますが、ここで取れたログはus-east1リージョンのCloudWatch Logsに保存されます。 何やら懐かしいスタイルのJSコードを書いていますが、今のところES5相当の文法にしか対応していないようです。なんでやねん。 次に「Test」フェーズで、保存されたコードをテストできます。 今回は「Viewer Request」のフェーズで処理を挟みますので、「Event Type」をそのように選択します。 HTTPメソッド、URI、クエリパラメータ、リクエストヘッダー、Cookie、クライアントIPなどを変更できるようです。 「Compute utilization」という値は、最大実行時間の1msを100とした時の、実際の実行時間の値だそうです。最大でも70~80ぐらいに抑えておいたほうがよさそう。 このように、InputのURIに/hogeを入力して、OutputのURIが/index.htmlになっていればOKです。 次に「Publish」をして、この段階で「Live」ステージにもコードがデプロイされます。 最後に「Associate」で、このFunctionを紐づけたいCloudFrontディストリビューションを設定します。 先ほども書いたように、「Viewer Request」のフェーズで処理を挟むので、「Event Type」は「Viewer Request」を選んでください。 ディストリビューションの選択時、自動補完が出てきますが、ディストリビューションIDしか出てこないので、事前に紐づけたいディストリビューションのIDをメモっておいたほうがいいです。 設定が完了すると、/hogeをアドレスバーに直入力しても、正常にサブページが表示されるようになります。 CloudFront Functionsで出来ないこと CloudFront Functionsは、Lambda@Edgeで出来ることをもっとそぎ落として軽量高速化した機能であるため、今のところ以下のようなことはできません。 コード内で別のAWSリソースへのアクセスはできない 最大実行時間が1msを超えるような重い処理はできない 「Origin Request」「Origin Response」イベントタイプの処理はできない このような処理を行いたい場合は、Lambda@Edgeを採用するとよいでしょう。 まとめ 従来、SPAのindex.htmlへのルーティング処理をCloudFrontで行う場合、「Custom Error Response」でオリジンが403を返した時に、ドメイン直下(index.html)を返すように設定するというような、若干ハッキーな手法が多く用いられてきました。その後、Lambda@Edgeが出てきて一応解消できるようにはなりましたが、デプロイまでが結構複雑なので二の足を踏んでいた方も多いと思います。今回のCloudFront Functionsの登場で、よりシンプルに同様の処理を実装できるようになりました。ありがとうAWSさん。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-model

1)Vueインスタンス内にあるデータを読み込んでいる。 2)フォーム内に打ち込んだ文字も受け取ってくれる *データ内のmessage内容は変更されない「こんにちは」のまま。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <input type="text" v-model="message"> </div> <script> new Vue({ el: '#app', data: { message: 'こんにちは' } }) </script> </body> さらにmessageを表示する行を追加してみてみると <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <input type="text" v-model="message"> <h1>{{ message }}</h1> </div> <script> new Vue({ el: '#app', data: { message: 'こんにちは' } }) </script> </body> インプットフォーマットに一込んだ先から次々とメッセージの中身が変わるこことになります。 *データ内のmessage内容は変更されない「こんにちは」のまま。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

V-onディレクティブを動的に表現

<body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button v-on:[event]=countUp>カウントアップ</button>> </div> <script> new Vue({ el: '#app', data: { number: 0, event: 'click' }, methods: { countUp: function() { this.number += 1; } } }) </script> </body> 省略記法1 <button @[event]=countUp>カウントアップ</button>> 省略記法2 <button @click=countUp>カウントアップ</button>> data: { number: 0, event: 'click' }, データ内のevent: 'click'は消してください。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

キー修飾子

インプットボックスを作ってそこに文字を打ち込んだ(keyupにしているのでkeyが打ち終わってupしたらイベント)発動するようになっています。 今回はアラートを表示します。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <input type="text" v-on:keyup="myAlert"> </div> <script> new Vue({ el: '#app', methods: { myAlert() { alert('アラート'); } } }) </script> </body> 入力ごとにアラートが出ます。 次にエンターを押した時だけにする「キー修飾子」を設定します。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <input type="text" v-on:keyup.enter="myAlert"> </div> <script> new Vue({ el: '#app', methods: { myAlert() { alert('アラート'); } } }) </script> </body> 次にスペースをキー修飾子に設定 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <input type="text" v-on:keyup.space="myAlert"> </div> <script> new Vue({ el: '#app', methods: { myAlert() { alert('アラート'); } } }) </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【入門】Vue.jsを試してみた

Vue.jsとは JavaScriptのフレームワークの1つで、効率よくフロントエンドの開発が行える。 学習コストが低い。 CDNでjsファイルを読み込むだけで使用することができる。 シンプルにコードを書くことができる。 DOM操作を自動に行う HTMLの要素とJSの値やイベントとの紐付けを自動で行ってくれる。 jQueryよりも容易にコーディングできる。 Hello World! まず、Vue.jsで「Hello World!」を表示してみましょう。 CDNでVueを読み込む <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"> Vueインスタンスの生成 new Vue({}) el: HTML側のid属性との対応づけをする。 data: 表示するデータなどを定義する。 index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Vue.js入門</title> </head> <body> <div id="app"> {{ message }} </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { message: "Hello World!" } }); </script> </body> </html> ディレクティブ ディレクティブとは、接頭辞v-が付いたVue.jsに用意された特別な属性のことである。 もっと詳しく言うと、DOM要素に対して何か実行するものをライブラリに伝達する。 Vue.jsではこのディレクティブで始まりディレクティブで終わるとも言うくらい重要な概念となる。 ※以下からソースコードはbody部のみを記載する。 v-bind HTML側のある要素の属性を動的に設定することができる。 index.html <body> <div id="app"> <p v-bind:class="error_class">エラーが発生しました。</p> <!- 省略記法 --> <p :class="error_class">エラーが発生しました。</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { error_class: "error" } }); </script> </body> v-on イベントリスナーを定義することで、Vueインスタンスのメソッドを呼び出すことができる。 index.html <body> <div id="app"> <p>{{ now }}</p> <button v-on:click="time">現在時刻を表示</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { now: "00:00:00" }, methods: { time: function() { var date = new Date(); this.now = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); } } }); </script> </body> v-if 条件分岐によって、要素の有無の切り替えができる。 isErrorがtrueならば、エラーが発生しました。が画面に表示される。 isErrorがfalseならば、エラーが発生しました。が画面に表示されない。 index.html <body> <div id="app"> <p v-if="isError">エラーが発生しました。</p> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var error = new Vue({ el: "#app", data: { isError: true } }); </script> </body> v-once Vue.jsによるレンダリング(画面描画)を一度のみ行うようにする。 Vueインスタンスの変数にアクセスするときはthis.変数名と記述する。 index.html <body> <div id="app"> <p v-once>{{ count }}回クリックされました</p> <button v-on:click="counter">カウントボタン</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue ({ el: '#app', data: { count: 0 }, methods: { counter: function(){ this.count++ } } }) </script> </body> v-for 配列であるデータの各要素を制御することができる。 拡張for文のような記法をv-forに記述する。 v-forを使用する場合は、v-bindのkeyプロパティの指定が必須である。 keyを指定しない場合は配列のindexがkey値に使用されるが、key として使用すべきではない。 → 配列内の要素の追加・削除や順序の変更が行われるとき、index値も変化してしまう。 index.html <body> <div id="app"> <button v-on:click="shuffle">シャッフル</button> <ul> <li v-for="prefecture in prefectures" :key="prefecture.id"> {{ prefecture.name }} </li> </ul> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", data: { prefectures: [ { id:1, name: "福岡県" }, { id:2, name: "佐賀県" }, { id:3, name: "長崎県" }, { id:4, name: "大分県" }, { id:5, name: "熊本県" }, { id:6, name: "宮崎県" }, { id:7, name: "鹿児島県" } ] } }); </script> </body> v-model 入力情報とデータの双方向データバインディングを簡単に行うことができる。 もっと詳しく言うと、テキストボックスの値(value属性値)が変更されると、dataで持っているtextの値に自動的に反映される仕組みがある。 v-modelは属性の初期値を無視するという特徴があるため、dataに初期値を持たせるかカスタムディレクティブで独自に実装する必要がある。 index.html <body> <div id="app"> <p>{{ text }}</p> <input v-model="text"> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue ({ el: '#app', data: { text: '' } }) </script> </body> 算出プロパティ 算出プロパティとは、関数で算出したデータを返すことができるプロパティのこと。 conputedをvueインスタンスに記述する。 index.html <body> <div id="app"> {{ fullName }} </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { firstName: 'Nobi', lastName: 'Nobita' }, computed: { fullName: function() { return this.firstName + ' ' + this.lastName } } }) </script> </body> 上記の例はmethodsでも同様なことができる。 index.html <body> <div id="app"> {{ getFullName() }} </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: '#app', data: { firstName: 'Nobi', lastName: 'Nobita' }, methods: { getFullName: function() { return this.firstName + ' ' + this.lastName } } }) </script> </body> conputed VS methods conputed methods 記法(呼び出し) () 不要 () 必要 キャッシュ される されない conputed 引数を伴う処理ができない。 キャッシュ機能あり(=指定されているデータに変化があれば、再実行される) methods 引数を使った処理が可能である。 キャッシュ機能なし(=毎度毎度再実行される) index.html <body> <div id="app"> // conputed <ol> <li>{{ randomNum }}</li> <li>{{ randomNum }}</li> <li>{{ randomNum }}</li> </ol> // methods <ol> <li> {{ getRandomNum() }}</li> <li> {{ getRandomNum() }}</li> <li> {{ getRandomNum() }}</li> </ol> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <script> var app = new Vue({ el: "#app", computed: { randomNum: function () { console.log("computed"); return Math.random(); } }, methods: { getRandomNum: function () { console.log("methods"); return Math.random(); } } }); </script> </body> computedでは全て同じ値になるが、methodsは全て異なる値となる。 // computed 0.5562891327999486 0.5562891327999486 0.5562891327999486 // methods 0.10127439472454514 0.530424483259178 0.4696634887357811 computedではコンソールログには1度しかログが出ない。(1回しか呼ばれていない) computedはリアクティブデータ(dataオプションに設定されているデータ)が更新されない限り、実行されない!! 参考 https://jp.vuejs.org/ https://qiita.com/okerra/items/cda378436ed060e83a8c
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

イベント修飾子stop

v-onディレクティブで設定したイベントを止めることができます。 stop修飾子 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-on:mousemove="mousePosition(10, $event)">マウスを乗せてください <span v-on:mousemove.stop>マウスを乗せてみてください</span></p> <p>X:{{x}}、Y:{{y}}</p> </div> <script> new Vue({ el: '#app', data: { number: 0, x:0, y:0 }, methods: { mousePosition: function(divideNumber, event) { this.x = event.clientX / divideNumber; this.y = event.clientY / divideNumber; } } }) </script> </body> stopをつけるだけです。 <span v-on:mousemove.stop> prevent修飾子 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a v-on:click.prevent="url" href="https://google.com">Google</a> </div> <script> new Vue({ el: '#app' }) </script> </body> <a v-on:click.prevent="url" href="https://google.com">Google</a> .stop.preventと続けて書くこともできます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

イベント修飾子.stop/.prevent

v-onディレクティブで設定したイベントを止めることができます。 stop修飾子 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-on:mousemove="mousePosition(10, $event)">マウスを乗せてください <span v-on:mousemove.stop>マウスを乗せてみてください</span></p> <p>X:{{x}}、Y:{{y}}</p> </div> <script> new Vue({ el: '#app', data: { number: 0, x:0, y:0 }, methods: { mousePosition: function(divideNumber, event) { this.x = event.clientX / divideNumber; this.y = event.clientY / divideNumber; } } }) </script> </body> stopをつけるだけです。 <span v-on:mousemove.stop> prevent修飾子 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a v-on:click.prevent="url" href="https://google.com">Google</a> </div> <script> new Vue({ el: '#app' }) </script> </body> <a v-on:click.prevent="url" href="https://google.com">Google</a> .stop.preventと続けて書くこともできます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

DOMイベントごと変数で渡す

特別な $event変数を使うことでメソッドにDOMイベントを渡すことができます。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="example"> <p>{{ message }}</p> <button @click="say('こんちわ', $event)">こんにちは</button> </div> <script> let app = new Vue({ el: '#example', data: { message: '挨拶' }, methods: { say:function(message, event){ console.log(event) this.message = message } } }) </script> </body> ボタンを押すと 上を使って前の回のクリックカウントを2の倍数で表示させます。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button v-on:click="countUp(2)">カウントアップ</button> </div> <script> new Vue({ el: '#app', data: { number: 0 }, methods: { countUp: function(times) { this.number += 1 *times } } }) </script> </body> 上を使って前の回のXY座標のコードを10で割って表示させます。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-on:mousemove="mousePosition(10, $event)">マウスを乗せてください</p> <p>X:{{x}}、Y:{{y}}</p> </div> <script> new Vue({ el: '#app', data: { number: 0, x:0, y:0 }, methods: { mousePosition: function(divideNumber, event) { this.x = event.clientX / divideNumber; this.y = event.clientY / divideNumber; } } }) </script> </body> 座標が10で割った値となりました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-on:mousemuveで検証してみる

<body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-on:mousemove="mousePosition">マウスを乗せてください</p> <p>X:{{x}}、Y:{{y}}</p> </div> <script> new Vue({ el: '#app', data: { number: 0, x:0, y:0 }, methods: { mousePosition: function(event){ console.log(event); } } }) </script> </body> option+command+jで検証画面を開きます。 MouseEvent {isTrusted: true, screenX: 962, screenY: 215, clientX: 121, clientY: 35, …} altKey: false bubbles: true button: 0 buttons: 0 cancelBubble: false cancelable: true clientX: 121 clientY: 35 composed: true ctrlKey: false currentTarget: null defaultPrevented: false detail: 0 eventPhase: 0 fromElement: null isTrusted: true layerX: 121 layerY: 35 metaKey: false movementX: -3 movementY: 5 offsetX: 114 offsetY: 20 pageX: 121 pageY: 35 path: (6) [p, div#app, body, html, document, Window] relatedTarget: null returnValue: true screenX: 962 screenY: 215 shiftKey: false sourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false} srcElement: p target: p timeStamp: 158322.96499999939 toElement: p type: "mousemove" view: Window {window: Window, self: Window, document: document, name: "", location: Location, …} which: 0 x: 121 y: 35 __proto__: MouseEvent *console.logで取得しています。 今回注目すべきものは clientX: 121 clientY: 35 になります。 ですのでこうコードを変更してください。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-on:mousemove="mousePosition">マウスを乗せてください</p> <p>X:{{x}}、Y:{{y}}</p> </div> <script> new Vue({ el: '#app', data: { number: 0, x:0, y:0 }, methods: { mousePosition: function(event) { this.x = event.clientX; this.y = event.clientY; } } }) </script> </body>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

便利ページ:WebSocketをサクッと触れるページを作ってみた

便利ページ:Javascriptでちょっとした便利な機能を作ってみた のシリーズです。 今回は、WebSocketをサクッと呼び出せるページを作ります。 最近のほとんどのブラウザには、WebSocket APIが実装されているため、それを使います。 もろもろは、GitHubに上げてあります。 Webページはこちらからも見ることができます。ユーティリティタブでWebSocketを選択してください。 また、今回からついで、ベースとしていたフレームワークをBootstrap 3.4.1からBootstrap 5に変更し、便利ページ内の各ページをVueのコンポーネントで構成するようにしました。 こうすることで、ページもメンテナンスしやすく、追加しやすくなりました。 もし、Bootstrap3.4.1との比較を見たい場合は以下を参照してください。  Bootstrap 3からBootstrap 5に移行してみた 画面はこんな感じです。 PWAにもしているので、アプリとして登録してあげてください。 Chromeを立ち上げなくても、いつでも便利ページを呼び出せますので。WindowsでもAndroidでもOKです。 ソースコード といっても、大したことはやっていないので、ソースコード(Vueコンポーネント)を示しておきます。 js/comp/comp_websocket.js const log_separator = "\n----------\n"; export default { mixins: [mixins_bootstrap], template: ` <div> <h2 class="modal-header">WebSocket</h2> <label class="title">url</label> <input type="text" class="form-control" v-model="ws_url" placeholder="wss://192.168.1.1:443/ws"> <div class="row"> <label class="col-auto title">protocols</label> <span class="col-auto"> <input type="text" class="form-control" v-model="ws_protocols"> </span> </div> <button class="btn btn-secondary" v-on:click="ws_open" v-if="!ws_socket">Open</button> <button class="btn btn-secondary" v-on:click="ws_close" v-else>Close</button> <br> status: {{ws_status_message}} <br><br> <div class="row"> <label class="col-auto title">message</label> <span class="col-auto"> <select class="form-select" v-model="ws_send_type"> <option value="text">text</option> <option value="binary">binary</option> </select> </span> </div> <input type="text" class="form-control" v-model="ws_send_message"> <button class="btn btn-secondary" v-on:click="ws_send" v-bind:disabled="!ws_socket">送信</button> <br><br> <textarea class="form-control col" id="ws_textarea" rows="10">{{ws_console_message}}</textarea> <button class="btn btn-secondary" v-on:click="console_clear">クリア</button> </div>`, data: function () { return { ws_socket: null, ws_url: "", ws_protocols: "", ws_console_message: "", ws_send_type: "text", ws_send_message: "", ws_status_message: "closed", } }, methods: { /* WebSocket */ ws_open: function(){ this.ws_close(); try{ this.ws_socket = new WebSocket(this.ws_url); this.ws_socket.binaryType = "arraybuffer"; this.ws_socket.onopen = (event) => { // console.log("websocket opened", event); this.console_log(this.make_console_state_message(event)); var date_string = new Date().toLocaleString('ja-JP', { "hour12": false, "year": "numeric", "month": "2-digit", "day": "2-digit", "hour": "2-digit", "minute": "2-digit", "second": "2-digit" }); this.ws_status_message = "opened from " + date_string; }; this.ws_socket.onclose = (event) =>{ // console.log("websocket closed", event); this.console_log(this.make_console_close_message(event)); this.ws_socket = null; this.ws_status_message = "closed"; }; this.ws_socket.onerror = (event) =>{ // console.log("websocket error", event); this.console_log(this.make_console_state_message(event)); }; this.ws_socket.onmessage = (event) => { // console.log("websocket message", event); if (typeof (event.data) == "string" || event.data instanceof String ){ this.console_log(this.make_console_input_message(event)); }else{ this.console_log(this.make_console_input_message(event)); } }; }catch(error){ alert(error); } }, ws_close: function(){ if (this.ws_socket) this.ws_socket.close(); }, ws_send: function(){ if( this.ws_send_type == "text" ){ this.ws_socket.send(this.ws_send_message); this.console_log(this.make_console_output_message("text", this.ws_send_message)); }else{ var data = hexStr2byteAry(this.ws_send_message); var array = new Uint8Array(data); this.ws_socket.send(array); this.console_log(this.make_console_output_message("binary", array)); } }, console_clear: function () { this.ws_console_message = ""; }, make_console_output_message: function (type, data) { var date_string = new Date().toLocaleString('ja-JP', { "hour12": false, "year": "numeric", "month": "2-digit", "day": "2-digit", "hour": "2-digit", "minute": "2-digit", "second": "2-digit" }); var message; if (typeof (data) == "string" || data instanceof String) { message = data; } else { // message = new Uint8Array(data).toString(); message = byteAry2hexStr(data); } return "[SEND] message " + type + " " + date_string + "\n" + message; }, make_console_state_message: function (event) { var date_string = new Date().toLocaleString('ja-JP', { "hour12": false, "year": "numeric", "month": "2-digit", "day": "2-digit", "hour": "2-digit", "minute": "2-digit", "second": "2-digit" }); return "[STATE] " + event.type + " " + date_string; }, make_console_close_message: function (event) { var date_string = new Date().toLocaleString('ja-JP', { "hour12": false, "year": "numeric", "month": "2-digit", "day": "2-digit", "hour": "2-digit", "minute": "2-digit", "second": "2-digit" }); return "[STATE] " + event.type + " code=" + event.code + " " + date_string; }, make_console_input_message: function(event){ var date_string = new Date().toLocaleString('ja-JP', { "hour12": false, "year": "numeric", "month": "2-digit", "day": "2-digit", "hour": "2-digit", "minute": "2-digit", "second": "2-digit" }); var message; var type; if (typeof (event.data) == "string" || event.data instanceof String) { message = event.data; type = "text"; } else { // message = new Uint8Array(event.data).toString(); message = byteAry2hexStr(event.data); type = "binary"; } return "[RECV] " + event.type + " " + type + " " + date_string + "\n" + message; }, console_log: function(message){ this.ws_console_message = message + log_separator + this.ws_console_message; } }, mounted: function(){ var elem_in = document.querySelector("#ws_textarea"); elem_in.style.height = 10; } }; function hexStr2byteAry(hexs, sep = '') { hexs = hexs.trim(hexs); if (sep == '') { var array = []; for (var i = 0; i < hexs.length / 2; i++) array[i] = parseInt(hexs.substr(i * 2, 2), 16); return array; } else { return hexs.split(sep).map((h) => { return parseInt(h, 16); }); } } function byteAry2hexStr(bytes, sep = '', pref = '') { if (bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes); if (bytes instanceof Uint8Array) bytes = Array.from(bytes); return bytes.map((b) => { const s = b.toString(16); return pref + (b < 0x10 ? ('0' + s) : s); }).join(sep); } 要は、以下でWebSocketサーバに接続して、 this.ws_socket = new WebSocket(this.ws_url); 以下で、サーバに送信して、 this.ws_socket.send(this.ws_send_message); 以下で、サーバから受信する。 this.ws_socket.onmessage = (event) => { それだけです。 何かわかんなくなったり、パラメータで微調整したい場合は、以下を参考にしてください。 接続・切断・送信・受信の動きは、テキストエリアに逐一出力していますので、時系列で終えるようにしています。 WebSocket API (WebSockets)  https://developer.mozilla.org/ja/docs/Web/API/WebSockets_API 終わりに HTTPSで立ち上げたWebサーバのJavascriptからHTTPのWebSocketサーバに接続するには、WebSocketサーバをHTTPS接続にする必要があります。 以下を参考に、Web Proxyサーバを立ち上げてください。  HTTPで立ち上げたWebSocketサーバに、HTTPSで接続するためのWeb Proxyの立ち上げ あと、こちらもご参考まで。  MMDダンスをM5Core2のディスプレイに表示する 以上
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-onディレクティブ(2)

Viewインスタンス 全てのVueアプリケーションは、Vue 関数で新しい Vue インスタンスを作成することによって起動されます。 Vueインスタンスは、データ監視、イベント通信や DOM 操作をするいくつかのインスタンスメソッドを持っています。 var vm = new Vue({ // オプション }) 関数とは 同じ処理を定義し何度も使い回しができる形にしたもの。 <script> function 関数名(){ 処理 } </script> 無名関数とは 関数名なしで関数を定義できるもの。 <script> function(){ 処理 } </script> v-on:clickをvueインスタンス内で定義してみます <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button v-on:click="countUp">カウントアップ</button> </div> <script> new Vue({ el: '#app', data: { number: 0 }, methods: { countUp: function(){ this.number += 1 } } }) </script> </body> 【参考】関数呼び出しパターンのthis 呼び出し元 number: 0 *data: { }内 呼び出し先 this.number += 1 *methods{無名関数function( ){ }内} @hiroshimaeasyryo様 https://qiita.com/hiroshimaeasyryo/items/a270b00c420ed96f02f0 @Sthudent_Camilo https://qiita.com/Sthudent_Camilo/items/29467821eac0a11cfb80 @takkyun https://qiita.com/takkyun/items/c6e2f2cf25327299cf03 JavaScript Primer https://jsprimer.net/basic/function-this/
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue Typerで遊んでみた(タイピングエフェクト)

Vue Typerとは タイピングアニメーションを簡単に実装できるVue.jsのライブラリです。 おしゃれーな感じになります。 それではやってみましょう。 Vue Typerのインストール 今回の記事はCode Penを利用するのでCDNで読み込みます。 npmでインストール npm % npm install --save vue-typer yarnでインストール yarn % yarn add vue-typer CDNで読み込み CDN <script src="https://unpkg.com/vue-typer/dist/vue-typer.min.js"></script> Vue Typerコンポーネントを使えるようにする ローカルに登録する場合 特定のコンポーネントでしか使わないよという場合はローカルに登録します。 Vue Typerを使いたいファイルに記述します。 ローカル import { VueTyper } from 'vue-typer' export default { components: { VueTyper }, ... } グローバルに登録する場合 あまりないかもしれませんがグローバルに登録する場合は エントリーポイントに記述します。 グローバル import VueTyperPlugin from 'vue-typer' Vue.use(VueTyperPlugin) CDNで読み込んだ場合 グローバルに登録します。 CDN var VueTyperPlugin = window.VueTyper.default Vue.use(VueTyperPlugin) Vue Typer使い方 vue-typerタグを設置します。 <vue-typer text="表示させたいテキスト"></vue-typer> 配列も使えます。その場合は:textとします。 html <vue-typer :text="['テキスト1', 'テキスト2', 'テキスト3']"></vue-typer> dataプロパティから情報を取り出すことももちろんできます。 html <div id="app"> <p><input type="text" v-model="text"></p> <vue-typer :text="text"></vue-typer> </div> javascript const VueTyperPlugin = window.VueTyper.default Vue.use(VueTyperPlugin) new Vue({ el: '#app', data: { text: 'Hello World!' } }); textプロパティは必須です。 See the Pen Vue Typer1 by morioka (@rm5912) on CodePen. Vue Typerのプロパティ Vue Typerはさまざまなエフェクトを使うことができます。 入力のプロパティ プロパティ名      型        説明                    text String,Array 文字列もしくは配列で値を設定(必須)    repeat Number リピート回数を設定。0の場合は1回。デフォルトはinfinity(リピート) shuffle Boolean textプロパティ、配列に設定した値をランダムで出色。デフォルトはfalse initalAction String 開始時に空で始まるか、入力された状態で始まるかを設定。typingまたはerasingで設定。デフォルトはtyping preTypeDelay Number 最初の文字を入力する前に待機するミリ秒。 デフォルトは70 typeDelay Number 文字を入力してから次の文字が入力されるまで待機するミリ秒。デフォルトは70 caretAnimation String カーソルのアニメーションを指定する。デフォルトは blink caretAnimation="solid" 名前の通り。特にアニメーションなし      caretAnimation="blink" 普通のカーソルの感じ  caretAnimation="smooth" blinkよりも少し早くなり滑らかな印象 caretAnimation="phase" smoothよりも早くなりチカチカした印象 caretAnimation="expand" 伸びたり縮んだりする 消去のプロパティ プロパティ名     型         説明                      preEraseDelay Number 文字列が完全に入力された後、最初の消去アクション(バックスペース、ハイライトなど)が実行されるまで待機するミリ秒。デフォルトは2000 eraseDelay Number 文字列が完全に入力された後、最初の消去アクション(バックスペース、ハイライトなど)が実行されるまで待機するミリ秒。デフォルトは250 eraseStyle String 文字を消去する際のアクション eraseStyle="backspace" バックスペースで1文字ずつ消去する eraseStyle="select-back" 1文字ずつ強調表示して全ての文字が強調表示されると全てを消去 eraseStyle="select-all" 全ての文字を強調表示してすぐに全ての文字を消去 eraseStyle="clear" すぐに全ての文字を消去             eraseOnComplete Boolean 全ての文字が入力を完了した後、最後に入力された文字は消去されず、表示されたままに。デフォルトはfalse CSSで遊ぶ Vue typerはクラスが用意されていてCSSで遊ぶこともできます。 CSS SCSS */ /* SCSS .vue-typer { /* vue-typerコンテナのスタイル 例: font-family, font-size .custom.char { /* 各文字用のスタイル 例: color, background-color &.typed { タイプされた文字に固有のスタイル キャレットの左にある文字 } &.selected { 選択された文字に固有のスタイル VueTyperの'eraseStyle'が選択ベースのスタイルに設定されている間のキャレットの右側の文字 'eraseStyle'が選択ベースのスタイルに設定されている場合 } &.erased {. 消した文字に固有のスタイル VueTyperの'eraseStyle'が選択ベースのスタイルに設定されている間は、キャレットの右にある文字を消去する。 'eraseStyle'が非選択ベースのスタイルに設定されている場合 } } .custom.caret { キャレットのスタイル 例:背景色、アニメーション、表示 } &.pre-type{ タイプ前のアイドル状態のキャレットのスタイル 文字列が入力される前、'preTypeDelay'の間 } &.pre-erase { キャレットが消去される前にアイドル状態にあるときのスタイル すなわち、'preEraseDelay'の間、文字列が消去される前の状態} } &.idle { キャレットがアイドル状態で、VueTyperがまだ入力を完了していない場合のスタイル すなわち、'pre-type'または'pre-erase'が設定されていて、'complete'が設定されていない場合 } &.typing { VueTyperがタイピングしている間のキャレットのスタイル } &.selecting { { /* VueTyperが選択している間のキャレットのスタイル /* VueTyperが選択しているときのキャレットのスタイル すなわち、キャレットが後方に移動し、'eraseStyle'が選択ベースのスタイルに設定されている場合 } &.erasing { /* VueTyperが消去している間のキャレットのスタイル キャレットが後方に移動し、'eraseStyle'が非選択ベースのスタイルに設定されている場合 } &.complete {. VueTyperが全ての入力/消去を終了した時のアイドル状態のキャレットのスタイル } } } ざっと翻訳しただけなのでみづらいところはご了承ください。 文字を変えるだけでとてもおしゃれに。。。 See the Pen Vue Typer2 by morioka (@rm5912) on CodePen. 終わりに Webページにアクセントとして入れると動きが出るのでいいなと思いました。 ぜひ皆さんも遊んでみてください。 参考サイト VueTyper Demo カバの樹 タイピングのようなテキストアニメーションを「VueTyper」で実装する Qiita ポートフォリオで使おうと思ったVueTyperについて UPDATE 【Vue.js】タイピングエフェクトを実装する「VueTyper」の使い方 VueTyper GitHub
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

anyenv + nodenv で Mac に Vue.js の開発環境を構築する

自分用のメモを兼ねて, 環境構築シリーズです. 今回は Vue.js, 特に Vue CLI の開発環境を構築していきます. Homebrew は導入済みとします. 例によって M1 チップ/Big Sur では挙動が異なるかもしれません. 環境 macOS Catalina 10.15.7 Homebrew 3.1.5 この記事で導入するもの anyenv ○○env 系のパッケージをまとめて管理してくれるパッケージです. 今回のように nodenv だけであれば特に必要ありませんが, 他に pyenv (Python) や rbenv (Ruby) など env 系パッケージが増えてきたときにそれらを一元管理するため, 今回は anyenv を経由することにします. nodenv Node.js のバージョンを管理するのに使います. nodebrew も定番ですが, Node のバージョンを切り替えるのに毎回コマンドが必要だったり, また anyenv で管理できなかったりという点を考慮して今回は nodenv を用います. 実用上は nodebrew でも問題はありません. また ndenv というものもありますが, そちらは非推奨になったようです. Node.js 本来ブラウザ上で動作する言語である JavaScript をサーバー (今回は普通の PC) 上で動作するようにしたものです. Vue.js に限らず, JavaScript のフレームワークを使うときは PC に Node.js をインストールして, 様々な Node 製のツールを活用して開発を進めることが多いです. npm Node.js 用のモジュール管理ツールです. nodenv で Node をインストールしたときに自動的に導入されます. Vue CLI JavaScript フレームワークである Vue.js を用いて SPA (Single Page Application) を開発するために, ビルド設定などが含まれたツールです. Vue.js は通常の JavaScript のように HTML からプラグイン的に読み込んで使うこともできますが, 実際には Node ベースの Vue CLI 環境で開発を行い, 最終的にビルドされた静的ファイルをデプロイすることが多いです. インストール anyenv まずは 公式の手順 に従って anyenv をインストールします. Homebrew からインストールできます. $ brew install anyenv $ anyenv --version anyenv 1.1.2 以下のコマンドを叩くと eval "$(anyenv init -)" を使っているシェルの設定ファイルに書くよう指示が出るので, 従います (以下は zsh の場合です). $ anyenv init # Load anyenv automatically by adding # the following to ~/.zshrc: eval "$(anyenv init -)" $ echo 'eval "$(anyenv init -)"' >> .zshrc インストール用のディレクトリを作成します. $ anyenv install --init [y/N] で確認されるので, y を入力して進んでください. Completed! と出れば大丈夫です. nodenv anyenv を使って nodenv をインストールします. 無事にインストールできたら設定ファイルを読み込み直すよう指示が出るので, 従います. $ anyenv install nodenv ... (省略) Install nodenv succeeded! Please reload your profile (exec $SHELL -l) or open a new session. $ exec $SHELL -l Node.js nodenv でインストールできる Node.js の一覧は以下で確認できます. $ nodenv install --list 今回はせっかくなので最新の Node 16 をインストールしてみましょう (執筆時点での LTS は 14 系 です. バージョン 16 系は秋から LTS になるようです). $ nodenv install 16.0.0 インストールした Node のバージョンは以下で確認できます. $ nodenv versions 16.0.0 標準で使うバージョンを切り替えるには nodenv global で指定します. versions で表示される一覧に * が付いていれば大丈夫です. $ nodenv global 16.0.0 $ nodenv versions * 16.0.0 (set by /Users/ユーザー名/.anyenv/envs/nodenv/version) ここまでで npm も自動的に導入されています. $ npm --version 7.10.0 なお, 特定のディレクトリでのみ Node のバージョンを切り替えたい場合は nodenv local コマンドを使います. 一度設定すると .node-version というファイルが生成され, 以降はディレクトリに移動するだけで自動的にバージョンが切り替わります. $ mkdir node-test $ cd node-test $ nodenv local 16.0.0 $ nodenv versions * 16.0.0 (set by /Users/ユーザー名/node-test/.node-version) set by 以下の表示が切り替わったのがわかります. Vue CLI いよいよ Vue CLI をインストールします. 今回はグローバルに入れることにします. $ npm install -g @vue/cli オプション -g はグローバルにインストールすることを表します. グローバルにインストールしたくない場合はこのオプションを外し, 以下で実行する vue コマンドを npx vue に置き換えてください. なお, npm でインストールできる Vue CLI には @vue/cli の他に vue-cli がありますが, 後者は古いものです. Vue 自体のバージョンなどはプロジェクト作成時に選べますので, 基本的には前者をインストールすれば問題ないと思います. これでコマンドラインから vue コマンドが使えるようになりました. command not found となる場合は $ nodenv rehash を試してみてください. $ vue --version @vue/cli 4.15.2 のように表示されれば OK です. 動作確認 Vue CLI でプロジェクトを作成するには $ vue create <プロジェクト名> です. プロジェクト名と同じ名前のディレクトリが生成されます. カレントディレクトリをそのままプロジェクトのルートとして使いたい場合は vue create . とします. Generate project in current directory? (Y/n) と聞かれるので Y を入力してください. $ vue create vue-test Vue CLI v4.5.12 ? Please pick a preset: (Use arrow keys) ❯ Default ([Vue 2] babel, eslint) Default (Vue 3 Preview) ([Vue 3] babel, eslint) Manually select features create コマンドを実行するとプリセットを選ぶ画面になります. 今回は動作確認なので真ん中の [Vue 3] babel, eslint を選ぶことにします. 矢印キーで選択して Return です. Manually select features では Vue のバージョンを含め設定を細かくカスタマイズできます. ここで選ばなくても後から追加することは可能ですが, 移行が面倒だったりするので仕様が決まっている場合はあらかじめ選んでしまうのがいいかと思われます. プロジェクトが生成されたら開発用のサーバーで確認してみましょう. プロジェクトのルートで npm run serve です. $ cd vue-test $ npm run serve ... (省略) DONE Compiled successfully in xxxxms xx:xx:xx App running at: - Local: http://localhost:8080/ - Network: http://192.168.x.x:8080/ Note that the development build is not optimized. To create a production build, run npm run build. となれば立ち上がっています. ブラウザで localhost:8080 にアクセスしてみましょう. のような画面が表示されれば成功です. サーバーを停止するには Ctrl + C です. VSCode で開発する VSCode はデフォルトでは Vue のファイルをうまく扱えませんが, Vetur という拡張機能を入れると便利になります. Marketplace から検索して追加してみてください. Vue ファイルがシンタックスハイライトされ, Cmd + Return で参照元に飛んだりできるようになっていればひとまず OK です. まとめ これで Mac に Vue CLI の開発環境が構築できました. 具体的な開発の進め方についてはインターネットに素晴らしい記事がたくさんあるので, それらを参考にバリバリ開発を進めていきましょう!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-onディレクティブ

v-onはDOMイベントを引数に取ります。 *イベントを扱うことをイベントハンドラーと呼ぶ。 v-on イベントの種類 change フォーム要素の変更を検知 click マウスクリックを検知 dbclick マウスのダブルクリックを検知 input フォーム要素の変更完了を検知 keypress キーボードのキーダウンを検知 keyup キーボードのキーアップを検知 mousedown マウスボタンのキーダウンを検知 mouseup マウスボタンのキーアップを検知 mousemove マウスカーソルの移動を検知 mouseover マウスカーソルの侵入を検知 mouseout マウスカーソルの離脱を検知 クリックをカウントするものを作ります。 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>現在{{ number }}回クリックされています</p> <button v-on:click="number += 1">カウントアップ</button> </div> <script> new Vue({ el: '#app', data: { number: 0 } }) </script> </body>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

v-text,v-html,v-bindディレクティブについて

以下の2つのコードは同じ表現になります。 {{sayYes()}} <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p>{{sayYes()}}</p> <p v-text="message"></p> </div> <script> new Vue({ el: '#app', data: { message: "おはよう"}, methods: { sayYes: function() { return this.message; } } }) </script> </body> v-onceディレクティブ 再代入を防ぐ <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-once>{{message}}</p> <p>{{sayYes()}}</p> </div> <script> new Vue({ el: '#app', data: { message: "おはよう"}, methods: { sayYes: function() { this.message="おはようございます" return this.message; } } }) </script> </body> 最初に代入したものしか受け付けなくなる (this.message="おはようございます"で2度目に追加していますが) v-htmlディレクティブ タグを機能させる <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <p v-html="html"></p> <p>{{html}}</p> </div> <script> new Vue({ el: '#app', data: { html: '<h1>h1タグです</h1>' } }) </script> </body> *クロスサイトスクリプチィング(脆弱性)を生み出す危険性があります。 *ユーザーから提供されたコンテンツは絶対におかないでください。信頼のあるコンテンツに使ってください。 v-bindディレクティブ Linkタグを生成 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a v-bind:href="url">google</a> </div> <script> new Vue({ el: '#app', data: { url: 'https://www.google.com' } }) </script> </body> いままでとコードの仕方が違います。(引数を取ります) <a v-bind:href="url">google</a> 省略形 <a href="url">google</a> v-bindディレクティブを動的に扱う Linkタグを生成 <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a :[attribute]="url">google</a> </div> <script> new Vue({ el: '#app', data: { url: 'https://www.google.com', attribute: 'href' } }) </script> </body> <a :[attribute]="url">google</a> v-bindディレクティブ:引数を繋げることもできます <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a :href="url" :id="number">Twitter</a> </div> <script> new Vue({ el: '#app', data: { url: 'https://twitter.com', number: 100 } }) </script> </body> <a :href="url" :id="number">Twitter</a> v-bindディレクティブ:urlとidをオブジェクトとして扱う <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a v-bind="{href: url, id: number}">Twitter</a> </div> <script> new Vue({ el: '#app', data: { url: 'https://twitter.com', number: 100 } }) </script> </body> <a v-bind="{href: url, id: number}">Twitter</a> v-bindディレクティブ:urlとidをオブジェクトとして扱う(2) <body> <script src="https://cdn.jsdelivr.net/npm/vue@2.6.12/dist/vue.js"></script> <div id="app"> <a v-bind="urlObject">Twitter</a> </div> <script> new Vue({ el: '#app', data: { urlObject: { href: 'https://twitter.com', id: 100 } } }) </script> </body> <a v-bind="urlObject">Twitter</a> 中略 data: { urlObject: { href: 'https://twitter.com', id: 100 } }
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Nuxt.js】nuxt.config.jsに何が書かれているのか

nuxtの設定ファイル「nuxt.config.js」 nuxt.config.js では、下記のようにオプションを設定することができます。 export default { オプション: 値 } head このオプションで設定した値が、アプリケーション全体のメタタグに反映されます。 export default { head: { titleTemplate: '%s - Nuxt.js', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: 'Meta description' } ] } } metaタグって? 記事コンテンツの情報を検索エンジンやブラウザに伝えるための情報です。使用言語や文字エンコーディング、キーワードや説明文などについて記述しており、HTMLのhead要素内に配置されるタグのことです。 外部リソース読みこみもここで 第二引数以降に、詳細を指定できる。 async:非同期 defer:遅延 body:</body>の直前に追加 export default { head: { script: [ { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', async: true, defer: true, body: true } ] } } Headに指定できるオプション Nuxt.js公式 - head build ここで webpack や loaders など build 時の様々な設定を行うことができます。 import Sass from 'sass' import Fiber from 'fibers' build: { //略 loaders: { scss: { implementation: Sass, sassOptions: { fiber: Fiber, } } } } ここではサンプルとして、 Dart Sass という Sass のコンパイラの設定を書いてます。 fibers はコンパイル速度を向上させるためのライブラリです。 Nuxt.js公式 - build CSS グローバルに、全てのページで利用したい CSSファイルやCSSモジュールを指定します。 export default { css: ['~/assets/css/main.scss', '~/assets/css/animations'] } また、配列の2番目のように、 .css .scss といった拡張子を省いてもOKです。 plugins アプリケーションの初期化前にインポートしたい場合にここに記述。 plugins/ 配下に該当ファイルを置いて、ここに追加します。 引数を指定したい場合、オブジェクト形式で。 mode: 'client' ならクライアント側でのみファイルが読み込まれます。 export default { plugins: [ { src: '~/plugins/both-sides.js' }, { src: '~/plugins/client-only.js', mode: 'client' } { src: '~/plugins/server-only.js', mode: 'server' } ] } Nuxt.js公式 - plugins router nuxtで自動設定されたルートに変更を加えたいときに使います。 export default { router: { extendRoutes(routes, resolve) { routes.push({ name: 'Not Found', path: '*', component: resolve(__dirname, '~/pages/errors/404.vue'), }) } } } ルートを拡張したいときには、 extendRoutes() メソッドが準備されています。 Nuxt.js公式 - router srcDir このオプションで、nuxtアプリケーションの「ソースディレクトリ」を設定します。 export default { srcDir: 'app/' } この設定では、app/ 配下に components 、 pages、 plugins などの主要ファイル郡を設置するといった意味です。 Nuxt.js公式 - srcDir server アプリケーションのサーバー接続用の変数を nuxt.config.js 内に定義できます。 export default { server: { port: 8000, // デフォルト: 3000 host: '0.0.0.0', // デフォルト: localhost, timing: false } } server.timing オプションを有効にすると、サーバーサイドレンダリング中に経過した時間を計測するミドルウェアが追加され、'Server-Timing' としてヘッダーに追加されます。 Nuxt.js公式 - server 参考文献 Nuxt.js 公式 - nuxt.config Headに指定できるオプション
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Nuxt.js】nuxt.config.jsに何が書かれているのか調べた

nuxtの設定ファイル「nuxt.config.js」 nuxt.config.js では、下記のようにオプションを設定することができます。 export default { オプション: 値 } head このオプションで設定した値が、アプリケーション全体のメタタグに反映されます。 export default { head: { titleTemplate: '%s - Nuxt.js', meta: [ { charset: 'utf-8' }, { name: 'viewport', content: 'width=device-width, initial-scale=1' }, { hid: 'description', name: 'description', content: 'Meta description' } ] } } metaタグって? 記事コンテンツの情報を検索エンジンやブラウザに伝えるための情報です。使用言語や文字エンコーディング、キーワードや説明文などについて記述しており、HTMLのhead要素内に配置されるタグのことです。 外部リソース読みこみもここで 第二引数以降に、詳細を指定できる。 async:非同期 defer:遅延 body:</body>の直前に追加 export default { head: { script: [ { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js', async: true, defer: true, body: true } ] } } Headに指定できるオプション Nuxt.js公式 - head build ここで webpack や loaders など build 時の様々な設定を行うことができます。 import Sass from 'sass' import Fiber from 'fibers' build: { //略 loaders: { scss: { implementation: Sass, sassOptions: { fiber: Fiber, } } } } ここではサンプルとして、 Dart Sass という Sass のコンパイラ(npmインストールしたパッケージ)の設定を書いてます。 fibers はコンパイル速度を向上させるためのものです。 Nuxt.js公式 - build CSS グローバルに、全てのページで利用したい CSSファイルやCSSモジュールを指定します。 export default { css: ['~/assets/css/main.scss', '~/assets/css/animations'] } また、配列の2番目のように、 .css .scss といった拡張子を省いてもOKです。 plugins アプリケーションの初期化前にインポートしたい場合にここに記述。 plugins/ 配下に該当ファイルを置いて、ここに追加します。 引数を指定したい場合、オブジェクト形式で。 mode: 'client' ならクライアント側でのみファイルが読み込まれます。 export default { plugins: [ { src: '~/plugins/both-sides.js' }, { src: '~/plugins/client-only.js', mode: 'client' } { src: '~/plugins/server-only.js', mode: 'server' } ] } Nuxt.js公式 - plugins router nuxtで自動設定されたルートに変更を加えたいときに使います。 export default { router: { extendRoutes(routes, resolve) { routes.push({ name: 'Not Found', path: '*', component: resolve(__dirname, '~/pages/errors/404.vue'), }) } } } ルートを拡張したいときには、 extendRoutes() メソッドが準備されています。 Nuxt.js公式 - router srcDir このオプションで、nuxtアプリケーションの「ソースディレクトリ」を設定します。 export default { srcDir: 'app/' } この設定では、app/ 配下に components 、 pages、 plugins などの主要ファイル郡を設置するといった意味です。 Nuxt.js公式 - srcDir server アプリケーションのサーバー接続用の変数を nuxt.config.js 内に定義できます。 export default { server: { port: 8000, // デフォルト: 3000 host: '0.0.0.0', // デフォルト: localhost, timing: false } } server.timing オプションを有効にすると、サーバーサイドレンダリング中に経過した時間を計測するミドルウェアが追加され、'Server-Timing' としてヘッダーに追加されます。 Nuxt.js公式 - server 参考文献 Nuxt.js 公式 - nuxt.config Headに指定できるオプション
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Vue.jsを理解するために

#概要 Vueの構成要素を理解するためにVueの構成要素とディレクティブ、算出プロパティ、メソッドについてわかりやすく記載しました。 Vue.jsの構成 基本的な、Vue.jsの構成についての復習です。 main.js let app = new Vue({ el:'#app', data:{ message:'こんにちわ!' } }); 1,インスタンス化 main.js let app =new Vue Vue.jsを起動するためには、Vueクラスをインスタンス化する必要があります。 letで宣言していますが、生成したインスタンスを後から参照する必要がなければ必要ありません。 2,動作オプション Vue(オプション)動作オプション HTMLから参照できる値を格納オブジェクトです。プロパティ名:値とします。 el:Vueの適用要素 data:データオブジェクト message:dataオブジェクトのmessageプロパティです。データは上記ではこんにちわです。 HTMLの構成 index.html <div id="app"> <h1>{{ message }}</h1> </div> id属性▶Vueの適用範囲です。 {{}}▶マスタッシュ構文。テンプレートからデータオブジェクトをにアクセスします。複雑な条件分岐などは出来ません。 Vuejsを理解するために ①ディレクティブ イベントを表します。[v-]から始まります。 マスタッシュ構文は式の値を埋め込むことが出来ません。 そこで、属性値の操作はv-bindを使用します。 main.js data:{ url:'https://qiita.com/akari_0618/items/5a9e9d565b47c5de2e4d' } データオブジェクトにurlプロパティを追加します。 index.html <div id="app"> <a v-bind:href="url">GO</a> </div> v-bind:属性名=値 ディレクティブ名と属性名はコロンで区切ります。 コロンの後方はディレクティブの引数です。 ②ブール属性 属性名を指定するだけで意味がある属性のことを論理属性またはブール属性といいます。これらの値を紐付けるためにはtrue,falseで表します。 index.html <input type="button" value="クリック" v-bind:disabled="flag"> main.js flag:false ③算出プロパティ 算出プロパティとは、既存のプロパティを演算した結果を取得するためです。 算出プロパティの元では、[this.プロパティ名]でアクセスすることができます。 定義側はメソッドですが、参照はプロパティです。 index.html <p>{{loEmail}}</p> main.js data:{ email:'suzuki-r.e @ddddd.ne.jp' }, computed:{ loEmail:function(){ return this.email.split('@')[0].toLowerCase(); } } *split(r) 正規表現が一致する場所で文字列を分割して配列にします。 ④メソッド 上記の算出プロパティはメソッドでも表すことが出来ます。 ただし、methodで表した場合は index.html <p>{{loEmail()}}</p> プロパティでは無いため、()で呼び出します。 methodとは、Vue内で扱える機能を定義する場所です。 他の関数から呼び出したり、HTML内で呼び出すことが出来ます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む