BackacheEngineerの技術的な備忘録

技術系でいろいろ書けたらなーと

Vue.js とやらを勉強2

Vue.js で基本の属性をまとめる。

目次

v-html

ほとんど使わないじゃないかなって思ってるやつ。 v-html="---html---" で指定した html が差し込めるってやつ。

サンプル。 ボタン押すと入力した文字がどんどん追加されるってやつ。 こういう、追加作業するときって Web アプリだと多いのだろうか・・・。 そんななさそうなので、「使わない」と勝手に思っている。

  <div id="app">
    <ol v-html = "message"></ol>
    <hr>
    <input type="text" oninput="tempValue(event);">
    <button onclick="add();">add</button>
  </div>

  <script>
    let data = {
      message: '<li>one</li>',
      tempInput: ''
    }

    let app = new Vue({
      el: '#app',
      data: data
    });

    function add(){
      data.message += `<li>${data.tempInput}</li>`
    }
    function tempValue(event){
      data.tempInput = event.target.value;
    }

v-if

html 中に if 文が書き込めるやーつ。 ちゃんと else も書ける。

サンプルはボタン押すと内容が切り替わるよってやつ。 まとめてないけど template 構文を使ってる。

template 構文のおかげで、中身をまるっと変更できる。 後述するコンポーネントとか、実際に Vue.js でアプリ 作ってくってなるとこの template 構文が基本になる(と思っている)。

v-if = "条件" といったふうに書く。 「条件」に bool 値の変数名を書いて、data がその bool 値持ってれば Vue.js がきれいに変数として扱ってくれる。ありがたい。

    <div id="app">
    <template v-if="flag" >
      <p>Display data table.</p>
      <table>
        <tr><th>Name</th><th>mail</th></tr>
        <tr><td>Taro</td><td>taro@yamada</td></tr>
        <tr><td>Hanako</td><td>hanako@flower</td></tr>
        <tr><td>Sachiko</td><td>sachiko@happy</td></tr>
      </table>
    </template>
    <template v-else>
      <p>Display data list</p>
      <ul>
        <li>name: Taro, mail: taro@yamada</li>
        <li>name: Hanako, mail: hanako@flower</li>
        <li>name: Sachiko, mail: sachiko@happy</li>
      </ul>
    </template>
  </div>
  <button onclick="onChangeFlag();">
    change flag
  </button>

  <script>
    let data = {
      flag: true
    }

    let app = new Vue({
      el: '#app',
      data: data
    });

    function onChangeFlag(){
      data.flag = !data.flag;
    }
  </script>

v-for

さっきの v-if と一緒で html に for 文が書ける。 これのおかげでリスト表示とかもらくらくってわけ。

注意すべきなのは、v-if と併用すると 「v-if が後になる」ってことくらい? v-for が優先で動く。

使い方は v-for = " val in values " みたいなかんじ。 values がオブジェクトだとプロパティも抜き出せて、 ( obj, prop ) in values みたいな書き方になる。

index 番号が欲しい時もオブジェクトと同じ書き方で、 ( element, index ) in values になる。 ( javascript の for-in ループとは違うのがちょっと面倒・・?)

サンプルはオブジェクトを対象に、さらに v-if を組み合わせたやつ。

  <div id="app">
      <p>Display data list</p>
      <table>
        <tr>
          <th>name</th>
          <th>mail</th>
          <th>tel</th>
        </tr>
        <!-- v-for が優先で動く。v-if は v-for のあと。 -->
        <tr v-for="( obj, key ) in items" v-if="obj.isPublic">
          <td>{{ key }}</td>
          <td>{{ obj.mail }}</td>
          <td>{{ obj.tel }}</td>
        </tr>
        <tr v-else>
          <td>{{ key }}</td>
          <td>*** 非公開 ***</td>
          <td>*** 非公開 ***</td>
        </tr>
      </table>
    </div>

    <script>
      let data = {
        items: {
          Taro: {mail: 'taro@ssss', tel: '777-777', isPublic: true},
          Machiko: {mail: 'machiko@ieiieieie', tel: '888-888', isPublic: true},
          Administrator: {mail: 'admin@opertor', tel: '999-999', isPublic: false},
          Tester: {mail: 'tester@test', tel: '999-999', isPublic: false}, 
          Takeshi: {mail: 'takeshi@iwatype', tel: '999-999', isPublic: true}
        }
      };

      let app = new Vue({
        el: '#app',
        data: data
      });
    </script>

コンポーネント

すーぱー使う。絶対に使う。 必ず習得すべきもの。

できることは、新しい html のタグを作るようなもの。 C# でいうところのカスタムコントロールとかユーザコントロール。 ユーザコントロールのが近いかな。

このコンポーネントにプロパティ持たせて、そこに値をバインドとかできる。 XAML みたいだと思えば楽かも。(こういう時、自分の得意な言語にあてはめて考えれるのは楽だ)

単一のファイルでコンポーネントを作るときは Vue の関数を呼び出す。 そうでない場合、つまりちゃんとしたアプリだと *.vue っていう拡張子が vue の ファイルに書く感じ。

今回は前者で書く。

Vue.component(conponentName, { conponent が持ついろんなプロパティ })

こんな感じで使う。 conponentName はコンポーネント名で、これがタグになる。文字列で指定する。

第2引数はコンポーネントの本体で、オブジェクトで指定する。

ほんじゃまかサンプル。 「Hello ○○」って書いてくれるだけのコンポーネント。 サンプルは以下の仕様になってる。

  • コンポーネント名は hello(つまり、タグ名が hello)
  • name プロパティを持つ
  • 複数の「Hello ○○」を出すようになってる
  • name を v-bind して指定する

v-bind については後述する。

    <div id="app">
      <hello v-for="name in names" v-bind:name="name"></hello>
    </div>

    <script>
      Vue.component("hello", {
        props: ['name'],
        data: () => {
          return {
            message: "Hello ",
          };
        },
        template: '<p class="hello">{{ message }} {{ name }}</p>',
      });

      let app = new Vue({
        el: "#app",
        data: {
          names: ['taro', 'hanako', 'sachiko', 'takeshi']
        }
      });
    </script>

v-for で複数の name を取得する。names は Vue オブジェクトが持つ data に設定されたプロパティである。

1つ取り出した name が v-bind によってコンポーネントの name 属性にバインドされる。

そして、name 属性が template の {{ name }} 部分に入る仕組み。 name 属性は props: ['name'] で設定されている。(配列なんで複数書けるよ!)

Hello 部分を担う message はコンポーネント内の data プロパティが返している message プロパティのこと。 こいつが {{ message }} に入る。

v-bind

間違いなく超使うやつ。 バインドなんで、XAML でもいっぱい出てきてる。 つまり、特定の値に特定の値を割り当てる感じ。 ただし、v-bind は単方向だから、入力値をプロパティに代入とかはできない。 双方向でバインドしたいときは v-model を使う。

ちょっと前に v-bind で name 属性に変数 name をバインドした。 つまり、こいつは属性に対してバインドできる。

つまり、自分で設定した属性だけでなく html のタグの style とか class にもちゃんとバインドできる。

ほんじゃサンプル。 ボタンを押すと文字色が変わる。 文字色は css 側で class 「red」, 「blue」に対して変えてる単純なもの。

.red {
  color: red;
}

.blue {
  color: blue;
}
  <div id="app">
    <p v-bind:class="classes">{{ message }}</p>
    <button onclick="onChnageColor();">{{ btnText }}</button>
  </div>

  <script>
    let classObj = {
      // プロパティ名がそのままクラス名になる
      red: true,
      blue: false
    };

    let data = {
      message: "This is Message.",
      classes: classObj,
      btnText: "To Blue"
    };

    let app = new Vue({
      el: "#app",
      data: data
    });

    function onChnageColor() {
      classObj.red = !classObj.red;
      classObj.blue = !classObj.blue;
      data.btnText = classObj.red ? "To Blue" : "To Red";
    }
  </script>

classes でクラスを代入してる。プロパティ名がそのままクラス名になる。

そんで、bool 値に従ってクラスが適用される。

サンプルだとプロパティでクラスを代入してるが、下記のようにばちこり書いてもOK。

class="{red: isRed, blue: isBlue}"

v-model

v-model もバインドなんだけど、こいつは input タグの値をプロパティにバインドするやつ。

違った、v-model は双方向バインドのこと。 XAML でもあったやつ。入力した値をプロパティに渡すことができるし、プロパティの値を表示したりもできる。

これ以下の説明は一応そのとおりなんでそのままにしておくが、双方向バインドなんでもっとうまいことできるし、 ちゃんと考えないとたぶんだが沼る。

v-bind と組み合わせれば、input の値をプロパティにバインドして、プロパティにバインドした値を 属性にバインドする。これでリアルタイムに input の値がほかのタグに反映される。

下記がサンプル。 上記で書いてるとおり、input の内容を hello コンポーネントに渡している。

v-model でまとめたとおりの簡単なサンプルなので、これ以上は特に説明なし。

    <div id="app">
      <!-- name 属性に name プロパティを代入してる -->
      <hello v-bind:name="name"></hello>
      <!-- v-model により name プロパティに対して値が代入される。 -->
      <input type="text" v-model="name">
    </div>

    <script>
      // name プロパティを定義し、html 側で name 属性を指定すればここのプロパティとして入る
      Vue.component('hello', {
        props: ['name'],
        template: '<p class="hello">Hello, {{ name }}</p>'
      });

      let app = new Vue({
        el: '#app',
        data: {
          name: 'no-name'
        }
      })
    </script>
v-on

v-on はイベントの発生のこと。 指定した関数を実行してくれる。

下記のように書けば、click 時に func1 が実行される。

v-on:click="func1();"

複数個の関数を実行したいときは

v-on:click="func1();func2();func3()"

みたいに複数個繋げて書く。

コンポーネントに関数をオブジェクトとして持てる。

methods というプロパティを用意し、そこにオブジェクトを書く。 プロパティ名が関数名になり、「function () { ... } 」で関数を設定してやればいい。

サンプルはボタンを押すと以下の機能が働くもの。

  • ボタンの文字色が変わる
  • カウンターが増える
  • ボタンのメッセージも変える

文字色はクラスを変更し、 css で変えてる。 カウンターとかメッセージは関数の中身でゴリゴリと。

    <div id="app">
      <click></click>
    </div>

    <script>
      Vue.component("click", {
        methods: {
          // この this は component 内のネストのみ
          onChangeColor: function () {
            this.classes.red = !this.classes.red;
            this.classes.blue = !this.classes.blue;
          },
          onAddCounter: function () {
            this.counter++;
          },
          onChangeMessage: function () {
            this.message = this.classes.red
              ? `To Blue counter: ${this.counter}`
              : `To Red counter: ${this.counter}`;
          },
        },
        data: function () {
          return {
            counter: 0,
            classes: {
              red: true,
              blue: false,
            },
            message: `To Blue counter: 0`
          };
        },
        template:
          '<button v-on:click="onChangeColor();onAddCounter();onChangeMessage();" v-bind:class="classes">{{ message }}</button>',
      });

      let app = new Vue({
        el: "#app",
      });
    </script>

v-on も好きな関数を実行できるんで、よく使うだろうなぁ。

次にまとめるの

次はばちこり vue/cli でアプリ作ったやつをまとめたい。 まだ勉強中なんでまたまとまってきたら書く・・・。