【Vue.js3入門】Javascriptが、あまり分からない人向け

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約18分で読めます。
広告

初心者が公式のVue.jsを読んで勉強しようとしても難しく感じると思うので私なりに公式をベースに解説したいと思います。対象はHTML、CSSが、ある程度わかっている方Javascriptは分からなくてもいけるかもしれません。公式が分かりづらいのは英語の翻訳ということもありますが誤解を生まないような正確な内容でなければならないこともあるかと思います。またVueを使いこなすにはJavascriptの知識は必須です。しかし初心者がJavascriptマスターしてVueにたどり着くまでには相当時間がかかると思います。そこでVueから入り、後から必要に応じてJavascript勉強してはどうかと思います。Vueが取りあえず使えるようになることを目的にJavascriptが詳しくない私が初心者目線で解説します。まずはある程度使えるようになってから正確な知識を取得する第一段階としてとらえてください。私のレベル感的にはこんな感じです。(私のポートフォリオ)Vueを勉強して日が浅いので誤解してるところもあるかもしれませんがご了承ください。

Vue.jsに沿って説明しますのでVue.jsを見ながら、こちらの記事をお読みください。

またプログラミングが全く初心者の方は、こちらで勉強してから読んでもらえればわかるかもしれません。

ある程度Vue.jsがわかったらvuetifyを使うと結構簡単にそれなりのものができます。

広告

インストール

ここで私が知っておけばいいと思うことは、実用する方法を確認できればいいと思います。
具体的にはindex.htmlにコードを書くだけでも使えるということ。

Vue アプリケーションの作成は、Node.jsが必要で初心者には難しいので、やらないで
まずはCDN の Vue を使用するをやったほうがいいです。
グローバルビルドの使用、ES モジュール ビルドの使用、インポートマップの有効化と3種類ありますが、意味はわからなくても、(私も分からない)それぞれ下の方法で確認してみてください。

公式ではJSFiddleを使っていますが一度htmlファイルで動くことを確認すると必要なものが、これだけでいいことが分かるのでやってみることをおすすめします。またブラウザの検証ツールで確認したいとき、index.htmlを作ってブラウザで動かせば検証ツールも使えます。
具体的にはWindowsの場合、メモ帳で作れます。メモ帳を立ち上げます→下記コードに公式のサンプルプログラムをコピペ→メモ帳のファイル→名前を付けて保存→「ファイルの種類」をテキスト文章ではなく、すべてのファイルに変更(ここが大事です)→ファイル名をindex.html→保存→保存したindex.htmlをダブルクリックかブラウザにドラッグアンドドロップすると実行できます。修正するときは、空のメモ帳を開いて、そこにドラッグアンドドロップ。
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

  <--ここにhtmlと書いてあるコードを書く-->

</html>

ブラウザによるのかもしれませんが実際<!DOCTYPE html>とかなしでクイックスタートに書いてあるコードだけ貼っても動きました。

モジュールの分割
これは単純にindex.htmlmy-component.jsを作って横においてもエラーになります。クイックスタートの説明に書いてある通りサーバーを用意しないとできません。

チュートリアル

チュートリアルはAPI選択というのがあります。Options API 、Composition API が切り替えられます。
上のようにメモ帳でやる場合Optionsのコードでないと動きませんでした。しかも先頭には以下が必要です。

<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>

HTMLとSFCの切り替えは、SFCのほうはVue アプリケーションの作成で使うApp.vueファイルです。
基本OptionsとHTMLに設定してやっていけばいいと思います。
チュートリアルでは右側のデフォルトのコードをいじって実験できます。
下段のShow me!をクリックすると答えのコードが出ます。

題名は公式の場所が分かるように書いています。言葉の意味にこだわる必要はなく動かしてみて後々つながればいいと思います。(私は宣言的レンダリングと言われても、まだ?ですが)

宣言的レンダリング

先ほどのindex.htmlのひな形にサンプルコード(Show me!を押した状態のコード)をくっつけたコードを載せておきます。
それとチュートリアルの解説にあるHello World!を反転させるコードを最下段に付けました。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>
<script type="module">
import { createApp } from 'vue'

createApp({
  data() {
    return {
      message: 'Hello World!',
      counter: {
        count: 0
      }
    }
  }
}).mount('#app')
</script>

<div id="app">
  <h1>{{ message }}</h1>
  <p>Count is: {{ counter.count }}</p>
  <h1>{{ message.split('').reverse().join('') }}</h1>

</div>
</html>

昔の1個目サンプルはただCounter: 0と出るだけでした。
今回のサンプルに当てはめたコードです。
注意点は今回ES モジュール構文が使われています。
createAppの部分をCounterとして実行して開発者ツールのコンソールで確認すると
Uncaught SyntaxError: The requested module ‘vue’ does not provide an export named ‘Counter’ なってしまうところです。createAppという名前にしないとダメみたいです。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
</head>

<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>
<script type="module">
import { createApp } from 'vue'

createApp({
  data() {
    return {
        counter: 0
    }
  }
}).mount('#counter')
</script>

<div id="counter">
  Count is: {{ counter }}
</div>
</html>


昔のコード解説

Vue.createApp(Counter).mount('#counter')により青部分(Vueインスタンス)が有効な場所は赤の部分であることを指定している(マウントする)。#counterの#はid属性のcssセレクタ。名前はそろえる必要はなく
<div id="app">
Vue.createApp(Counter).mount('#app')
というようにmountのところはappがよく使われます。
{{変数}}で変数の中身が表示される
js(Vueインスタンス)部分の基本構成
const インスタンス名 = {   //今回のインスタンス名はCounter
  data() {
    return {
      htmlで使ってる変数: 0
    }
  },
  created()やcomputed()やmethods()など { //詳細は後述
処理
  }
}

目次へ

属性バインディングv-bind

昔のチュートリアルのサンプルも載せておきます。
チュートリアルの右側のコードが貼れる所にコピペしてみてください。

HTMLのtitle属性は、タグ内の文字にマウスを持っていくとtitle属性に設定した文字列が表示(ホーバー)されます。上の場合messageと表示されるはずです。下は日付付きのメッセージが出ます。

<script type="module">
import { createApp } from 'vue'

createApp({
  data() {
    return {
      message: 'You loaded this page on ' + 
                new Date().toLocaleString() //Javascriptの日付を取得するメソッド
    }
  }
}).mount('#app')
</script>

<div id="app">
  <span title="message">
    Hover your mouse over me for a few seconds to see my dynamically bound
    title!
  </span>
  <br><br>
  <span v-bind:title="message">
    Hover your mouse over me for a few seconds to see my dynamically-bound
    title! 
  </span>
</div>
ここでのポイントはv-bind:属性="○○○○"としてdataのところに○○○○:値とすることで紐づけされるところです。例でいえばdataのところのmessage:の値を'abc'に変えv-bind:title='abc'に変えればいいです。

もう一つサンプルとしてstyle属性のv-bind例も紹介しておきます。v-bind:titleを下のようにv-bind:styleに変えてください。変数はmessageのままにしてみます。jsも以下のように変えるとフォントサイズ30で赤色になります。
略
createApp({
  data() {
    return {
      message:{fontSize:'30px',color:'red'}
    }
  }
}).mount('#app')
略
<span v-bind:style="message">
略

目次へ

イベントリスナー v-on

昔のサンプルも追加しました。
このプログラムの動作は、ボタンが押される→reverseMessage(ユーザー定義)メソッド実行→reverseMessageでmessageの中に入っている文字列を反転してmessageに代入→messageの値が変わったので新しいmessageの中身で描画される。

<script type="module">
import { createApp } from 'vue'

createApp({
  data() {
    return {
      count: 0,
      message: 'Hello Vue.js!'
    }
  },
  methods: {
    increment() {
      this.count++
    },
    reverseMessage() {
      this.message = this.message //messageの中に入っている文字列に以下の3つの処理を上から順番にしてmessageに代入する。
        .split('') //1文字ずつの配列になる
        .reverse()//配列を逆転させる
        .join('')//配列を連結して文字列にする
    }
  }
}).mount('#app')
</script>

<div id="app">
  <button @click="increment">count is: {{ count }}</button>
  <p>{{ message }}</p>  <!--messageの中身が表示される-->
  <button v-on:click="reverseMessage">Reverse Message</button>
<!--ボタンが押されるとjsのmethodsのreverseMessageが実行される。-->
</div>
ポイント
<button v-on:イベント名="メソッド名">でjsのmethodsのメソッドが実行される。イベント名には今回clickだが他にmousemoveやinputやkeydownなどがある。参考Vue の基本イベント全17実例!
dataに書かれている変数(ここではmessageのみ)の値がjs部で変わったら、何もしなくても新しい値で再描画される。

目次へ

レンダリングされた DOM がどのように変化するかを見てみましょう

昔のサンプルです。今はなくなっています。

今回と昔でコードの形が違うのはVue.js本体を読み込んでいる部分が違うためです。
今回(ES モジュール構文)
<script type="importmap">
  {
    "imports": {
      "vue": "https://unpkg.com/vue@3/dist/vue.esm-browser.js"
    }
  }
</script>
昔(今回のグローバルビルドと形は似ているが、読み込んでいるもの(src=の部分)が違う上にscriptの書き方も違っている(下のサンプル参照)。なので読み込んでいるVue.js本体と同じものを使っているサンプルを確認し、それに書き方を合わせるようにしたほうがいい。)
<script src="https://unpkg.com/vue@next"></script>

メモ帳に貼って実行すると今でも動くので、よかったら読んでみてください。
1ずつ数字が増えます。stoptimerボタンはコードにはありません。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <script src="https://unpkg.com/vue@next"></script>
  <title>Document</title>
</head>
<body>
  <div id="counter">
  Counter: {{ counter }}
</div>
</body>
<script>
const Counter = {
  data() {
    return {
      counter: 0
    }
  },
  mounted() {
    setInterval(() => {
      this.counter++
    }, 1000)
  }
}
Vue.createApp(Counter).mount('#counter')
</script>
</html>
コード解説
setInterval(() => {
      this.counter++
    }, 1000)
setIntervalはJavascriptのメソッドsetInterval(func, delay)。delayミリ秒ごとにfuncが実行されます。なのでこの場合1000ミリ秒=1秒ごとにcounterが1づつ増えます。

()=>はアロー関数といってfunction()を書き換えたものです。なぜアロー関数を使っているかの前にthisについて解説。公式でthisとは呼び出し元である現在アクティブなインスタンスを指すと書いてあります。
thisは文字通り「これ」です。thisは見たほうが速いのでconsole.log(this)を入れて確認します。ついでにアロー関数とfunction()でthisがどう違うかも見てみます。インターバル時間も30秒に変更
。先ほどのコードのmounted部分を以下に変更してください。
  mounted() {
   console.log('最初')
   console.log(this) //①ここのthisはproxy(恐らくCounterインスタンス)を指してる
   console.log(this.counter) 
   setInterval(()=> {
      this.counter++;
    console.log('アロー関数内')
    console.log(this) //②ここのthisはproxy(恐らくCounterインスタンス)を指してる
    console.log(this.counter)
    }, 30000);
   setInterval(function() {
      this.counter++;
    console.log('function内')
    console.log(this) //③ここのthisはwindow(グローバルオブジェクト)を指してるためここのthis.counter++は実行されない。
    console.log(this.counter)
    }, 30000)
  }
index.htmlをダブルクリックしてプログラムを動かしたら、ブラウザの検証ツールを開きます。edgeの場合ブラウザのどこかで右クリック→開発者ツールで調査する→コンソールで見れます。
function()に変えたらthisがwindows(グローバルオブジェクト)ということで別なものを指しているのでthis.counter++は動きません。
また▶proxyをクリック、▶[[Target]]:Objectをクリックするとcounterが表示されます。これを見てもthis.counterで指定できそうなのが分かります。windowのほうはない。
setIntervalで30秒ごとに呼ばれると、そのときthisはwindowになっています。アロー関数では、thisはアロー関数が宣言された場所によって決まるようです。参考(【JavaScript】アロー関数式を学ぶついでにthisも復習する話)なのでsetIntervalでアロー関数を使った場合は最初にthisが固定されますが。functionの場合、1番最初はアローと同じthisだったはず(違うかも、未確認)ですが、30秒後にはthisはwindowになって、そっちを使うのでcounter++は実行されません。
ライフサイクルフックのtipで
アロー関数 (opens new window)をオプションのプロパティやコールバックに使用しないでください。と書かれています。そこで使っていけない例としてcreated: () => console.log(this.a)があります。オプションのプロパティにcreatedと同じくmountedやmethodsも該当します。
今回mounted: () =>ではなくmounted()で使っているので問題ありません。アロー関数を使っているのは、mountedの中のsetInterval(()=> なので該当しません。

まとめると
js部分のdata以外の場所で変数を使うときはthis.を付ける。
おかしかったらconsole.log(this)でwindowになっていないか確認すればいいと思います。
目次へ

CODE Pen使い方

昔のチュートリアルはCODEPENでプログラムを動かせるようになってるのでCODEPENを使用してました。使い方はRun Penをクリックすると実行されます。コードを見るときはHTML、CSS、JSのタグをそれぞれクリックすれば見れます。変更もできます。ただしRun Penを押した後でないと編集できない。HTMLはbodyタグの中身だけ書けば動くようになっています。<DOCTYPE html><html lang=”ja”><head>・・・は不要です。

ここから先は本を出しています。

2023/5/11チュートリアルが変わったので書き直しました。

CDNの限界VueCLIを使う理由

ここまでCDNを使用してきました。このまま公式のサイトで勉強を続けてもいいと思いますがVueCLIを使ってみるのをおすすめします。
VueCLIを使ったほうが便利な理由

  • エラーチェックしてくれる。CDNだと、おかしなところがあっても実行できてしまう。
  • ファイルを分割しやすい。
  • コンポーネントが使いやすい。

CDNだと1文入れるだけでメモ帳だけでも作れてしまいます。それと比べるとVueCLIは難しそうに思えますが簡単です。1番いい点は、出来上がったコンポーネントを簡単に読み込んで使えるのでやれることが増えます。以下を参照してください。VueCLIで実際に作ります。

また出来上がったコンポーネントが豊富にあって使えるvuetifyがおすすめです。

上はVuetify2ですが公式が日本語なのでVue2でまずは勉強するのもいいと思います。
下はVuetify2で作ったものをベースにエラーが出るところをVuetify3に変更したんですが、ほとんどVuetify2のコードでも動きました。ワーニングの部分は、少し書き換えないとワーニングは取れませんがワーニングが出ても動くので慣れてから修正でいいと思います。

イチゲをOFUSEで応援する(御質問でもOKです)Vプリカでのお支払いがおすすめです。
Vプリカでのお支払いがおすすめです。

MENTAやってます(ichige)
目次へ

コメント

タイトルとURLをコピーしました