Vue.js 練習

これはなに?

私が Vue.js を練習した時の忘備録的記録です。詳しい内容が知りたいならオフィシャルのリファレンスを見たほうがよいです。日本語ですし。

経緯

最近 PHP でもやってみるかな、と思って始めたけど、テンプレートエンジンでいいのがなさそうだったので(というか、Smarty しかつかってないけど)、それなら Vue.js をフロントにしてみては? と思って使い始めてる。気に入らなかったらやめると思う。

ちなみにVue.js をPHPのフロントにする方法は以下のサイトに載ってます。

レガシー管理ページをちょっと動的にするためだけのVue.jsとPHP - Qiita

初めの一歩。Hello World

以下の html を サーバーに置くと Hello Vue!! と表示される。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>

    <script type="text/javascript">
      var v = new Vue({
        el: "#app",
        data: {
            message: "Hello Vue!!"
        }
      });
    </script>
  </body>
</html>

<div id="app"> 下の要素で {{ }} でくくった部分を置き換える。というのが基本的な動作のようだ。

属性の動的生成

属性にデータを割り当てたいからと言って <a href="{{ link }}">test</a> という書き方はできないらしい。その代わりに <a v-bind:href="link">test</a> という書き方をする。 v-bind: というプレフィックスを属性名につけることで値にデータ名が使えるようになる。下記の例では link の部分が #app に置き換わる。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <a v-bind:href="link">test</a>
    </div>

    <script type="text/javascript">
      var v1 = new Vue({
        el: "#app",
        data: {
            link: "#app",
        }
      });
    </script>
  </body>
</html>

属性に式を指定して動的生成

さっきの例では バインドしている値はデータ名のみだが、値は式でもよい。以下の例では href="/sub_dir/" となる。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <a v-bind:href="link + '/'">test</a>
    </div>

    <script type="text/javascript">
      var v1 = new Vue({
        el: "#app",
        data: {
            link: "/sub_dir",
        }
      });
    </script>
  </body>
</html>

属性にメソッドを指定して動的生成

式だけではなくてメソッドも可能。オリジナルのメソッドだけではなく、組み込み関数も指定できる。例えば、<a v-bind:href="Math.abs(-100)">test</a> とすると <a href="100">test</a> が生成される。意味はない。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <a v-bind:href="goto('/')">test</a>
    </div>

    <script type="text/javascript">
      var v1 = new Vue({
        el: "#app",
        methods: {
            goto: function(path) {
                return "/sub_dir" + path;
            }
        }
      });
    </script>
  </body>
</html>

コンポーネント

でもやっぱり、属性に式とか関数とか書きたくない。一回だけならまだいいけど、何回も書くとなるともうちょっと違う感じで書きたい。

コンポーネントは独自のノードを作成するための手法。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <link_to uri="/"></link_to>
    </div>

    <script type="text/javascript">
      Vue.component('link_to', {
        props: ['uri'],
        template: `
          <a :href="uri">test</a>
        `
      })
      var v1 = new Vue({
        el: "#app",
      });
    </script>
  </body>
</html>

こんな感じでかける。ただ、これだど直接書くのと変わらないのでコンポーネント側で関数や式を使って入力値(ここでは uri ) を修飾してあげるとよいかも。ただ、オリジナルのメソッドやデータをコンポーネント内で使いたい場合には以下の例のように this.$root.goto(uri) のようにし、少し工夫する必要がある。何回も同じような記述をする場合はコンポーネントにまとめておくのがよさそうだ。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <link_to uri="/"></link_to>
    </div>

    <script type="text/javascript">
      Vue.component('link_to', {
        props: ['uri'],
        template: `
          <a :href="this.$root.goto(uri)">test</a>
        `
      })
      var v1 = new Vue({
        el: "#app",
        methods: {
            goto: function(uri) {
                return "/sub_dir" + uri;
            }
        }
      });
    </script>
  </body>
</html>

コンポーネントのネスト

先の例では、<a> 要素のテキストが test 固定になってしまって不便。props に足してもいいけど、HTMLっぽく書きたい場合もある。そういう場合は <slot> を使う。

<html>
  <head>
    <title></title>
    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
  </head>
  <body>

    <div id="app">
      <link_to uri="/">test</link_to>
    </div>

    <script type="text/javascript">
      Vue.component('link_to', {
        props: ['uri'],
        template: `
          <a :href="this.$root.goto(uri)"><slot></slot></a>
        `
      })
      var v1 = new Vue({
        el: "#app",
        methods: {
            goto: function(uri) {
                return "/sub_dir" + uri;
            }
        }
      });
    </script>
  </body>
</html>

おわり

おわり。