Vue
Vue は、ユーザーインターフェースを構築するための JavaScript フレームワークです。標準の HTML、CSS、JavaScript を基礎にし、宣言的でコンポーネント化されたプログラミングモデルを提供します。これにより、効率よく UI を開発できます。
スキャフォールド
スキャフォールドの作成
まず、最新版の Node.js がインストールされていることを確認します。
次のコマンドを入力します。
npm create vue@latest次の内容が表示されます。
✔ Project name: … your-project-name ✔ Add TypeScript? … No / Yes ✔ Add JSX Support? … No / Yes ✔ Add Vue Router for Single Page Application development? … No / Yes ✔ Add Pinia for state management? … No / Yes ✔ Add Vitest for Unit testing? … No / Yes ✔ Add an End-to-End Testing Solution? … No / Cypress / Nightwatch / Playwright ✔ Add ESLint for code quality? … No / Yes ✔ Add Prettier for code formatting? … No / Yes ✔ Add Vue DevTools 7 extension for debugging? (experimental) … No / Yes
Scaffolding project in ./your-project-name... Done.
cd your-project-name
npm install
npm run devプロジェクト構造
次は Vue CLI で作成した Vue プロジェクトの標準的な構造です。
プロジェクトルート
├── node_modules/ // 依存モジュール(自動生成)
├── public/
│ ├── favicon.ico // サイトアイコン
│ └── index.html // プロジェクトのメインページテンプレート。Vue アプリの HTML 基礎で、id="app" の DOM 要素が Vue アプリのマウント先
├── src/
│ ├── assets/ // 画像、スタイルシート、フォントなどの静的リソース
│ ├── components/ // Vue コンポーネントを保存し、コード再利用性を高める
│ ├── App.vue // Vue アプリのルートコンポーネント。UI 構造の最上位にあり、他のコンポーネントはここにネストされる
│ └── main.js // プロジェクトのエントリーファイル。Vue アプリインスタンスを作成し、グローバルプラグインなどを設定して、index.html の指定要素へマウントする
├── .gitignore
├── babel.config.js // 構文変換ツール。新しい JS API を低いバージョンのブラウザでも動くコードへ変換する
├── package.json // プロジェクト設定と依存宣言ファイル。依存、スクリプトコマンドなどを記録する
├── README.md
└── vue.config.js // CLI 設定ファイル。パスエイリアス、プロキシサーバー、ビルド最適化などを設定できるテンプレート構文
テキスト補間
もっとも基本的なデータバインディングはテキスト補間です。「Mustache」構文、つまり二重波括弧を使います。
<template>
<span>Message: {{ msg }}</span>
</template>
<script>
export default {
data() {
return {
msg: "こんにちは"
}
}
}
</script>二重波括弧タグは、対応するコンポーネントインスタンス の msg 属性値に置き換えられます。また、msg 属性が変わるたびに同期して更新されます。
v-model データバインディング(双方向バインディング)
v-model ディレクティブは主にフォーム要素で使い、データの双方向バインディングを実現します。つまり、ユーザーがフォームに入力または選択した値は Vue インスタンスのデータへリアルタイムに反映され、データの変化もフォームへ反映されます。
<div>
<input type="text" v-model="password">
{{ password }}
</div>Vue インスタンスの data に password 変数を定義します。例:data: { password: '' }。ユーザーが入力欄に入力した内容は、下の補間式にも同時に表示されます。
原理:v-model は本質的にシンタックスシュガーです。input 要素では、input イベント発生時にデータを更新し、value 属性にデータをバインドします。
v-if、v-else、v-else-if
v-if ディレクティブは、式の値に応じて要素を条件付きでレンダリングします。式の値が true なら要素は DOM にレンダリングされ、false なら DOM に現れません。
<div v-if="showElement">表示する要素</div>v-else ディレクティブは、必ず v-if または v-else-if の直後に置き、別の条件分岐を提供します。
<div v-if="isTrue">条件が真の時に表示</div>
<div v-else>条件が偽の時に表示</div>v-else-if は複数の条件分岐を追加するために使います。
<div v-if="score >= 90">優秀</div>
<div v-else-if="score >= 80">良好</div>
<div v-else-if="score >= 60">合格</div>
<div v-else>不合格</div>注意:v-if は本当の条件レンダリングです。切り替え時に、要素とその子要素を破棄または再作成します。
v-bind 属性バインディング
v-bind ディレクティブは要素の属性をバインドします。よく使う属性は href、src、class、style などです。
<a v-bind:href="href">検索する</a>Vue インスタンスの data に href 変数を定義します。例:data: { href: 'https://www.example.com' }。すると、a タグの href 属性は指定したリンクになります。
v-bind は : と省略できます。
<a :href="href">検索する</a>v-on: クリックイベント
v-on ディレクティブは click、mouseenter、keyup などの DOM イベントをバインドします。イベントが発生すると、バインドされたメソッドを実行します。
<button v-on:click="functionName">閉じる</button>Vue インスタンスの methods に functionName メソッドを定義します。
methods: {
functionName() {
// ボタンクリック時に実行する処理を書く
console.log('ボタンがクリックされました');
}
}v-on は @ と省略できます。
<button @click="functionName">閉じる</button>v-for
v-for ディレクティブは、配列またはオブジェクトをもとに複数の要素をレンダリングします。配列またはオブジェクトのプロパティを反復し、各要素にテンプレートをレンダリングします。
配列に基づく反復:
<div v-for="item in students" :key="item">{{ item.name }}</div>Vue インスタンスの data に students 配列を定義します。
data: {
students: [{name: '張三さん'},{name: '李四さん'},{name: '王五さん'}]
}上のコードは、students 配列内の各オブジェクトに対して div 要素をレンダリングし、学生名を表示します。
v-for は配列要素のインデックスも同時に取得できます。
<div v-for="(item, index) in usernames" :key="index">{{index+1 + '==>' + item}}</div>Vue インスタンスの data に usernames 配列を定義します。
data: {
usernames: ['張三','李四','王五']
}上のコードは、各 div に要素の番号と値を表示します。
オブジェクトに基づく反復:
<div v-for="(value, key) in userInfo">
{{ key }}: {{ value }}
</div>Vue インスタンスの data に userInfo オブジェクトを定義します。
data: {
userInfo: { name: '小明', age: 20, city: '北京' }
}上のコードは、userInfo オブジェクトの各プロパティに対して div 要素をレンダリングし、プロパティ名と値を表示します。
注意:v-for を使う時は、各要素に一意の :key 属性を与えることが重要です。Vue が DOM を効率よく更新でき、性能が上がります。
ルーティング(Vue Router)
Vue Router は Vue.js 公式のルーティングマネージャーです。次は一つの例です。
import Vue from 'vue';
import VueRouter from 'vue-router';
import Home from './views/Home.vue';
import About from './views/About.vue';
Vue.use(VueRouter);
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
const router = new VueRouter({
routes
});
new Vue({
router,
render: h => h(App)
}).$mount('#app');テンプレートでルートリンクを使います。
<router - link to="/">Home</router - link>
<router - link to="/about">About</router - link>
<router - view></router - view>ルートナビゲーションガード
ルートナビゲーションガードを使うと、ルートへのアクセス権などを制御できます。例:グローバル前置ガード。
router.beforeEach((to, from, next) => {
// ユーザーがログインしているか確認
const isLoggedIn = localStorage.getItem('isLoggedIn');
if (to.meta.requiresAuth &&!isLoggedIn) {
next('/login');
} else {
next();
}
});状態管理(Vuex)
コア概念
- state:アプリの状態です。コンポーネントの
dataに似ています。 - mutations:
stateを変更できる唯一の場所です。同期関数でなければなりません。 - actions:任意の非同期処理を含められます。
mutationsをコミットしてstateを変更します。 - getters:算出プロパティに似ており、
state内のデータを取得します。
簡単な例
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
},
getters: {
getCount(state) {
return state.count;
}
}
});
export default store;コンポーネントで使います。
export default {
computed: {
count() {
return this.$store.getters.getCount;
}
},
methods: {
increment() {
this.$store.commit('increment');
},
incrementAsync() {
this.$store.dispatch('incrementAsync');
}
}
};ライフサイクルフック
Vue インスタンスには複数のライフサイクルフック関数があり、特定の段階でコードを実行できます。例:
new Vue({
data() {
return {
message: 'Hello'
};
},
// Vue インスタンスライフサイクルの最初のフック
// インスタンス初期化後、データ監視と event/watcher イベント設定の前に実行
beforeCreate() {
console.log('Before create');
},
// インスタンス作成完了後に呼ばれる
created() {
console.log('Instance created');
},
beforeMount() {
console.log('Before mount');
},
mounted() {
console.log('Component mounted');
},
beforeUpdate() {
console.log('Before update');
},
updated() {
console.log('Component updated');
},
beforeDestroy() {
console.log('Before destroy');
},
destroyed() {
console.log('Instance destroyed');
}
});コンポーネント化
コンポーネント基礎
コンポーネントは Vue アプリの最も重要な概念の一つです。ページを複数の小さく再利用可能な部分に分けられます。たとえば、簡単な HelloWorld コンポーネントを作ります。
// HelloWorld という名前のコンポーネントを定義
const HelloWorld = {
template: '<div>Hello, World!</div>'
};
// Vue インスタンスでこのコンポーネントを使う
new Vue({
el: '#app',
components: {
HelloWorld
}
});テンプレートでコンポーネントを使います。
<div id="app">
<HelloWorld></HelloWorld>
</div>コンポーネント通信
- props:親コンポーネントから子コンポーネントへデータを渡すために使います。
// 子コンポーネント
const ChildComponent = {
props: ['message'],
template: '<div>{{ message }}</div>'
};
// 親コンポーネントで子コンポーネントを使い、データを渡す
new Vue({
el: '#app',
components: {
ChildComponent
},
data() {
return {
parentMessage: 'Hello from parent'
};
}
});<div id="app">
<ChildComponent :message="parentMessage"></ChildComponent>
</div>