LoginSignup
6
5

More than 3 years have passed since last update.

Vue.js + TypeScript覚え書き

Last updated at Posted at 2020-07-28

概要

Vue.js + TypeScriptに関する覚書。インストールオプション等は後で変えるかもしれません。

バージョン

  • Node.js : 12.18.1
  • TypeScript(tsc) : 3.9.3
  • vue : 2.6.11
  • vue-router : 3.2.0
  • VueCLI(@vue/cli) : 4.4.6
  • axios : 0.18.0
  • element-ui : 2.4.5

プロジェクト作成と起動

$ vue create training
================================================
Vue CLI v4.4.6

### TypeScriptを使うためManuallyを選ぶ
? Please pick a preset: (Use arrow keys)
  default (babel, eslint)
? Manually select features

### 「TypeScript」「Router」を選択
? Check the features needed for your project:
 ◯ Babel
 ? TypeScript
 ◯ Progressive Web App (PWA) Support
 ? Router
 ◯ Vuex
 ◯ CSS Pre-processors
 ◯ Linter / Formatter
 ◯ Unit Testing
 ◯ E2E Testing

### Noを選択(class-styleではなくVue.Extendを使った記法にする)
### https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121
? Use class-style component syntax? (Y/n) n

### Noを選択(自動検出されたポリフィルにBabelとTypeScriptを使用しないため)
### ポリフィル : 古いブラウザーで、最近機能を使えるようにするためのコード
### https://developer.mozilla.org/ja/docs/Glossary/Polyfill
### https://www.sejuku.net/blog/100946
? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? n

### Yesを選択(Historyモードを使う。Hashモードは若干速くなるがURLに「#」が入る)
### https://qiita.com/kozzzz/items/af9ad63fa70d4724cc2a
? Use history mode for router? (Requires proper server setup for index fallback in production) (Y/n) Y

### 「In package.json」を選択(パッケージを全てpackage.jsonで管理するため)
? Where do you prefer placing config for Babel, ESLint, etc.?
  In dedicated config files
? In package.json

### Noを選択(毎回プロジェクトを作成する毎に設定を選ぶため)
? Save this as a preset for future projects? (y/N) n

### 起動
$ cd training
$ npm run serve
================================================

初期のディレクトリ構造

training
|-- README.md
|-- node_modules
|-- package-lock.json
|-- package.json
|-- public
|   |-- favicon.ico   # ファビコン
|   `-- index.html    # index.htmlのテンプレート
|-- src
|   |-- App.vue
|   |-- assets        # webpackに処理されるアセットを格納するディレクトリ
|   |   `-- logo.png
|   |-- components
|   |   `-- HelloWorld.vue
|   |-- main.ts
|   |-- router
|   |   `-- index.ts
|   |-- shims-tsx.d.ts
|   |-- shims-vue.d.ts
|   `-- views
|       |-- About.vue
|       `-- Home.vue
`-- tsconfig.json
  • /public
  • /src
    • App.vue
      • アプリケーション全体で使うナビゲーションをここで設定
      • viewsディレクトリに格納したページデータはApp.vueを通して表示する
    • /components
      • 単一ファイルコンポーネント(.vueなど)を格納
      • アプリケーション内で何度も使うようなパーツを入れる
    • main.ts
      • Vueの基本設定ファイル。App.vueをhtmlに紐付ける。
    • /router/index.ts
      • ルーティングを設定
      • VueリソースのURLやURLに紐づくコンポーネント等を設定
    • shims-tsx.d.ts
      • IDEでjsx syntaxsupportを有効にして、JSXスタイルのTypeScriptコードを記述できる
      • 実は末尾がd.tsで終わるファイルであればファイル名は何でも良い
    • shims-vue.d.ts
      • VueファイルをTypeScriptで利用可能とするファイル
      • webpackを使わない場合 import Foo from "./Foo.vue"; はTypeScriptはモジュールであることを理解できない
      • 実は末尾がd.tsで終わるファイルであればファイル名は何でも良い
    • /views
      • ページデータの(.vueなど)を格納する

ファイルの内容

/src/App.vue

<template>
  <div id="app">
    <div id="nav">
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

image.png

/src/view/About.vue

<template>
  <div class="about">
    <h1>This is an about page</h1>
  </div>
</template>

image.png

  • 一番上に「App.vue」のtemplateが出力されている
  • その下に「About.vue」のtemplateが出力されている

/src/view/Home.vue

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">  ロゴを表示
    <HelloWorld msg="Welcome to Your Vue.js App"/> ※1
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'Home',    // nameは自身のファイル名から.vueを除いたものをつける?
  components: {
    HelloWorld
  }
}
</script>
  • ※1
    • HelloWorldコンポーネントを出力
    • msgには「Welcome to Your Vue.js App」の文字列が入る

/src/components/HelloWorld.vue

<template>
  <div class="hello">
    <h1>{{ msg }}</h1>      // 「Home.vue」でmsgに代入した値が入る
    <p>
      For a guide and recipes on how to configure / customize this project,<br>
      check out the
      <a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
    </p>
    <h3>Installed CLI Plugins</h3>
    <ul>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
      <li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
    </ul>
    <h3>Essential Links</h3>
    <ul>
      <li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
      <li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
    </ul>
    <h3>Ecosystem</h3>
    <ul>
      <li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
      <li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
      <li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
      <li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
    </ul>
  </div>
</template>

<script lang="ts">
import Vue from 'vue';

export default Vue.extend({
  name: 'HelloWorld',    // nameは自身のファイル名から.vueを除いたものをつける?
  props: {               // 親コンポーネントから子コンポーネントにデータを受け渡す
    msg: String,
  },
});
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
  margin: 40px 0 0;
}
ul {
  list-style-type: none;
  padding: 0;
}
li {
  display: inline-block;
  margin: 0 10px;
}
a {
  color: #42b983;
}
</style>

image.png

  • props(プロパティ)
    • 親コンポーネント(App.vue)から子コンポーネント(HelloWorld.vue)にデータを受け渡すときに使う
    • 流れ
      • 子コンポーネント(HelloWorld.vue)のscriptタグ内でプロパティ名を列挙
        • ここでは msg: String のみ
      • 子コンポーネント(HelloWorld.vue)のtemplateタグ内でプロパティを記載
        • ここでは <h1>{{ msg }}</h1>
      • 親コンポーネント(Home.vue)のtemplateタグ内で子の呼び出しとデータの受け渡し
        • ここでは <HelloWorld msg="Welcome to Your Vue.js App"/>

/src/router/index.ts

import Vue from 'vue'
import VueRouter, { RouteConfig } from 'vue-router'
import Home from '../views/Home.vue'

Vue.use(VueRouter)

  const routes: Array<RouteConfig> = [
  {
    path: '/',
    name: 'Home',
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  }
]

const router = new VueRouter({
  mode: 'history',             // historyモードで利用
  base: process.env.BASE_URL,
  routes
})

export default router

/src/main.ts

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

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

単語帳

6
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
5