Skip to content
This repository was archived by the owner on May 25, 2024. It is now read-only.

Commit 7ca0057

Browse files
authored
migrate to typescript (#226)
* migrate to typescript * chore: add tsconfig of docs * pkg: update @vitejs/plugin-vue * chore: tsconfig include * chore: language mode * chore * chore * chore
1 parent 9c35255 commit 7ca0057

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+4157
-1204
lines changed

.eslintrc.cjs

+7-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
require('@rushstack/eslint-patch/modern-module-resolution')
22

33
module.exports = {
4-
root: true,
5-
env: {
6-
node: true,
7-
'vue/setup-compiler-macros': true
4+
parser: 'vue-eslint-parser',
5+
parserOptions: {
6+
parser: '@typescript-eslint/parser'
87
},
9-
extends: [
10-
'plugin:vue/vue3-recommended',
11-
'eslint:recommended',
12-
'@vue/eslint-config-prettier'
13-
],
8+
root: true,
9+
env: { node: true },
10+
plugins: ['@typescript-eslint'],
11+
extends: ['plugin:vue/vue3-recommended', '@vue/eslint-config-prettier'],
1412
rules: {
1513
'vue/html-closing-bracket-newline': [
1614
'error',

.vscode/settings.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"editor.codeActionsOnSave": {
3-
"source.fixAll.eslint": true
3+
"source.fixAll.eslint": "explicit"
44
},
55
"editor.defaultFormatter": "esbenp.prettier-vscode",
66
"editor.formatOnSave": true,

docs/component.md

+36-61
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# 商品をコンポーネント化する
22

33
## 本章の概要とゴール
4+
45
本章では、1 つ 1 つの商品を表示するコードをコンポーネントとして分離し、再利用できるようにプログラムを改修していきます。
56
本章を実践すると、プログラムの一部を再利用できるコンポーネントとして切り出したり、 `props` を使ってコンポーネントに必要な情報を渡すことができるようになります。
67

@@ -9,7 +10,7 @@
910
Vue.js ではテンプレート、ロジック、そしてスタイルを 1 つのファイルにまとめることで、単一ファイルコンポーネント(`Single File Components`、略称 `SFC`)として利用することができます。`SFC``<script setup>` 内で `import` することで、テンプレートで直接使用することが可能となります。
1011

1112
```vue{2,6}
12-
<script setup>
13+
<script setup lang="ts">
1314
import MyComponent from './MyComponent.vue'
1415
</script>
1516
@@ -33,18 +34,19 @@ import MyComponent from './MyComponent.vue'
3334
<<< @/../examples/event/src/App.vue#script
3435

3536
## 一部をモジュールとして切り出す
37+
3638
モジュールとして切り出す時、どの範囲で切り出すか迷うかもしれません。そのような場合は、再利用可能という観点で考えてみてもよいかもしれません。今回の場合、商品の部分は、`v-for` の中で何度も呼ばれているので、この範囲で切り出してみるのが良さそうです。
3739

3840
### コンポーネントの作成
3941

40-
`Card` コンポーネントとして切り出しますが、`src` ディレクトリの下に新たに `components` ディレクトリを作成し、そこに `Card.vue` ファイルを作成します。今後コンポーネントを新たに作っていく場合は、`components` ディレクトリに格納していくとよいでしょう。作成後は下記のようなディレクトリ構成になっていると思います。
42+
`Card` コンポーネントとして切り出しますが、`src` ディレクトリの下に新たに `components` ディレクトリを作成し、そこに `Card.vue` ファイルを作成します。今後コンポーネントを新たに作っていく場合は、`components` ディレクトリに格納していくとよいでしょう。作成後は下記のようなディレクトリ構成になっていると思います。
4143

4244
```
4345
src
4446
┣━ components
4547
┃ ┗━ Card.vue
4648
┣━ App.vue
47-
┗━ main.js
49+
┗━ main.ts
4850
```
4951

5052
次にいよいよモジュールを切り出す作業に入ります。以下のハイライト部分を `Card.vue` に移します。また、`pricePrefix()` や関連する `style` も一緒に移します。
@@ -66,26 +68,23 @@ src
6668
#### Card.vue
6769

6870
```vue
69-
<script setup>
70-
/**
71-
* 価格を3桁ごとのカンマ付きで返す
72-
* @param {number} price 価格
73-
*/
74-
function pricePrefix(price) {
71+
<script setup lang="ts">
72+
/** 価格を3桁ごとのカンマ付きで返す */
73+
function pricePrefix(price: number): string {
7574
return price.toLocaleString()
7675
}
7776
</script>
7877
7978
<template>
8079
<div class="thumbnail">
81-
<img
82-
:src="item.image"
83-
alt="">
80+
<img :src="item.image" alt="" />
8481
</div>
8582
<div class="description">
8683
<h2>{{ item.name }}</h2>
8784
<p>{{ item.description }}</p>
88-
<span>¥<span class="price">{{ pricePrefix(item.price) }}</span></span>
85+
<span
86+
>¥<span class="price">{{ pricePrefix(item.price) }}</span></span
87+
>
8988
</div>
9089
</template>
9190
@@ -118,6 +117,7 @@ function pricePrefix(price) {
118117
```
119118

120119
## Card コンポーネントを使用する
120+
121121
切り出しができたので、作成したコンポーネントを `App.vue` で使えるようにしましょう。
122122

123123
#### App.vue / template
@@ -146,7 +146,7 @@ function pricePrefix(price) {
146146
#### App.vue / script
147147

148148
```vue{3}
149-
<script setup>
149+
<script setup lang="ts">
150150
import { ref } from 'vue'
151151
import Card from './components/Card.vue'
152152
@@ -185,42 +185,24 @@ import Card from './components/Card.vue'
185185
#### Card.vue / script
186186

187187
```vue{2-23}
188-
<script setup>
189-
defineProps({
190-
name: {
191-
type: String,
192-
default: '',
193-
required: false
194-
},
195-
description: {
196-
type: String,
197-
default: '',
198-
required: false
199-
},
200-
price: {
201-
type: Number,
202-
default: 0,
203-
required: false
204-
},
205-
image: {
206-
type: String,
207-
default: '',
208-
required: false
209-
},
210-
});
188+
<script setup lang="ts">
189+
defineProps<{
190+
name: string
191+
description: string
192+
price: number
193+
image: string
194+
}>()
211195
212196
// 省略
213197
214198
</script>
215199
```
216200

217-
`defineProps` の中に受け取る `props` を書いていきます。`type` は型、`default` は初期値、`required` は必須要素を表しています。
218-
219201
::: tip ヒント
220202
`defineProps` とこのあと紹介する `defineEmits``<script setup> ` 内でのみ使用可能なコンパイラマクロとなっているため、`import` する必要はありません。
221203
:::
222204

223-
### App.vueから値を渡す準備をする
205+
### App.vue から値を渡す準備をする
224206

225207
`Card.vue``defineProps` で定義した値を `template` 内で渡していきます。
226208

@@ -260,6 +242,7 @@ defineProps({
260242
`Card` コンポーネントでは `pricePrefix` 関数を使用しています。このように、同じコンポーネント内で処理が完結している場合はよいですが、呼び出されている親のコンポーネントの関数を実行したい時があります。今回は例として、`Card` コンポーネントに「売り切れ」のボタンを作成し、クリックすると非表示になる、という処理を追加してみます。
261243

262244
### Card コンポーネントで emits の定義をする
245+
263246
Vue.js では `emits` オプションが使えます。`emits` オプションは、子のコンポーネント内で親のコンポーネントに発行できるイベントを定義できます。
264247

265248
今回では子のコンポーネントで「売り切れ」のイベントを発行して、親のコンポーネントで `items` を書き換える、という流れになります。現状では `Card` コンポーネントは渡された情報を表示するのみで、どの `item` か特定できる情報がないので、`id` も渡すように修正します。`defineProps` も忘れず修正しましょう。
@@ -278,22 +261,14 @@ Vue.js では `emits` オプションが使えます。`emits` オプション
278261
#### Card.vue / script
279262

280263
```vue{3-7}
281-
<script setup>
282-
defineProps({
283-
id: {
284-
type: Number,
285-
default: null,
286-
required: false
287-
},
288-
name: {
289-
type: String,
290-
default: '',
291-
required: false
292-
},
293-
294-
// 省略
295-
296-
})
264+
<script setup lang="ts">
265+
defineProps<{
266+
id: number
267+
name: string
268+
description: string
269+
price: number
270+
image: string
271+
}>()
297272
298273
// 省略
299274
@@ -303,15 +278,15 @@ defineProps({
303278
`<script setup>` の中で `emits` を使用するためには `defineEmits` の API を使用します。`defineProps` と同様に `<script setup>` の中で自動的に使えるようになっているため、`import` は不要です。
304279

305280
```vue{9}
306-
<script setup>
281+
<script setup lang="ts">
307282
308283
// 省略
309284
310-
function pricePrefix(price) {
285+
function pricePrefix(price: number): string {
311286
return price.toLocaleString()
312287
}
313288
314-
const emit = defineEmits(['sold-out'])
289+
const emit = defineEmits<{ 'sold-out': [id: number] }>()
315290
</script>
316291
```
317292

@@ -345,11 +320,11 @@ const emit = defineEmits(['sold-out'])
345320
`Card` コンポーネントには `sold-out``emits` を受け取った場合に `changeSoldOut` が実行されるように設定しました。次に、実行される `changeSoldOut` を定義します。
346321

347322
```vue{5-8}
348-
<script setup>
323+
<script setup lang="ts">
349324
350325
// 省略
351326
352-
function changeSoldOut(id) {
327+
function changeSoldOut(id: number) {
353328
const pickElm = items.value.find(item => item.id == id)
354329
pickElm.soldOut = true
355330
}

docs/create.md

+9-4
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@
3131
Ok to proceed? (y) -> y
3232
```
3333

34-
以降の質問には、基本的に `No` を選択して進めます。
34+
以降の質問には、基本的に `No` を選択して進めます。\
35+
TypeScript だけは `Yes` を選択しましょう。
3536

3637
::: tip ヒント
3738
矢印キーでアンダースコアを移動させることで項目を選択します。
@@ -40,7 +41,7 @@
4041

4142
```
4243
Vue.js - The Progressive JavaScript Framework
43-
? Add TypeScript? › No / Yes -> No
44+
? Add TypeScript? › No / Yes -> Yes
4445
? Add JSX Support? › No / Yes -> No
4546
? Add Vue Router for Single Page Application development? › No / Yes -> No
4647
? Add Pinia for state management? › No / Yes -> No
@@ -86,6 +87,9 @@
8687
├── node_modules
8788
├── package-lock.json
8889
├── package.json
90+
├── tsconfig.app.json
91+
├── tsconfig.json
92+
├── tsconfig.build.json
8993
├── public
9094
│   └── favicon.ico
9195
├── src
@@ -104,8 +108,9 @@
104108
│   │   ├── IconEcosystem.vue
105109
│   │   ├── IconSupport.vue
106110
│   │   └── IconTooling.vue
107-
│   └── main.js
108-
└── vite.config.js
111+
│   ├── main.ts
112+
│   └── vite-env.d.ts
113+
└── vite.config.ts
109114
110115
6 directories, 19 files
111116
```

docs/event.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ Vue.js でイベントリスナーを登録するには `v-on` というディ
138138
```
139139

140140
```vue
141-
<script setup>
141+
<script setup lang="ts">
142142
// ...省略
143143
144144
function alertDialog() {

0 commit comments

Comments
 (0)