Open5

Vite+Vue3(Composition API)の環境構築から途中経過備忘録

soba8soba8

yarn run devではエラーにならないがyarn run buildするとエラーになる件。

有名なのだとaws-amplify.js入れたあとに

'request' is not exported by __vite-browser-external, imported by node_modules/@aws-sdk/....../remoteProvider/httpRequest.js
file: /myproject/node_modules/@aws-sdk/......./remoteProvider/httpRequest.js:4:9
2: import { ProviderError } from "@aws-sdk/property-provider";
3: import { Buffer } from "buffer";
4: import { request } from "http";
                   ^

とか出る。aws-amplifyの場合は対処方法の案内がAmplify UIにある。
https://ui.docs.amplify.aws/getting-started/installation?platform=vue

soba8soba8

Vue3+Vite環境へのEslint導入絡みで

/myproject/src/App.vue
  3:1  error  Parsing error: '>' expected

なんて出る。

.eslintrc.jcの以下の一文が適切に設定されてなかった

{
  "parser": "vue-eslint-parser"
}

トップレベルでparserパラメータを指定する必要がある。parserOptionsにもparserというパラメータ指定があるので、間違ってここに指定しなまわない事。
つまり正しくは以下のようになる。

module.exports = {
    ︙
    "parser": "vue-eslint-parser",
    "parserOptions": {
        "parser": "@typescript-eslint/parser",
        "sourceType": "module",
        'extraFileExtensions': ['.vue',],
 },
}
soba8soba8

Vue3 + Vite環境内でbackground-image: url( /myassets/image.jpg ) を正しく設定する。
Viteを使った画像ファイル読み込みのテクニックで、importを経由させる事でdevとprodの環境差異を吸収させる方法がある。<v-img>とかの場合は<v-bind :src="imageUrl">等で、srcをv-bindさせる。

今回はcssのbackground-imageで指定したかったが、やり方が分からず結構彷徨ったのでメモ。
background-imagは読み込ませる画像のパスをCSS関数のurl()を使って指定する必要がある。
この時、imoprt経由で画像パスを変数化したものを、url()で指定する方法でハマった。通常の画像パスの場合、指定方法は以下の通り

background-image: "url(src/image/image.jpg)";

この時、import経由で変数化した変数を指定するのに、以下のようにした。

Import imagePath from '@/image/image.jpg';

~~~ 以下CSS ~~~
.backgroun {
    background-image: "url(imagePaath)"
}

やってみるとうまく行かず。。結論以下のようにする必要があった。

Import imagePath from '@/image/image.jpg';

~~~ 以下CSS ~~~
.backgroun {
    background-image: "url(" + imagePaath + ")"
}

つまり、imagePathの変数はトランスコンパイルでjs化するタイミングで実際の画像が配置された場所を示す文字列に変換され、cssとしては"url(" + src/image/image.jpg + ")"のような形で読み込まれる。逆にダブルクォーテーションで囲んでしまうと変数として認識されない。

soba8soba8

国籍選択について

結局、一旦国旗は入れず文字のみで対応。
Vuetify3で、slotを使えば簡単に実現できそうだったけど、なぜかitemsに渡す変数をObjectにすると、キーの中身が参照できない。

<v-select :items="countries">
  <template v-slot:item="{ item }">
     {{ item.name }}   
  ↑ 中身が参照出来ない。selectは渡した数だけ<option>を生成してるっぽいのでcountriesは
  ちゃんと渡ってるみたい。リアクティブの影響?
  </template>
</v-select>

<scritp>
export default {
  data: () => ({
    countries: [{ name: "日本", name: "ブラジル" }]
  })
}
</script>

これがうまく行かない。

検討

次に考えたのは、<select>で<option>をv-forとかで回す方法。今までちゃんとわかってなかったが(今更w)<option>の中ってテキストしか置けない(HTMLタグが反映されない)らしい。。出来れば、以下のようにテキスト文字の前にタグを置いて、国旗を表現する方法とかに柔軟に対応できるようにしておきたい。。
※CSSも<option>の中は反映できるものとそうでないものがあるっぽい?

<select>
  <option>
    <i class="fr fr-jp"></i> ← optionタグの中のタグは認識されない
    日本
  </option>
</select>

結論

色々調べてみると、HTML標準のselectを使うよりも、cssを駆使したselect boxを自前で実現するような方法の方がselectの実現には良さそう。formのselectと区別するため、dropboxとかdropdownとか言ってた。

UIフレームワークの主軸をVueitfyとしてしまったので、Vuetify3が正式にリリースされるまでは、一旦国旗アイコン無しで国籍選択を入れるのが無難な気がしてきた。UIフレームワークを根本変更する事も考えたが、学習コストを考えるとあまり賢くないなと思ったり。

また、モバイルの場合は入力インターフェースの関係上、自前css-select-boxではなく、formのselectを使うようにしたほうが良いかも。国旗出す為に、画面上に国がズラーッと表示されると使いづらそう。モバイルでselectの場合、画面下部に専用の入力画面が表示されので、それを出すようにしたほうがユーザーフレンドリーかなと考えてみたりした。