laravel10 vue3 typescript で helloworld

途中書きかけのメモ。

laravel10をインスコ

```
cd /var/www/html/
composer create-project laravel/laravel your.club
cd your.club
```

vue3 インスコ

```
npm install
npm update
npm i @vitejs/plugin-vue
cat package.json 
```

vite.config.js

```
import { defineConfig } from 'vite'
import laravel from 'laravel-vite-plugin'
import vue from '@vitejs/plugin-vue' // 追加

export default defineConfig({
  plugins: [
    laravel([
      'resources/css/app.css',
      'resources/js/app.js',
    ]),
    vue(), // 追加
  ]
})
```

resources/js/app.js

```
import './bootstrap'

import { createApp } from 'vue'

import App from './App.vue'
createApp(App).mount('#app')

```

resources/views/welcome.blade.php

```
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel</title>
  @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
  <div id="app"></div>
</body>
</html>
```

resources/js/App.vue
```
<script setup>

import { ref } from 'vue'

const count = ref(0)
const addCount = () => {
    count.value++
}

</script>

<template>
    <button @click="addCount">{{ count }} 回クリックしましたよ！</button>
</template>

```


実行
```
npm run build
```


# ルーターの設定

router.js
```
import { createRouter, createWebHistory } from 'vue-router'
const BASE_URL = '/'

import Home from './components/Home.vue'
import Home2 from './components/Home2.vue'


const routes = [
    {
        path: '/',
        name: 'Home',
        component: Home,
    },
    {
        path: '/home2',
        name: 'Home2',
        component: Home2,
    },

]

const router = createRouter({
    history: createWebHistory(BASE_URL),  // set BASE_URL
    routes
})

export default router

```

app.js
```
import './bootstrap';
import router from './router.js'
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.use(router)
app.mount("#app")

```


components/home.vue
```
<template>
    ほーむ1
</template>

```

components/home2.vue
```
<template>
    ほーむ２
</template>

```

resources/js/App.vue
```
<template>
    App hello
    <router-view></router-view>
</template>

```


ここの `app-component` というのが味噌。
めっちゃハマった。

vue.blade.php


```
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Laravel</title>
  @vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body>
<div id="app">
    <app-component></app-component>
</div>
</body>
</html>

```


web.php
```
Route::get('/{any?}', function () {
    return view('vue');
})->where('any', '^(?!api\/)[\/\w\.-]*');
```

これでルートが有効になる。


# npm run watch 有効にしようぜ

npm run watch が動かない。
以下のようにすれば動く。

```package.json
    "scripts": {
        "dev": "vite",
        "build": "vite build",
        "watch": "vite build --watch"//これ大事
    },

```

# リンク移動しちゃうぜ

```Home.vue
<template>
    Home
    <RouterLink to="/home2">home2</RouterLink><!-- 「/about」へのリンク -->
</template>

<script lang="ts" setup>
</script>

```


```Home2.vue
<template>
    Home2
    <RouterLink to="/">Homeへ移動</RouterLink><!-- 「/」へのリンク -->
</template>

<script lang="ts" setup>
</script>


```

# とりあえず、typescriptで足し算

ref の意味は、 リアクティブということ。
これがないと動的に変更されない。

```Home2.vue
<template>
    <div>
        <span> Count: {{ count }} </span>
        <span style="color: red;"> Double: {{ double }} </span>
        <button style="font-size:18px;font-weight: bold;" @click="increment">+</button>
    </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch , computed } from 'vue'

// リアクティブ変数
const count = ref<number>(0)

// 算出プロパティ
const double = computed<number>(() => count.value * 2)

// 状態を変更し、更新をトリガーする関数
const increment = (): void => {
    count.value++
}

// ウォッチャー
watch(count, (value) => {
    console.log(value)
})

// ライフサイクルフック
onMounted(() => {
    console.log('mounted')
})
</script>

```

# 値をセット

Props で 配列の型を指定し、
withDefaults で 値を入れる。

型は string[] で 配列らしい。

```
<template>
    <div>
        msg: {{msg}}
        <br/>
        labels: {{labels}}
    </div>
</template>

<script setup lang="ts">
export interface Props {
    msg: string
    labels: string[]
}

const props = withDefaults(defineProps<Props>(), {
    msg: 'hello',
    labels: () => ['one', 'two']
})
</script>

```