Vue.jsでよく使われる用語まとめ②

# Vue.jsで使用される基本用語について

### Props（プロパティ）

PropsはPropertiesの短縮形。
親コンポーネントから子コンポーネント間で文字列、数値、配列やオブジェクトなどの値を受け渡すことができる。

- 親コンポーネント(App.vue)
```vue
<template>
  <Child message="hello, Vue.js!">
</template>

<script>
import Child from './Child.vue';

export default {
  components: {
    Child,
  },
};
</script>
```

- 子コンポーネント(Child.vue)
```vue
<template>
  <p>{{ message }}</p><!-- hello, Vue.js!が表示 -->
</template>

<script>
export default {
  props: ['message'], 
};
</script>
```

Propsの値を変更したい場合は別の`data`や`computed`を使用して値を反映するようにすること。（以下例はdata使用）

```vue
<template>
  <div>
    <p>{{ nextMessage }}</p>
    <button @click="updateMessage">メッセージを変更する</button>
  </div>
</template>

<script>
export default {
  props: ['message'], 
  data() {
    return {
      nextMessage: this.message, // propsの値をdataに
    };
  },
  methods: {
    updateMessage() {
      this.nextMessage = 'new message!';
    },
  },
};
</script>
```

データの型や必須かどうかなどのバリデーションを設定することが可能なため、予期しないデータの受け渡しを防ぐことができる。

```vue
<script>
export default {
  props: {
    message: {
      type: String,
      required: true,
      default: 'Vue.jsでよく使われる用語まとめ',
    },
  },
};
</script>
```

### Vue Router
SPA（シングルページアプリケーション）のルーティング制御を行うもの。
ページ遷移する際にページ全体を読み込まず済み、不必要な更新がないため遷移がよりスムーズ。

- router.js
```javascript
import VueRouter from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

const router = new VueRouter({
  mode: 'history',
  routes
});

export default router;
```

- main.js
```javascript
import Vue from 'vue';
import App from './App.vue';
import VueRouter from 'vue-router';
import router from './router';

Vue.use(VueRouter);

new Vue({
  render: h => h(App),
  router, 
}).$mount('#app');
```

- App.vue
```vue
<template>
  <div id="app">
    <nav>
      <router-link to="/">Home</router-link> <!-- Homeへのリンク -->
      <router-link to="/about">About</router-link> <!-- Aboutへのリンク -->
    </nav>
    <router-view></router-view> <!-- 現在のルートに対応するコンポーネントを表示 -->
  </div>
</template>

<script>
export default {
  name: 'App',
};
</script>
```

- Home.vue
```vue
<template>
  <h2>Homeページ</h2>
</template>

<script>
export default {
  name: 'Home',
};
</script>
```

- About.vue
```vue
<template>
  <h2>Aboutページ</h2>
</template>

<script>
export default {
  name: 'About',
};
</script>
```
### Vuex

Vue.jsでアプリのデータを管理するためのライブラリ。
アプリ全体の状態を一元管理できるようになるため、コードの可読性・保守性が向上する。
また、アプリケーションの状態を格納し、管理するオブジェクトを`store（ストア）`という。

Vuexの構成要素としては下記のようになっている。

#### State（状態）
アプリケーションの全体で共有されるデータの状態を管理。
すべてのコンポーネントはここから必要なデータを取得する。

#### Mutations（変更）
Stateの変更のみ行う。
状態の変更を同期的に管理するため、いつどのように変更が行われたかを把握することができる。

#### Actions（アクション）
状態変更のトリガー。
非同期処理を含むことができ、Mutationsを呼び出してStateを変更することができる。

#### Getters（ゲッター）
Stateから算出したデータを取得する。
`computed`プロパティと使用方法は近い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3763202/c741a722-d27e-46ab-a243-3898edc53d97.png)

- index.js
```javascript
import Vue from 'vue';
import Vuex from 'vuex';
import module from './modules/module';  // モジュールをインポート
import module2 from './modules/module2';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    module,
    module2
  },
});
```
- module.js
```javascript
const state = {
  id: '',
  mail_address: '',
  count: 0
};

const getters = {
  getId: (state) => {
    return state.id;
  },
  getMailAddress: (state) => {
    return state.mail_address || 'メールアドレスが存在しません';
  },
  getCount: (state) => {
    return state.count;
  },
};

const mutations = {
  set(state, { id, mailAddress, count }) {
    state.id = id;
    state.mail_address = mailAddress;
    state.count = count;
  }
};

const actions = {
  updateUserInfo({ commit }, { id, mailAddress, count }) {
    commit('set', { id, mailAddress, count });
  }
};
export default {
  state,
  mutations,
  actions,
  getters
};
```

- User.vue
```vue
<template>
  <div>
    <h2>ユーザー情報</h2>

    <p>ID: {{ id }}</p>
    <p>Email: {{ mailAddress }}</p>
    <p>Count: {{ count }}</p>

    <p>Email: {{ formattedMailAddress }}</p>

    <button @click="updateUser">ユーザー情報を更新</button>

    <button @click="incrementCount">カウントを増やす</button>
  </div>
</template>

<script>
export default {
  computed: {
    id() {
      return this.$store.state.module.id;
    },
    mailAddress() {
      return this.$store.state.module.mail_address;
    },
    count() {
      return this.$store.state.module.count;
    },
    formattedMailAddress() {
      return this.$store.getters['module/getMailAddress'];
    }
  },
  methods: {
    updateUser() {
      this.$store.dispatch('module/updateUserInfo', {
        id: 'newId',
        mailAddress: 'new@example.com',
        count: this.count + 1
      });
    },
    incrementCount() {
      const newCount = this.count + 1;
      this.$store.commit('module/set', {
        id: this.id,
        mailAddress: this.mailAddress,
        count: newCount
      });
    }
  }
};
</script>

```

### 参考

・[[Vue.js]Vue RouterでSPAのルーティング制御](https://www.distant-view.co.jp/column/5757/#:~:text=Vue%20Router%E3%81%A8%E3%81%AFVue,%E3%81%99%E3%82%8B%E4%BA%8B%E3%81%8C%E5%87%BA%E6%9D%A5%E3%81%BE%E3%81%99%E3%80%82)

・[はじめてのVue Router(基本編)](https://reffect.co.jp/vue/first-time-vue-router)

・[【Vue + vue-cli】vue-routerの基本的な使い方](https://www.dailyupblog.com/web_development/754/)

・[【Vuex】Vuex をざっくり理解](https://qiita.com/kobayashimakoto/items/edf9ffff0c5d695e4fe6)

・[入門者必読、vue.jsの状態管理Vuexがわかる](https://reffect.co.jp/vue/understaind-vue-basic)