Rodhos Soft

備忘録を兼ねた技術的なメモです。Rofhos SoftではiOSアプリ開発を中心としてAndroid, Webサービス等の開発を承っております。まずはご相談下さい。

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が付与される。 で囲んでおけば表示のアニメーションが加えられる。次のようなcssを追加する。

<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していた。 これも頻繁に飛んできた。

このあたりの動きが謎すぎて驚いた。

adhoc周り

Rebuild from Bit Codeやるとipaの中身が変わってくる。 今回はやっていないのが正解だった。

あと

プロファイルは証明書(certification)とアプリとdeviceを紐付けるが、今回キーチェーン内にその証明書の秘密鍵がなかった。しかも証明書が同盟のものが複数ある感じで混乱‥。orz

ファイル操作

試してみた。

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}

基礎的なこと

ひとまず座学したことをまとめてみた。

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
  • オーケストラレーションツール サービスの停止等を監視等、実際に運用する場合はこれらを使う。googleKubernetesAWSのECSが主にある。

スニペット登録

設定画面にスニペット登録項目があるのでクリックしJSONを編集する。

 "hoge": {
        "prefix": "hoge",
        "body": [
            "ABCD",
            "DDDDDDDDDDD",
        ],
        "description": "for hoge"
    }

登録するとprefixまで書いてからコード補完が効く。macならalt+esc

Snippets in Visual Studio Code