【初心者向け】Vuetify3+Firebaseでホームページを作って無料で公開してみた。

※ 当サイトではアフィリエイト広告を利用しています。リンクは広告リンクも含みます。

この記事は約23分で読めます。
広告

Vuetify3で作ったホームページをXFREE、Firebase Storage、Firebase Hostingの3つのやり方で無料で公開してみました。
Vuetifyは、Vue.jsのUIライブラリーで結局Html、Css、Javascriptになるのですが、コードを簡単にかけるようなパーツになっています。XFREEは、無料レンタルサーバー。Firebaseは、Googleが提供するクラウドサービス。その中のStorageはファイルをアップロードしたら一般公開できるものです。アップロードしたファイルを一般公開するのは他にもあると思いますが、公開したファイルは大概、パソコンのどこかのフォルダにダウンロードされるタイプです。このXFREEやFirebase Storageは、そうではなくWEBに表示します。こういうタイプでないとホームページの表示には使えません。Firebase StorageとFirebase Hostingの違いはHostingは独自のドメインがつくことです。以下の完成品でurlの違いを確認してください。
Node.jsがインストールされている環境が必要です。Vuetify3のインストールから手順を紹介します。

完成品(全部同じ見た目です。)
XFREE版 Firestorage+Vuetify3で作ったホームページ
Firebase Storage版 Firestorage+Vuetify3で作ったホームページ
Firebase Hosting版 Firestorage+Vuetify3で作ったホームページ
Node.jsが必要です。Windows11の場合、下の記事で環境がそろいます。

広告

Vuetify3準備

ここのVuetifyの章でVSCodeを立ち上げまで実行してください。
コードを書いていきます。
デフォルトでできるHelloWorld.vueコンポーネントを置き換えるだけで作ります。

public/index.html
<html lang="en">→<html lang="ja">にしておくとアプリを開いたときブラウザが翻訳するか?とたずねてこなくなります。
タブに表示する文字は以下で設定
<title>Firestorage+Vuetifyで作った掲示板</title>
<template>
  <v-app>
    <v-main>
      <!-- <HelloWorld /> -->
      <FrontEnd/>
    </v-main>
  </v-app>
</template>

<script setup>
  // import HelloWorld from '@/components/HelloWorld.vue'
  import FrontEnd from '@/components/FrontEnd.vue'
</script>

vuetify3のメイン部分

src/components/FrontEnd.vueを新規追加
wireframesでExtended Toolbarをクリックするとコードを実行したときの画面が表示されます。右下にあるGitHub(猫のマーク)をクリックするとコードが見れます。そのコードをFrontEnd.vueにコピペします。

yarn devで実行するとExtended Toolbarが表示されます。
CTRL+Cで停止

タイトル部分修正

各タブにはAPI(Props)があります。これはhtmlの属性と同じようなものです。その値で設定がかえられます。
extendedPropsがあると高さが大きくなるので削除します。
app-barのDensityに同じよな例があるので、そのコードを見ると色の指定がcolor=”primary”となっています。コピペすると色が変わります。primaryというのは色を別名で定義しています。(背景色の項を参照してください。)どこで定義してるかは見つからないですがcolorsのMaterial Colorsで実物の色を確認するとblue-darken-3です。primaryをblue-darken-3に変えても同じです。

      <v-app-bar
        app
        color="primary"
      >

タイトルを変更しセンターにします。
v-spacerはv-app-barにある要素同士がくっつかないようにスペースを確保する役割があります。削除しないとセンターにならない。右側のボタン(v-btn)も使わないので削除します。
※html(<template>)部分は<!–コメントアウト–>で囲むと囲まれた部分はコメントアウト(削除と同じ)になります。
TypographyのサンプルのGitHubでclassにtext-h1(数字が小さいほうが大きい文字)を入れればよさそうなので調整してtext-h4にした。

        <v-toolbar-title class="text-center text-h4">Firestore+Vuetify3で作ったホームページ</v-toolbar-title>
         <!-- <v-spacer></v-spacer> -->
        <!-- <v-btn icon>
          <v-icon>mdi-dots-vertical</v-icon>
        </v-btn> -->
      </v-app-bar>
目次へ

ナビゲーションボタン

ここからVue.jsの内容が関わってきますが、その説明は省略します。Vue.jsの部分は、そんなものだと思って先に進めてください。Vue.jsは、こちらを参考にしてみてください。

navigation drawerのbottom drawerのGitHubをクリックしてコードを見ます。その中から必要な部分だけコピーします。
※GitHubには<script setup></script>と<script></script>という2種類の書き方が連続して載っているので注意してください。古い書き方ですがネットの情報が多いため<script></script>を使います。
※Javascript(<script>)は//がコメントアウトです。
略
        <!-- <v-app-bar-nav-icon></v-app-bar-nav-icon> -->
        <v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
        <v-toolbar-title class="text-center text-h4">Firestore+Vuetify3で作ったホームページ</v-toolbar-title>
      </v-app-bar>
      </v-app-bar>
      <v-navigation-drawer
        v-model="drawer"
        location="bottom"
        temporary
      >
        <v-list
          :items="items"
        ></v-list>
      </v-navigation-drawer>
      <v-main>
略
<script>
  export default {
    data: () => ({
      drawer: false,
   //   使ってないgroup: null,
      items: [
        {
          title: 'Foo',
          value: 'foo',
        },
        {
          title: 'Bar',
          value: 'bar',
        },
        {
          title: 'Fizz',
          value: 'fizz',
        },
        {
          title: 'Buzz',
          value: 'buzz',
        },
      ],
    }),

    watch: {
      group () {
        this.drawer = false
      },
    },
  }
</script>

実行すると下のほうに文字がでます。これを上に持っていきます。v-navigation-drawerを見ると英語の説明で分かりずらいですが、location=”bottom”が怪しいので”top”に変えてみます。実行すると上に来ています。
左のハンバガーメニューの動作はBingに以下のように質問してみます。

解説して <v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>
v-app-bar-nav-iconは、Vuetifyのコンポーネントで、アプリバーの左側に表示されるアイコンを表します。
variant="text"は、アイコンの色をテキストと同じ色にするプロパティです。
@click.stopは、クリックイベントの伝搬を止めるための修飾子です。
つまり、以下のように記述されている場合、左側にテキストとして表示されるアイコンがクリックされた時に、drawerプロパティがトグルされます。
<v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>

簡単にいうとクリックするたびにdrawerがfalse/trueで切り替わります。
ドロワーの開閉はv-navigation-drawerコンポーネントのv-modelでバインド(変数の変化を監視する役目)したデータ(drawer)で開/閉制御します。<v-app-bar-nav-iconのほうでクリックされるごとにdrawerの値を切り替えています。
目次へ

リストやタブにリンクをつける

ハンバーガーメニューリストにリンクを付けます。
ListsのUsageにあるコードをコピペします。v-list-itemのPropsを見るとhrefがあるので、これを追加して使います。

        <!-- <v-list
          :items="items"
        ></v-list> -->
    <v-list lines="one">
        <v-list-item
            v-for="item in items"
            :key="item.title"
            :title="item.title"
            :href="item.href"
        ></v-list-item>
    </v-list>
略
      items: [
        {
          title: 'Django基本完成品関連記事',
        //   value: 'foo',
          href:'https://kikuichige.com/8511/'
        },
解説:
v-for="item in items"
            :key="item.title"
            :title="item.title"
            :href="item.href"
はitemsから1個づず取り出して表示しています。
hrefでハイパーリンクになりクリックしたらそのURLを表示します。
:keyはitemの中の代表値を設定しておきます。item.hrefやitemだけでも動きますし。以下のような書き方もよくあります。
v-for="(item, i) in items"
            :key="i"
どれが正解かはわかりませんがVuetify3はkeyがないとエラーになります。Vuetify2はなくてもよかった。

タイトル下のメニューはTabsの中のCenter Activeを使用します。GitHubの<v-card></v-card>で囲まれた部分をコピペ。リンクはv-tabのhrefを使えばハイパーリンクになります。どこにも載っていませんが試しにtarget=”_blank”を使ったら別タブで開きます。
目次へ

カードの中に画像、テキスト、ボタンを入れる

カードの配置はグリッドシステムを参照してください。
もともとv-forでv-colが24個作られているので、これを3個のv-colにして、その中にcardを入れます。
CardsのBasicsには3つの書き方が書いてあります。With markupの書き方を参考にimgとボタンもつけました。

marginはclassで指定しclass=”mb-4″のようになります。
先頭のmがmargin、paddingの時はp。2文字目は方向を表します。tはtop、bはbottom、lはleft、rはrightです。最後の数字は4pxが1になります。4は4×4pxで16pxです。詳細はspacing

フッター

フッターはFootersのcompany footerを使います。
ボタンにハイパーリンクをつけるにはVBtn APIにhrefがあるので、それを使う。前述のv-listではtitleというPropsがあったがv-btnにはないので{{ link.title }}のような書き方になる。
目次へ

背景色

Theme configurationにテーマの変更の仕方が載っています。テーマとは設定できる変数に具体的な数字を入れているところです。
例えばcolor=”primary”とタグで使っていたprimayの具体的な色の番号を設定しています。node_modules\vuetify\lib\composables\theme.mjsにあります。
(試しに、ここで変えても反映されませんでした。ここは変えないほうがいいと思います。)
lightとdarkの2種類のセットがあってデフォルトはlightです。

Theme configurationではテーマをvuetify.jsでカスタマイズしていますがvuetify.jsを見たらprimaryとかの色が設定されていたので、試しにbackgroundを追加して実験したら変わりました。

src\plugins\vuetify.jsの以下の位置にbackground: 色,を追加すれば変わります。
export default createVuetify({
  theme: {
    themes: {
      light: {
        colors: {
          background: '#000000',
          primary: '#1867C0',
          secondary: '#5CBBF6',
なぜデフォルトのvuetify.jsでprimary、secondaryが変更されていたのかわかりませんが、試しにprimaryを消したら、theme.mjsで設定されている色primary: '#6200EE',に変わったので、基本はtheme.mjsで設定されている色です。
目次へ

ビルドして公開

ビルドします。(ビルドとはHtml、Css,Jsに変換することです。woff、eot、ttf、woff2というのができますが、なくても動きました。)
yarn build

ローカルで実行するとエラーになる

distフォルダに公開するファイルがすべてそろいます。しかし修正が必要な点が3個ありますので原因と対策を書きに記します。

①ハンバーガーメニューや<>のアイコンが表示しない。
原因はビルドしたときアイコンを表示するために必要なmaterialdesignicons.min.cssが読み込まれていないようです。ビルド後のindex.htmlで読み込むようにしました。
dist/index.htmlに以下追加
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">

参考https://nkeke0.hatenablog.com/entry/2021/07/09/111307

②パスが間違っている以下修正。
<head>
  <meta charset="UTF-8" />
  <link rel="icon" href="/favicon.ico" />→<link rel="icon" href="favicon.ico" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Firestore+Vuetifyで作ったホームページ</title>
  <script type="module" crossorigin src="/assets/index-7b5e6b89.js"></script>
→<script type="module" crossorigin src="./assets/index-7b5e6b89.js"></script>
  <link rel="stylesheet" href="/assets/index-937c0959.css">
→<link rel="stylesheet" href="./assets/index-937c0959.css">
</head>

③jsファイルがCORS policy違反(ローカルでindex.htmlをダブルクリックすると発生)
しかしjsが読み込めない。コンソールを見ると青色のプロトコルと違うfileというプロトコル(origin 'null'の原因)で開いているため、CORS policyに違反しているというエラーです。
Access to script at 'file:///C:/Users/taka3/vuetify3/vuetify-storage/dist/assets/index-7b5e6b89.js' from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome-untrusted, https, edge.

なのでhttpプロトコルを使っているXFREEにdistフォルダのファイルをアップロードします。woff、eot、ttf、woff2は不要です。html、css、jsだけでいいです。
完成品 Firestore+Vuetify3で作ったホームページ
目次へ

Firebase Storageで公開する方法

ビルドしたものをFirebase Storageで公開します。上でindex.htmlを修正した部分の①以外は関係ありません。
Firebase Storageの使い方は、こちらを参照してください。懸念点も書いてあるのでご一読を。

assetsにあるcssとjsファイルとfavicon.icoをStorageにアップロードします。
アップロードした各ファイルをクリックし右に表示する名前を右クリックしてリンクをコピーしてdist/index.htmlの対応するところに貼り付けます。webfrontloader~.jsはアップロードしたけどいらないみたいなので消しました。

上の①ハンバーガーメニューや<>のアイコンが表示しない。だけ対策します。

index.htmlを以下のように書き換えたらアップロードして完了です。
<head>
  <meta charset="UTF-8" />
  <link rel="icon" href="/favicon.ico" />→<link rel="icon" href="https://firebasestorage.googleapis.com/v0/b/storage-681e6.appspot.com/o/storage_dist%2Ffavicon.ico?alt=media&token=0091111-d8c8-4ff7-aa22-82cc7a8fe09e" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Firestore+Vuetifyで作ったホームページ</title>
  <script type="module" crossorigin src="/assets/index-7b5e6b89.js"></script>
→<script type="module" crossorigin src="https://firebasestorage.googleapis.com/v0/b/storage-681e6.appspot.com/o/storage_dist%2Fassets%2Findex-7b5e6b89.js?alt=media&token=1c3f0cb4-09fa-4z68-bb10-dc25b45fce9f"></script>
  <link rel="stylesheet" href="/assets/index-937c0959.css">
→<link rel="stylesheet" href="https://firebasestorage.googleapis.com/v0/b/storage-681e6.appspot.com/o/storage_dist%2Fassets%2Findex-937c0959.css?alt=media&token=f5918573-0116-4129-9a86-57712593c7bc">
 <link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
</head> 

Firebase StorageにアップロードしたものFirestore+Vuetify3で作ったホームページ
目次へ

Firebase Hostingで公開する

Firebase Storageの関数を使って表示する

Storageから画像のリンク先を取得する関数を使って画像表示するように変更します。上のままでもいいかもしれませんが、ドキュメントに書いてあるStorageの使い方でやってます。
画像ファイルをStorageにアップロードしてください。以下の初期設定のところを実施してください。

yarn add firebaseを実行していなかったら実行してください。

アプリがないとconst firebaseConfig = に設定するstorageBucket: がないのでアプリを追加します。以下のようにしてください。アプリのニックネームを入力→アプリを登録→そこに出ている手順は別途やっていくので×で閉じる。

FrontEnd.vueに追加したところ
<template>
略
<v-img class="mt-4 mx-5 mb-4" v-bind:src="image_urls[0]"></v-img>  
略
<v-img v-bind:src="image_urls[1]" max-height="200" class="mt-4"></v-img> 
略
<v-img v-bind:src="image_urls[2]" max-height="200" class="mt-4"></v-img>
略
<v-img v-bind:src="image_urls[3]" max-height="200" class="mt-4"></v-img> 
略
<script>
  import { initializeApp } from "firebase/app";
  import { getStorage } from "firebase/storage";
  const firebaseConfig = {
    storageBucket: '****'
  };
  const app = initializeApp(firebaseConfig);
  const storage = getStorage(app);
  import { ref ,getDownloadURL } from "firebase/storage";
  export default {
    data: () => ({
      image_names:["header","usuyuki","komakusa","siogama"],
      image_urls:[],
略
    },
    async created(){
      for (let i = 0; i < this.image_names.length; i++) {
              await getDownloadURL(ref(storage,'ichige_portfolio/img/'+this.image_names[i]+'.jpg'))
              .then((url) => {
                this.image_urls.push(url);
                console.log('image_urlは',this.image_urls[i]);
              })
              .catch((error) => {
                // Handle any errors
              });
            }
            
    }
  }
</script>

Hosting

以下にHostingのやり方があります。

完成品 HostingしたFirestore+Vuetify3で作ったホームページ
こちらは個別のドメインが割り与えられています。
画面表示はまったく同じですが先ほどのStorageにindex.htmlなどを手動でFirebase StorageにアップロードしたものFirestore+Vuetify3で作ったホームページはStorageのindex.htmlへのリンクとなっている点が違います。
結局、何が違うかというとHostingしないほうは、こういう使い方していいのという漠然とした不安があります。あとHostingのほうはGoogle検索に載せてくれるかも。Googleの検索窓に「site:調べたいURL」と入力して検索するだけで、インデックスされているかどうかチェックできます。
site:で調べた結果はクリックしないでください。ウィルスサイトがコンテンツとして利用している場合が多いので検索結果にウイルスサイトが出てきます。

今回のページの場合、site:storage-681e6.web.app
デプロイ直後なので「site:storage-681e6.web.app に一致する情報は見つかりませんでした。」と出ました。Google Search Consoleで積極的に登録したらどうなるかも、そのうち実験してみます。Google  Search Consoleについては↓↓
目次へ

あとがき

細かく解説しようとしましたが途中からだいぶ省略してます。
目次へ

イチゲをOFUSEで応援する(御質問でもOKです)Vプリカでのお支払いがおすすめです。
Vプリカでのお支払いがおすすめです。

MENTAやってます(ichige)

コメント

タイトルとURLをコピーしました