社内Vue勉強会①
目的
・Visual Studio Codeを使って、Vueの開発環境の構築ができる
・Vueの基本的な機能を理解する
当日までの事前準備
・Visual studio Codeをインストール済み
・ターミナル(Command line)の基本知識
・nodeのインストール(v16推奨)
用語集(後述します)
・Vite Webpackに変わる高速ビルドツール
・ディレクティブ vueで使われるカスタム属性
・コンポーネント開発 画面(GUI)のモジュール化
基本事項
・typescriptを使用します(js,jxs,tsxも可能)
・cssを使用します(sass,stylusでもOK)
・VueはSingle File Components形式で説明します
・Vue3系で説明します
環境構築
便利なcliを使って、プロジェクトの雛型を作ります。
(↑ビルドツールにViteを使っています)
npm init vue@latest
パッケージのインストールが始まり、以下の質問に答えると雛型が出来上がります。
・単純化のため、テストライブラリと状態管理ライブラリ(Vuex)はNoとしています
> Project name:
> Add TypeScript? -- Yes
> Add JSX Support? -- No
> Add Vue Router for Single Page Application dev? -- Yes
> Add Pinia for state management? -- No
> Add Vitest for Unit testing? -- No
> Add Cypress for both Unit and E2E testing? -- No
> Add ESLint fro code quality? -- Yes
> Add Prettier for code formatting? -- Yes
これでプロジェクトは出来上がりです。次にサーバーを立ち上げてみます。
> cd プロジェクト #プロジェクトに移動
> npm install #依存関係をインポート
> npm run dev
http://localhost:3000
にアクセスすると、
が表示されるはずです。
Viteの説明(optional)
Vueの作者が作ったビルドツール。以下の特徴がある。
・typescript->javascriptへのトランスパイル(ただし型checkは無し)
・cssモジュールに対応(後述)
・ホットリロードに対応(コード変更箇所が画面に即時反映)
・esbuildを使っており、webpackよりもバンドルが早い
プラグイン紹介
VSCodeで必要なpluginなどの説明をします。
Vue
- Volar
Vue3のSnippetsの生成や、入力補完をしてくれる。 - ESLint
Microsoftお手製のLintツール。 - Prettier(https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
コードのフォーマットをしてくれるツール。
HTML&CSS
- Auto Closed Tag
HTMLのタグを自動で閉じてくれる。 - Sass(Syler)
Sassの補完やフォーマッターをしてくれる
Git(Optional)
- GitGraph gitコミットをグラフにしてくれる
コード修正
.vscode/settings.json
コードを保存(ctrl+c)した時にフォーマットとeslint効かせることをオススメします。
{
"editor.codeActionsOnSave":{
"source.fixAll.eslint":true //コード保存時にeslintを走らせる
},
"editor.formatOnSave":true, //formatter
"editor.defaultFormatter": "esbenp.prettier-vscode" //プラグインのprettierを指定
}
を書いておくと、毎回保存した時にコード修正+フォーマットしてくれるので便利です。
tsconfig.json
tsc(typescriptコンパイラ)に食わせる設定ファイルです。
viteはtypescriptの、型チェックを有効にしておきます。
{
"compilerOptions":{
"noEmit":true //これを追加
}
}
Vueの説明
ファイル構造の説明
- .vscode/
- node_module/
- public/ favicon位しか置かない?
- src/
assets/ styleに関するファイルを置く。cssファイルや画像など。
components/ モジュール単位のvueファイル
views/ 画面単位のvue
App.vue 画面の親vue。全画面で共通な部分(ヘッダーなど)を記述。 - main.ts index.htmlとApp.vueを結びつける。ルーターなどのモジュールをインポート。
- .eslintrc.cjs eslintに関するルールを記述
- .gitignore
- index.html
<!DOCTYPE html>
が書かれた画面のエントリーポイント。 - package.json npm installしたライブラリが書かれている
- tsconfig.json tscの設定ファイル
- vite.config.ts viteの設定ファイル
画面実装でいじるのは、src/components/
とsrc/views/
です。
次にvueのファイルを見てみます。
Vueファイルの構造
App.vueを見てみると、<script>
と<template>
と<style>
のタグがあります。
<template>
にはHTML、<style>
にはcssを書きます。
*import文には@
がありますが、src/
のエイリアスです(tsconfig.jsonに書いてあります)
<script setup lang="ts"> //これはtypescriptで書くよという命令
import HelloWorld from "@/components/HelloWorld.vue" // HellowWorldモジュールをインポート。
import TheWelcome from "@/components/TheWelcome.vue" // TheWelcomeモジュールをインポート
</script>
<template> // lang="pug"でpugテンプレートエンジンも選べる
...
<div class="wrapper">
<HelloWorld msg="you did it!"/> //インポートしたモジュールを参照
</div>
...
<main>
<TheWelcome/> //インポートしたモジュールを参照
</main>
...
</template>
<style> // cssを記述する。
// lang=sassでsassが書ける npm install sass sass-loaderが必要
...
</style>
このように、一つの画面に対して、スタイル(css)、構造(html)、アクション(ts/js)を同じ場所に書くのを、Single-File Component(SFC)と呼びます。
cssとモジュール化
画面共通のスタイルを指定する場合は、src/assets/
以下にcssファイルを置きます。
src/assets/
に置くファイルは、基本以下のようなものです。
- normalize.cssやreset.css
- 基本色やthemeなどが書かれたcss
- ボタンやアイコンなど画面共通のレイアウト(.buttonや.iconなど)
逆に、コンポーネントに書いたcssは、他のコンポーネントに影響を及ぼさない方が良いでしょう。
その場合は、<style scoped>
と書けば、他のcssを上書きすることはありません。(cssのmodule化)
Vueディレクティブの説明
ディレクティブは、「コンパイラーに与える補足情報」と定義されてます。
vueにも良く使うディレクティブがいくつかあるので紹介します。
v-class(または:class)
クラスを動的に付けたい場合は、v-class
を使用します。
例えば、ボタンをactiveにしたい場合
演習
button要素を追加し、アクティブにする
v-on(または@)
Html要素のイベントハンドリングに使います。
良く使うのは、ボタンのクリックイベントですが、changeやblur,focusなど様々なイベントに対応しています。
<button v-on:click=function($event)></button>
演習
button要素のクリックイベントを取得する。
v-for
同じオブジェクトを複数回表示する場合に使います。
たとえば、動的なリストを表示する場合、<li v-for="item in items">{{item}}</li>
のように使います。
演習
人名を動的なリストで表示させる
v-model
inputやtextareaなどに入力された値を受け取ります。(そのままだとコンポーネントには使えません)
input要素に入力された値を、msgとして出力しましょう。
演習
input要素を追加し、それを表示する(refを使う)
これまで
ディレクティブは他にも、
- v-show
- v-if v-else
- v-style
などありますが、使い方は変わりません。
Vueコンポーネント間のデータの渡し方
コンポーネントにデータを渡すには、propsとemitの方法があります。
props(親コンポーネント->子コンポーネント)
コンポーネントに渡す引数です。例えば、<HelloWorld msg='You did it!'/>
のmsg
がpropsです。
'You did it!'のメッセージを変えると、表示も変わりますが、これはHelloWorld.vueに
{msg:'You did it!'}
という形で引数が与えられ、それを表示しているからです。
引数を受け取るにはdefineProps
を使います。
HelloWorld.vue実装を見てみると
<script setup lang="ts">
defineProps<{
msg: string
}>()
</script>
<template>
...
<h1 class="green">{{msg}}</h1> //ここで表示される。{{}}を使う
</template>
と、確かにmsgが受け取られているのが分かります。
次に、HTMLに直接文字を書くのではなく、msg
を変数として渡してみます。
この場合は、文字列ではなく変数を受け取るために、<HelloWorld :msg="msg">
となります。
演習
msgを変数にする。
emit(子コンポーネント->親コンポーネント)
子コンポーネントから親コンポーネントにデータを渡したい場合があります。
たとえば、ログインフォームの子コンポーネントであるInputPassword.vue
から親コンポーネントLogin.vue
に入力データを渡したい場合です。パスワードが入力されていない場合は、ログインボタンを押せないようにします。
こういう場合には、emit
を使います。
Login.vue
<template>
<InputPassword @update:password="update"/> //ここで受け取る
<button :class={'is-active':active}>ログイン</button>
</template>
<script lang="ts" setup>
import {ref} from "vue"
const active = ref<boolean>(false)
const update = (value:string)=>{
active.value = value.length!=0
}
</setup>
InputPassword.vue
<template>
...
<input v-model="password" type="password">
</template>
<script>
improt {watch} from "vue"
const password = ref<string>("")
const emits = defineEmits(['update:password'])
watch(password,()=>{ //passwordの値が変化した場合に、callbackが呼ばれる。
emits('update:password',password.value) //password.valueの値が親コンポーネントに渡る
})
</script>
演習
ボタンを押したら+1ずつカウント表示されるカウンターを作ってみましょう。
ただし、ボタンは子コンポーネントとして切り出してください。