投稿

ラベル(javascript)が付いた投稿を表示しています

vueでtypescript?あるいはOptional Chaining(短絡評価)

 以下の記事はアメブロで2022-05-09に投稿したものです。 vue-sfcのtemplate部で Optional Chaining が使えるようになっている(確認したのはvue3)。 例えばスタッフ名を表示する場合、以下のようなコードではstaffがundefinedの時、レンダリングが中断してしまう。 {{ staff.name }} なので、以下のように記述すると全体がundefinedと評価されるので、レンダリングが中断することなく完結する。 {{ staff?.name }} vueでいつからtypescriptが使えるようになったのか知らないのだけど ちょっと考えればすぐ気が付くのに 気づけなかった。 あるいはjavascriptのES20XXの機能なのかもしれないが大変ありがたい。 上述のstaffを取得するのにaxiosなどで非同期で得ようすると vueリアクティブで表示することになるのだけれど、 ここで最初のレンダリング時にはまだaxiosから結果を取得していないので なにも対策を取らないとstaffはundefinedなわけで そうするとレンダリング中断は問題なくても、vueからwarinig表示が出てしまい、まぁ、スッキリしない結果となってしまう。 なので、今まではstaffにはあらかじめ空オブジェクトで初期化していた。 これが必要なくなるのだ!!! 当然、axios結果取得でもstaffがundefinedだった場合でも問題ない!! つまりどれがオプションでどれが必須なのか気にする必要もない!!! ありがたい。 vue3ではv-modelも強化され、子コンポーネントでのprops変更不可問題も緩和されているようで 使いやすくなって来つつある。 最近はやり?のAtomic Designもやりやすくなるはずだ まだcssどうすんねん?とは思いますが、、、、

jest 特定のファイルだけ実行したい 特定のテストだけ実行したい

 以下の記事はアメブロで2022-11-10に投稿したものです。 わざわざ書く必要もない気もしたが 探してもすぐには設定がわからなかったので。 npx jest --testMatch [ "**" ] -t=ZZZZxxxx test/pages/AAAA/index.test.js とコマンドを打ちこむと良いようだ。 --testMatchオプションはほとんどの場合は必要ないようだが jest.config.jsのtestMatchが ['<rootDir>/test/components/**/*(*.)@(spec|test).[jt]s?(x)'] とかになっていると 上記のようにjest.config.jsの設定を無効化しないと test/pages/AAAA/index.test.jsが見つからないといってテスト実行できない。 jest.config.jsを書き換える方法もあるが また戻す必要がある場合はコマンドから直接指定したい。 -t=ZZZZxxxx こいつでテスト名と部分一致で実行してくれるようだ。 test('ZZZZxxxxテスト1', async done => {}) it('ZZZZxxxxテスト1', async done => {}) とかの最初の引数。

vueでasync、await、axios

 以下の記事はアメブロで2019-11-30に投稿したものです。 いやぁ、半年ぐらい悩んでたことが少し解決に近づいてきた。 vueのcreatedライフサイクルフックとかクリックイベントで axiosを使ってjsonデータを取得する時、 async、await使っても非同期処理で動いてしまって困ってたんだけども とにかくasync、awaitで上から下までファンクションすべてを囲ってしまうと 同期処理っぽくなることがわかった。 完全な同期処理ではなくてあくまでそれっぽくなるだけみたいだけども かなり見通し良く書けるようになった。 今までCから始まってC++,VB、PHP、Javaをやって、 最近一年ぐらいJavaScriptでやってるんたが、 こんな変な言語初めてだ!!! thisの扱いやら今回の件と良い、融通無碍と言うか、 もうちよっとどうにかならんか!!!

async、await、その2

 以下の記事はアメブロで2019-12-04に投稿したものです。 async、awaitでファンクション階層を包む話だけど、 ここにしっかり書いてあった https://azu.github.io/promises-book/#__code_await_code_%E5%BC%8F%E3%81%AFasync_function%E3%81%AE%E4%B8%AD%E3%81%A7%E3%81%AE%E3%81%BF%E5%88%A9%E7%94%A8%E5%8F%AF%E8%83%BD >Async Function内でawait式を使って処理を待っている間も、関数の外側では通常とおり処理が進みます やっぱりJavaScriptでは非同期処理を同期処理にすることはできないようで、、、 async、awaitを検索すると以下のような表現がよくあるんだけど、 大マチガイなので、真に受けないように >Promiseを返す関数をawaitで呼び出すと、次の処理には移らず、 >Promiseに格納した実値(resolve・rejectで返される値)が確定するまで待っていてくれる。 あくまで非同期処理は非同期処理だ!! 同期処理っぽく記述できるだけで 待ちゃぁしねえよっと!! awaitつけた関数以降のasyncラップされたコードをすっ飛ばすだけ!! すっ飛ばしてどうなるかと言うと、async/awaitの包みがなくなったところへ実行順序が移る すっ飛ばされたコードはawait付きの関数がresolveされた瞬間から実行再開される

vue HTML要素(checkbox)の表示非表示 v-modelは使わないと、、、

 以下の記事はアメブロで2019-12-04に投稿したものです。 いくつかにグループ化したchekbox集団があって、こいつらにv-modelを使っていなかった。 初期状態はすべてcheckなしだったし、必要な時にjqueryでchekck付きをかき集めてたから。 んで、グループ毎に表示非表示をやっていたんだが、 つまり表示したいcheckbox集団(配列)をv-forで一括して表示、 非表示にする場合checkbox集団(配列)から該当グループを削除、ってやっていた cssでdisplay:noneとかv-showとかv-ifを使わずに。 ところが間にあるグループを非表示にすると、 削除したはずのグループのchek状態が他へまだ表示状態のグループへずれて設定されてしまうことに気が付いた。 結局、v-modelでcheckboxをバインディングさせるとうまくいったが なるべくv-modelを使え!!ってこった と言うオチでした

async、await、その3

 以下の記事はアメブロで2020-02-05に投稿したものです。 babelを使っている場合と使ってない場合で結果が違うようで、、、 babelなしだと、確かに多くのサイトで書いてるように、 awaitで該当のコードは確実に停止しているようです。 IE対応でbabelトランスパイルすると、、、どうも違うような気がします。

nuxt-linkクリックイベントでの$refs

 以下の記事はアメブロで2020-03-25に投稿したものです。 nuxt-linkクリックイベントを拾って処理メソッド内から、 $refsを使って子コンポーネントを参照しようとしてももう子コンポーネントはdestoryされてしまっているようだ。 どうしても$refsを使いたい場合は、nuxt-linkにevent=""としてnuxt-link自体のクリックは無効にして 自前のクリックイベントメソッドから$router.pushなどで自力で遷移するようにすれば$refsが使える。

vueやらjestやらVeeValidateについて

 以下の記事はアメブロで2021-01-21に投稿したものです。 こちらのコードに落ち度があったのかもしれないが、 イロイロ気を付けたほうが良い点を上げておこうと思う。 ググってもみつかなかったし。 VeeValidate ValidationProviderのnameがバッティングしないようにしないとイロイロ不具合が多い 対象の入力項目が変な動作したり、 ValidationObserverのinvalidが正しく機能しなかったりする。 nameをユニークにする必要があるならドキュメントに書いておいてほしい 以下はjestだとかvue test utilsを使ったテストのはなし ValidationObserver asyncDataがjest環境では動作しないので、 代わりにwrapper = mount(xxxx)でマウントしてwrapper.setDataでデータを読み込ませてしまうと ValidationObserverのinvalidが正しく機能しない mountのmocksオプションを使ってなにかのイベントで読み込ませるとうまくいくことがある jest.spyOn テスト対象コードのイベントハンドラの記述は @click="saveData"ではなく@click="saveData()"としたほうが良い でないとjest.spyOnしてexpect(spy).toHaveBeenCalled()でチェックしようとしてもできないことがある vueのレンダリング createdやmountedの時にaxios.get、postで読み込んだデータをvueにレンダリングさせるには await mountして、 await flushPromises()、jest.runAllTimers()などを実行するとうまくいくことがある

CORS Access-Control-Allow-Originはレスポンスヘッダーなのだ

 以下の記事はアメブロで2021-11-27に投稿したものです。 よくある対策で リクエストヘッダーにAccess-Control-Allow-Originを含めるって あるけど、 これは間違いだ。 公式サイト見るとわかるが、 これはレスポンスヘッダーだ。 CORS リクエストヘッダに含めても動作していたとしていたら サーバー側が気をきかせて、設定してるだけ。 CORSで許されるヘッダーは サーバー側のレスポンスヘッダーにあるAccess-Control-Allow-Headers にリストアップされる。 なので、余計なヘッダーがあるとCORSエラーは回避できなくなる。 結局のところ、CORS対策でリクエスト側がやることは 許されるヘッダーだけを 許されるメソッドでリクエストしているかだけを気をつけるのだ。 認証系のクッキーがどうとかになるとまた違う対策が必要みたいだが。 ちなみにaxiosではロクなエラー詳細を返してくれないので 例外が起きてerror.responseが空、 間違いなくサーバー側はなにかレスポンスを返してる であれば まずCORSエラーを疑うと良い。 またまたちなみにだが、 awsのCloudWatchログではCORSのOPTIONSリクエストは記録されない。 なので、ログには全く記録されずリクエストが届いていないように見える、 curlではリクエストが問題ない であればCORSを疑おう。

puppeteer、clickできない、クリック反応しない

 以下の記事はアメブロで2022-12-15に投稿したものです。 初めてPuppeteerを使うことになって 少々はまったので覚書として記したい。 puppeteerから const btn = page.$(セレクタ) で要素取得して await btn.click()などとやっても反応しない もしくはローカルでは期待通りに動くのにawsなどデプロイ時テストに失敗するという時は btn.evaluate(b => b.click()) として、ブラウザ内部から実行するのが良いようだ。 いろいろ調べてみると ブラウザの表示範囲から外れてると Puppeteerからクリックしても反応しないようだったので ===> scrollIntoViewを使ってみる ===> puppeteer.launchオプションでブラウザサイズを変えてみる などやってみたが、ローカルでは動くがデプロイ時のテストで失敗した。 結局、前述のとおり、ブラウザ内部からclickするのが最善だと思う。 まぁ、vueを使ってるなら、vue test utilsで十分だと思うんですけど、、、

vee-validate 個数で制御(enable/disable)

 以下の記事はアメブロで2023-03-16に投稿したものです。 vue-nuxt、vee-validateのV3の環境で ボタンenable/disableを設定項目が1個以上かどうかで切り替えたい画面があった。 vee-validateには他の項目と連動させる機能があるのだが、どうにも使いづらい。 というかできるのかどうかもよく分からなかった。 なので結局、カスタムルールを作成し、computedで個数を取得して、それをrulesのカスタムルールのパラメータとして渡すことで解決した。 本来の機能でやった方が良いかもしれないが、こういうやり方もあるということでこちらに書くことにした。 xxxx.vue validation-provider(:immediate="true" vid="enabled" :rules="`XXXX_exist:${xxxxNums}`" v-slot="{errors}" name="XXXXの利用設定") computed: {   xxxxNums: {     get () {       return this.xxxx.length     },   }, plugins/validation.js extend(   'xxxx_exist',   {     message: (field) => { return field + 'には〇○〇○が必要です。' },     params: ['num'],     validate: (enabled, { num }) => {       return !enabled || parseInt(num)     },   }, ) 「利用しない」場合、enabledはfalse 利用する/利用しない というボタンで、ステータス切り替えを行うタイミングで ある項目が設定されているかチェックして、 更新 ボタン をenable/disableする。 このある項目は追加、削除で個数が上下する、という画面。 もちろん0個もあ...

vee-validate(V4系)のuseField、cssのtransitionでopacity

 以下の記事はアメブロで2024-06-26に投稿したものです。 vee-validateを使い始めて、 useFiledはバリデーションつきrefなのか? と気づいて実装を進めたところ、致命的なミスに気付いた。 なんとダイナミックに個数を増やせないのだ。 まぁ、正確には上限を10個にすることができれば <script setup>中に作ってしまえば良いのだが、 入力フィールドの横にプラス/マイナスボタンで増減しようとすると破綻する。 useFiled自体がボタンクリックなどのイベントに呼応して呼べないのだ(警告がワラワラと出てくる)。 まぁ、警告無視してもパット見、問題なさそうだが、、、これではビジネスユースでは難しいだろう。 結局、useFieldArrayを使うしかないようだ。 こいつにpush、insert、removeがあるからだ。 あとはuseFieldArrayと<Field standalone="true">とでなんとか対処した。 standaloneオプションは<Form>を使わずに<Field>を使う機能のようだ。 あとは公式ページのuseFieldArrayドキュメント冒頭にサンプルがある。 cssのtransitionだが よくありがちな10秒ぐらいでメッセージが消えるというアレをtransitionで実装しようとしたところ、 opacity:0を指定して指定秒数で消えるようにはなった。 だが、完全に消えるまでに、メッセージ後端にバツ印ボタンをクリックすると即座に消える機能を付加しようとすると、 イベントが起きない。 知ってる人からすると当たり前だろ、と思うかもしれないが、なぜイベントが起きないのか理解できなかった。 つまりイベントに関してはtransition指定がない時と同じでもうその要素のイベントは起きない。 指定秒数で消えるだけで、opacity:0なのだ!!

nuxt3(javascript、typescript)での文字コード変換

 以下の記事はアメブロで2024-07-13に投稿したものです。 いわゆるシフトJISだといくつかあるようだが、 MS932をサポートしているものはiconv-liteしか見つけられなかった。 厳密にはシフトJISとMS932は違うようなので、これを採用した。 まぁ、昨今のweb開発でUTF-8以外で開発とかかなり稀だが、 csvダウンロード/アップロードだとほぼシフトJIS系になる。 ここで文字コード変換が必要になるのだが、 使わせてもらって言うのもなんだが、 ドキュメントがクソだ。 UTF-8からMS932へ変換したいだけなのに、 公式ドキュメントのBasic APIを見るとdecode、encodeが出てくる。 どっち使うんだ??? とふつうは思うのだが、 この公式ドキュメントには全く記述がない。 結局、encodeを使うのが正解で、 const str932 = iconv.encode('あいうえお', 'MS932'); となる。 str932には変換後の [0x82, 0xa0, 0x82, 0xa2, 0x82, 0xa4, 0x82, 0xa6, 0x82, 0xa8] が入っているのだが typescriptだとBuffer型になるため、こいつがnuxt3には入ってない。 (標準ビルドでviteを使っているため?node特有のrequireなどもビルド結果に含めてもらえない) まぁ、BlobがBufferをそのまま受け入れてくれるので new Blob([str932], {'type' : 'text/plain' });して このあとはURL.createObjectURLしてAリンク作成してそのリンクのクリックを呼ぶと ブラウザがBlobの内容をダウンロードしてcsvファイルにくれる。 ここまでたどり着くのに1時間以上要した。 npmでBufferだけ入れてみたり、あっちこっちサンプルを探しまくった。 いろいろやって判明したのは iconvというコマンドツールが元々あった? このiconvがデフォルトでUTF-8になっている。 なのでiconv-liteも UTF-8<===>シフトJIS、JIS、EUC これが基本。 なのでUTF-8を介さない以下のようなことはで...

vee-validateをvue3で使う

イメージ
 以下の記事はアメブロで2025-06-26に投稿したものです。 ちょっと使いたいだけのなのに、 ドキュメントが英語だったり ComponentsとCompositionAPI(コンポーサブル)とに分かれていて どっちが使いやすいのか、どういうメリット/デメリットがあるのかすぐにはよく分からない。 どうもコンポーサブルのほうが自由度が高いようだし どちらというと公式ドキュメントもコンポーサブルを押しているようなので(Imperative vs Declarative)、 こちらを使うことにした。 どころがこちらもuserForm()だのuseField()だのあるし、 さらにdefineField()なんてもあるので、どれを使うとよいのかハテとなった。 なので、忘れないように、ここに覚え書きしようと思う。 以下のコードは公式ドキュメントを以下のようにたどると出てくる。 https://vee-validate.logaretm.com/v4/ ===> Get Started ===> Composition API ===> Custom inputs ここ(Building Custom inputs)編集可能サンプルの最初のサンプルソースを改変したものだ。 青字が変更箇所 コピペする場合はA0(ノーブレークスペース)から20(スペース)へ変換する必要があるかも、、、 アメブロってなんで20じゃないんだろ?? App.vue <template>   <form @submit=" onMySubmit ">     <InputText name="firstName" />     <InputText name="lastName" />     <InputText name="email" type="email" />     <InputText name="password" type="password" />     <InputText name="passwordConfirm" typ...

vue3のtransition

 以下の記事はアメブロで2025-06-30に投稿したものです。 vue2の時に、transitionを使おうとして、よく理解できなくて使えなかった。 なので、これも覚書として、残す。 vue3公式ドキュメントサイトのトランジション にサンプルがあるので それをベースに、ボタン押下でメッセージ表示===>数秒後にメッセージ消去orボタン押下ですぐメッセージ消去 というコードを作成した。 動作確認は公式ドキュメントサイトの「 Playground で試す 」で行った。 ここからいろいろなイベントで吹き出しメッセージ(保存しました!!のような)もすぐ作成できるだろう。 まぁこの程度は、コンポーネントでいろいろ公開されているかもしれないが、 数年前に探したときは、帯に短し襷に長し、でなにかと使いにくそうだった、、、、 <script setup> import { ref, nextTick } from 'vue' const show = ref(false); const showTransition = ref(false); const onShow = () => {   show.value = true;   showTransition.value = true;   nextTick(() => {     showTransition.value = false;   }); } const onHide = () => {   show.value = false; } </script> <template>   <div><button @click="onShow">Show</button></div>   <div v-if="show">     <Transition>       <p v-if="showTransition">hello</p>     </Transition>   ...