VueUseでOSのテーマを取得する

のはどうやるんだろう？と思った時の個人的メモです。
今更ながらVueUseとかいう超凄い！超便利！なライブラリを知ったので、手始めにテーマ切り替えを試してみます。Nuxt 3のオートインポートにも対応しているんですって！これはもう使わない手はない！ってことで、行ってみましょう。
↓はデモとVueUseのドキュメントです。

https://cslf-fh.github.io/vueuse-sample/

https://vueuse.org/

# 開発環境

* node.js : v16.17.0
* yarn : 1.22.19

# プロジェクト作成

先ずはNuxtのプロジェクトを作成します。いつもの。

```
npx nuxi init nuxt3-app
cd nuxt3-app
yarn install
```

# ライブラリ等々インストール

今回のメインである``VueUse``、CSSフレームワークの``Tailwind CSS``と豊富なテーマやコンポーネントが魅力的な``daisyUI``をインストールします。

```
yarn add --dev @vueuse/nuxt @vueuse/core @nuxtjs/tailwindcss daisyui
```

``tailwind.config.ts``を作成し、追記。

```
npx tailwindcss init
```

```diff_typescript:tailwind.config.ts
/** @type {import('tailwindcss').Config} */
module.exports = {
  content: [],
  theme: {
    extend: {},
  },
+ plugins: [require('daisyui')],
};
```

``nuxt.config.ts``に追記。

```diff_typescript:nust.config.ts
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
+ modules: ['@nuxtjs/tailwindcss','@vueuse/nuxt'],
});
```

# Nuxtのプロジェクトを編集

OSのテーマを取得し、それを管理するのに``useColorMode``を使用します。この関数は``useStorage``等をラップしているので、自動的に永続化までできちゃいます。楽ちんですね！
属性名には今回``daisyUI``のテーマを使用するので``data-theme``を指定しておきす。

```ts:composables/useTheme.ts
const useTheme = () => {
  const mode = useColorMode({
    storageKey: 'theme',
    attribute: 'data-theme',
    emitAuto: true,
  });
  const { next: changeTheme } = useCycleList(['dark', 'light', 'auto'], {
    initialValue: mode,
  });

  return {
    theme: readonly(mode),
    changeTheme,
  };
};

export default useTheme;
```

```vue:app.vue
<script setup lang="ts">
const { theme, changeTheme } = useTheme();
</script>

<template>
  <Html :data-theme="theme" />

  <button class="btn" @click="changeTheme()">change</button>
</template>
```

以上です。たったこれだけでOSのテーマを取得したり、永続化したりと大変お手軽です！型もしっかり付いていますし、オートインポートもいい感じ！
まだまだたくさんの便利な関数が用意されているので、色々試してみましょう！

# GitHub Pagesにデプロイ

<details>
<summary>備忘録</summary>

リポジトリの``Settings → Pages → Build and deployment → Source``を``GitHub Actions``に設定。

```diff_typescript:nuxt.config.ts
+ const REPOSITORY_NAME = '/<repository-name>/';

// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
  modules: ['@nuxtjs/tailwindcss', '@vueuse/nuxt'],
+ app: {
+   baseURL: REPOSITORY_NAME,
+   cdnURL: `https://<user-name>.github.io${REPOSITORY_NAME}`,
+ },
});
```

```yml:.github/workflows/deploy.yml
name: Deploy to GitHub Pages

on:
  push:
    branches: ['master']
  workflow_dispatch:

permissions:
  contents: read
  pages: write
  id-token: write

concurrency:
  group: 'pages'
  cancel-in-progress: true

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3
      - name: Setup Node
        uses: actions/setup-node@v3
        with:
          node-version: '16'
      - name: Setup Pages
        id: pages
        uses: actions/configure-pages@v1
      - name: Install dependencies
        run: yarn
      - name: Generate static page
        run: NUXT_APP_CDN_URL=https://<user-name>.github.io/<repository-name>/ yarn generate
      - name: Upload artifact
        uses: actions/upload-pages-artifact@v1
        with:
          path: ./.output/public

  deploy:
    permissions:
      pages: write
      id-token: write
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    needs: build
    steps:
      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v1
```

</details>


# さいごに

以下の記事を参考にさせていただきました。感謝！

[VueUse](https://vueuse.org/)
[Nuxt3 + GitHub Pages で ﾎｰﾑﾍﾟｰｼﾞ兼 ﾌﾞﾛｸﾞを作成してみた](https://zenn.dev/kazuhe/articles/nuxt3-githubpages-blog)
[Nuxt3・MicroCMS・Github Pagesを利用してJamStackなWebアプリケーションを作成する](https://blog.isystk.com/web_production/vue/1642/)