Vue.JS ABC3 ルーティング
vue-router
パスを定義する。
Vue.use(VueRouter) const routes: Array<RouteConfig> = [ { path: '/', name: 'Home', component: Home }, { path: '/hoge', name: 'Hoge', component: Hoge } ] const router = new VueRouter({ routes }) export default router
使用を宣言
Vue.config.productionTip = false new Vue({ router, vuetify, render: h => h(App) }).$mount('#app')
画面遷移させたいところに
<router-view></router-view>
を入れておく。
<router-link to="hoge">hoge</router-link>
をクリックすることでその画面のところにrouter-viewが表示される。
コードで遷移させる場合は
this.$router.push('/');
VueABCその2 基本
テンプレート
{{ }}
<div>hoge world,{{ name }}?</div>
でそのテンプレートのnameのdataをみている。{{ }}は口髭(Mustache)
クリック v-on:click
<button v-on:click="pushCrick">push</button>
これでテンプレートのpushCrockメソッドが呼ばれる。
テーブルリスト v-for
<table> <tr v-for="item in myTableData" v-bind:key="item"> <td><img src="" /></td> <td> {{ item.title }} </td> <td> {{ item.value }} </td> </tr> </table>
v-forをつかえば繰り返しを書かなくてすむ。
バインディング v-model
<p>{{ myTextAreaData }}</p> <textarea v-model="myTextAreaData"></textarea>
dataとしてmyTextAreaDataはあること。テキストエリアに入力した値が上にも出てくる。
ちなみに
<textarea v-model.number="myTextAreaData"></textarea>
で数値のみ取得できる。
表示非表示 v-if
<transition> <p v-if="myCheckBox">Hello Transision</p> </transition>
v-if で表示、非表示ができる。myCheckBoxはブール代数。v-showで行うと、no:displayが付与される。
<style> .v-enter-active, .v-leave-active { transition: opacity 1s; } .v-enter, .v-leave-to { opacity: 0; }
ラジオボタン
<label><input type="radio" value="a" v-model="myRadioData" />A</label> <label><input type="radio" value="b" v-model="myRadioData" />B</label> <label><input type="radio" value="c" v-model="myRadioData" />C</label> <p>{{ myRadioData }}</p>
myRadioDataにするとAに印がつく。
セレクトボタン
<p>select test</p> <select v-model="mySelectData"> <option disabled="disabled">select</option> <option value="x">selectX</option> <option value="y">selectY</option> <option value="z">selectZ</option> </select>
mySelectDataにxを選ぶと選択されている。
算出プロパティ
<p>getter_setter</p> width: <input v-model.number="width" />{{ width }} height: <input v-model.number="height" />{{ height }} halfWidth: <input v-model.number="halfWidth" />{{ halfWidth }} <p>result halfwidth {{ halfWidth }} = width {{ width }} / 2</p> <p>x = {{ halfPoint.x }} y = {{ halfPoint.y }}</p>
算出プロパティとしては
computed: { halfWidth: { get: function() { return this.width / 2; }, set: function(val) { this.width = val * 2; } }, halfHeight: function() { return this.height / 2; }, halfPoint: function() { return { x: this.halfWidth, y: this.halfHeight }; },
書いておく、height, widhはデータとして定義しておく。
リストに対する制限等
<div><input v-model.number="okane" />YEN</div> <div>item number = <input v-model.number="myOkaneLimit" /></div> <button v-on:click="myOkaneListOrder = !myOkaneListOrder"> switch ordring </button> <p> matched {{ myOkaneMatched.length }}, limited {{ myOkaneLimited.length }} </p> <ul> <li v-for="item in myOkaneLimited" v-bind:key="item.id"> name:{{ item.name }} price:{{ item.price }} </li> </ul>
商品をお金が高い順、低い順にならべる。myOkaneListOrderのところ。myOkaneLimitは最大表示すう。
算出プロパティは
myOkaneMatched: function() { return this.myOkaneList.filter(function(el) { return el.price <= this.okane; }, this); }, myOkaneLimited: function() { return this.myOkaneMatchedSorted.slice(0, this.myOkaneLimit); }, myOkaneMatchedSorted: function() { return this.myOkaneMatched.slice(0).sort((item1, item2) => { let ordering = item1.price > item2.price ? -1 : 1; return ordering * (this.myOkaneListOrder ? -1 : 1); }); },
表示をフィルターかけて加工する。 filters
<p> {{price | localeNum}}円</p> <!-- localeNumはvue.filterとして登録 -->
filters: { localeNum: function(val) { return val.toLocaleString(); } },
filterは|を使って連鎖可能
そのままでる。 v-pre
<p v-pre>そのままでてきます。{{ そのままでてきます }}</p>
値の監視 watch
<p>watch test </p> 年齢<input v-model.number="age">以下の人を表示 <div v-if="displayWatchedData"> <p> name: {{watchedData.name}}</p> <p> age: {{watchedData.age}}</p> </div>
で、displayWatchedDataを監視するのは
watch: { 'watchedData': { handler: function(newVal, oldVal) { if (newVal.age>40) { this.displayWatchedData = true; } else { this.displayWatchedData = false; } }, deep: true, immediate: true }
要素のリファレンス $refs
<p ref="hello">Hello</p>
要素にref属性をつけておくとthis.$refs.helloで取れる。
console.log(this.$refs.hello); // helloのrefのついているタグを参照
svgを動かす。
<svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <circle cx="100" cy="75" v-bind:r="radius" fill="lightpink" /> </svg> <input type="range" min="0" max="100" v-model="radius" />
これでradiusを変更させると動く。
Vue.JS ABC勉強ノート
基本
<template> </template> <script> </script> <style> </style>
プラグインを各種使う
Vue.config.productionTip = false new Vue({ router, vuetify, render: h => h(App) }).$mount('#app')
アプリのマウント
new Vue({ el: '#app` // エレメントのid指定 })
this.$elでマウントしたタグが見れる。
スクリプト部分の雛形
<script> /* eslint-disable */ import { defineComponent, computed, watch } from '@vue/composition-api'; import MyCard from '@/components/MyCard.vue'; import Vue from 'vue' export let bus = new Vue();// イベントバス用 export default defineComponent({ name: 'Hoge', components: { 'my-cards': MyCard }, // データ コンポーネントではデータ側は関数をかえすものとすべき。 data: function() { return { name: '未設定', myTableData: [ { title: 'title1', value: 'value1' }, { title: 'title2', value: 'valueHoge' } ], }, // ライフサイクル created: function() { // イベントバス登録 bus.$on("BusEvent", function (message) { alert(message); }) }, mounted: function() { console.log(this.$el); // マウントしているタグを出力 console.log(this.$refs.hello); // helloのrefのついているタグを参照 }, // メソッド methods: { pushCrick: function() { this.name = 'poi!'; }, pushHome: function() { this.$router.push('/'); }, addHoge: function() { this.myTableData.push({ title: 'HOGE!', value: 'HogeHoge!' }); }, }, // 算出プロパティ setter, getterも設置できる。 computed: { halfWidth: { get: function() { return this.width / 2; }, set: function(val) { this.width = val * 2; } }, halfHeight: function() { return this.height / 2; }, halfPoint: function() { return { x: this.halfWidth, y: this.halfHeight }; }, myOkaneMatched: function() { return this.myOkaneList.filter(function(el) { return el.price <= this.okane; }, this); }, myOkaneLimited: function() { return this.myOkaneMatchedSorted.slice(0, this.myOkaneLimit); }, myOkaneMatchedSorted: function() { return this.myOkaneMatched.slice(0).sort((item1, item2) => { let ordering = item1.price > item2.price ? -1 : 1; return ordering * (this.myOkaneListOrder ? -1 : 1); }); }, }, // フィルター、結果のフィルターを通せる filters: { localeNum: function(val) { return val.toLocaleString(); } }, // 変化を監視して処理する。 watch: { 'watchedData': { handler: function(newVal, oldVal) { if (newVal.age>40) { this.displayWatchedData = true; } else { this.displayWatchedData = false; } }, deep: true, immediate: true } }, // 独自ディレクティブ 例えばv-focusとして使われる。 directives: { // 要素が挿入されたときにフォーカスする。 focus: { inserted: function(el) { el.focus(); } } } }); </script>
Basic認証周り
didReceiveAuthenticationChallenge でchallenge.protectionSpace.authenticationMethodがNSURLAuthenticationMethodHTTPBasicなものが飛んでくる。
completionHandlerにNSURLCredentialでinitWithUserでユーザ名とパスワードを入れてNSURLCredentialPersistenceForSessionで呼んでやらないといけない。
問題はmainスレッドでやってくるのにcompletionHandlerを呼ばないでリターンしたと怒られるという矛盾した動きをするところ‥。
ずっとalertViewControllerでpresentViewControllerしてエラーでおこられていたが、
カスタムビューを作って、画面全体に貼り付けて認証画面を作った(presentViewControllerしない)らうまくいった。
ちなみに、completionHandlerは保持しておいて、認証画面を出そうとしているのにまだcompletionHandlerがよばれていないときはNSURLSessionAuthChallengePerformDefaultHandlingして解消してやるのが決めてだったのかもしれない。
ちなみにauthenticationMethodがそれ以外の場合はchallenge.protectionSpace.serverTrustのNSURLSessionAuthChallengeUseCredentialでcompleteしていた。 これも頻繁に飛んできた。
このあたりの動きが謎すぎて驚いた。
ファイル操作
試してみた。
import { utilFunc } from './util'; import * as fs from 'fs'; import * as path from 'path'; import * as readline from 'readline' console.log("Hello, typescript!"); console.log(utilFunc("test")); console.log(process.cwd()); console.log(JSON.stringify(process.env)); // read const filePath:string = path.join(process.cwd(), "dist/util.js"); const text = fs.readFileSync(`${filePath}`, {encoding:"utf-8"}); console.log(text); // write fs.writeFileSync(path.join(process.cwd(), "dist/test.js"), "hello?"); // copy fs.copyFileSync(path.join(process.cwd(), "dist/test.js"), path.join(process.cwd(), "dist/test2.js")); // ls const list = fs.readdirSync(path.join(process.cwd(), "/"), {withFileTypes:true}); console.log("readdirSync:"+list.map((f)=>f.name)); // readline and write const readStream = fs.createReadStream(filePath, {encoding:"utf-8"}); const writeStream = fs.createWriteStream(path.join(process.cwd(), "dist/util2.js")); const rwInterface = readline.createInterface({ input: readStream, output: writeStream }); rwInterface.on("line", (input) => { writeStream.write(input+'\n'); }); rwInterface.on('close', () => { console.log("end"); }); // reg console.log('reg'); const results = "hogePoiPoge84754puge".match(/.*(Poi).*(\d{5}).*/); if (results) { for (const result of results) { console.log("->"+result); } } // ->hogePoiPoge84754puge // ->Poi // ->84754
iBeaconが探知されない。
iBeaconが探知されない理由がわかった。"常に"を許可してもらわないとだめなようだ。マニュアル的にはiPhoneの設定画面から変えてもらうしかなくなる。逆にそこで常に許可をしてもらえば動く。 このあたりiOS13以降ではまた違うかも。
図の描き方
Tikzで三角形を描いてみた。
\usepackage{tikz} \usetikzlibrary{intersections, calc, arrows}
をプリアンブルで宣言しておいて、以下にようにnewcommandで定義して使う。計算はcalcによって行われている。
\newcommand{\myTriangle}[1]{ \coordinate (myA) at ($#1+(0,0)$); \coordinate (myB) at ($#1+(1,1)$); \coordinate (myC) at ($#1+(2,0)$); \fill (myA)--(myB)--(myC)--cycle;} \begin{tikzpicture} % https://texwiki.texjp.org/?TikZ % https://math-note.xyz/latex/tikz/tikz-coordinate/ %\draw (0,0) -- (1,1) -- (2,0) -- (0,0); \coordinate (R) at (2,0); \coordinate (U) at (0,1); \coordinate (LD) at (-1,-1); \coordinate (RD) at (1,-1); \coordinate (A) at (0,0); \coordinate (B) at ($(A)+3*(R)$); \coordinate (C) at ($(A)+3*0.5*(R)+4*(U)$); \myTriangle{(A)} \myTriangle{(B)} \myTriangle{(C)} \draw ($(A)+0.5*(R)+1*(U)$) -- ($(C)$); \draw ($(B)+0.5*(R)+1*(U)$) -- ($(C)+(R)$); \draw ($(A)$) -- ($(A)-0.5*(R)-4*(U)$); \draw ($(A)+(R)$) -- ($(A)+(R)+0.5*(R)-4*(U)$); \draw ($(B)$) -- ($(B)-0.5*(R)-4*(U)$); \draw ($(B)+(R)$) -- ($(B)+(R)+0.5*(R)-4*(U)$); \end{tikzpicture}
ジェネリクスな配列による変数定義
export const eventIdList = <const>["HogeEV", "PoiEV"]; export type EventId = typeof eventIdList[number];
基礎的なこと
ひとまず座学したことをまとめてみた。
Dockerはコンテナ 仮想化OSを使用しない分軽く手軽。
基本 Dockerファイル(設定ファイル)を作って、ビルドしてイメージを作る。イメージを実行してコンテナを起動する。
Dcokerイメージ すでにDocker Hubに色々用意されていたりする。
コマンド イメージのpull
docker pull hoge
イメージの実行(手元になかったら勝手にDocker Hubに探しに行く。)、-dはデバッグモードで指定しないとフォアグラウンド実行される。-pはポート指定で8081はホスト側、80はコンテナ側 データの永続化したい場合は -v で場所指定 (一時的に作って消すのは --rm)
docker run -d -p 8081:80 hoge
状態をみる。
docker ps -a
停止する
docker stop コンテナID
コンテナ閉じる
docker rm コンテナID
イメージ削除
docker rmi コンテナID
- docker file作成
DockerFileというファイル名が普通? FROM poi どのイメージを使用するか、省略しないこと。 RUN yum -y update RUNはイメージを作る際のコマンド RUN yum -y install hoge ADD my/index.html var/www/html/index.html 設定等ファイルのコピー (COPYというのもある) EXPOSE 80 コンテナ側でListenするポート指定をしておくと実行するとき省略できる? CMD ["/user/sbin/hoge", "-a", "xyx"] コンテナ起動時に実行されるコマンド
docker filleのビルドは
docker build -t test/hoge:ver2.5
-t はタグ指定で階層構造で指定できる。version指定したい場合は:ver2.5などをつける。
これでイメージができてる。
docker images
- オーケストラレーションツール サービスの停止等を監視等、実際に運用する場合はこれらを使う。googleのKubernetesやAWSのECSが主にある。
大文字と小文字の変換
選択しておいてコマンドパレットからtransform to UpperCase等を呼ぶ。
ショートカット Mac 矩形選択
Sift+Cmd+Altを押しながら上下作用にカーソルを動かしていく。
デフォルトのアイコン等
iOS Developerから取得できる。モック作成に使える。