Vue Test Utilsでコンポーネントのdata()を評価したい
なぜかうまくいかず時間がかかったのでメモ
こういうページネーションのコンポーネントのテストを書くとき、
コンポーネントのpropsには以下のような値(現在のページ,ページあたりの件数,トータル件数)を設定できるとして
<Pagination :config="{ current: 1, limit: 20, total: 100 }" @movePage="load" />
propsに値を設定したことを受け、watch
に定義したメソッドで、data()
の最終ページ lastPage
の値を算出したい。
watch: { config: function(payload) { // ここではわかりやすく「5ページ >>」とか変数にいれてる this.lastPage = Math.ceil(payload.total / payload.limit) + 'ページ >>' // 上記例の設定値だと「5ページ >>」になる } }
この「5ページ >>」を検査したかったのだけど、テストコードで propsData
をセットしてもなぜかwatchが発火しない。
<template> ... <a class="pagination-link last-page" :disabled="currentPage === lastPage" aria-label="Goto last page" @click="moveLast" > {{ lastPage }} <!-- 「5ページ >>」 --> </a> ... </template>
describe('components/Pagination.vue', () => { let wrapper describe('template', () => { beforeEach(() => { wrapper = mount(Pagination, { propsData: { config: { nextPage: 2, limit: 20, total: 100 } } // propsにセットしたのだからwatch発動してほしい! }) }) test('最終ページは5ページ目であること', () => { const page = wrapper.find('.last-page') expect(page.text()).toBe('5ページ >>') // 失敗。got:null }) }) })
props
を2回セットしたら思った通り動くようになった。
describe('components/Pagination.vue', () => { let wrapper describe('template', () => { beforeEach(() => { wrapper = mount(Pagination, { propsData: { config: { nextPage: 2, limit: 20, total: 100 } } }) }) test('最終ページは5ページ目であること', () => { wrapper.setProps({ config: { nextPage: 2, limit: 20, total: 100 } }) // これを足した。 const page = wrapper.find('.last-page') expect(page.text()).toBe('5ページ >>') // 成功した! }) }) })
2度setProps
していてなんかモヤるけど、やりたいことはできた。
【メモ】Nuxt.js/BulmaのNavbarでdropdownが残ってしまう(:focus-withinが効きっぱなし)
よくあるSPAのドロップダウン。
<n-link class="navbar-link" to="/members"> <span class="icon is-medium"> <i class="fas fa-lg fa-user"></i> </span> <span>メンバー管理</span> </n-link> <div class="navbar-dropdown"> <n-link class="navbar-item" to="/members">メンバー一覧</n-link> <n-link class="navbar-item" to="/members/new">メンバー登録</n-link> </div>
これ、なぜか n-link
click後にフォーカス状態が残ってしまい、閉じてくれない。
これは @click.native
イベントに一行追加することで、閉じてくれるようになりました(手元のChromeとFirefoxで確認)。
<n-link class="navbar-link" to="/members" @click.native="hideMenu"> <span class="icon is-medium"> <i class="fas fa-lg fa-user"></i> </span> <span>メンバー管理</span> </n-link> <div class="navbar-dropdown"> <n-link class="navbar-item" to="/members" @click.native="hideMenu">メンバー一覧</n-link> <n-link class="navbar-item" to="/members/new" @click.native="hideMenu">メンバー登録</n-link> </div>
んで、このメソッドを追加。
<script> export default { methods: { hideMenu(e) { e.target.blur() } } } </script>
以上です。
この一行を追加するまで、謎にえらい時間を費やしてしまったので、メモとして残します。
【メモ】Vueコンポーネントのwatchがwatchしない
こういうやつ
// NG watch: { config: (val, oldVal) => { console.log(val) console.log(oldVal) } }
functionにする必要があります。
// OK watch: { config: function(val, oldVal) { // functionにする console.log(val) console.log(oldVal) } }
ウォッチャを定義するためにアロー関数を使用すべきではない
と、ドキュメントにちゃんと、しかも太字で書いてありました。。サーセン
【メモ】Vueコンポーネントで再帰的に$emitしたいときの引数
Vueコンポーネントの中で自身のコンポーネントを呼び出してツリー表示をしたいときがあると思います。
今回やりたかったのは以下のこと。
1) 初期表示で最上位の階層(親のいない階層)を表示
2) 子要素があれば hasChild
属性が true
。「+」ボタンを表示する。
3)「+」ボタンを押したら、 loadChildren
メソッドを $emit
。自身の children
属性に子要素リストを読み込んで表示する。
4) 2-4を繰り返す。
というもの。再帰のところで $emit
の引数に何を渡すんだろう?とひるみましたが、 $event
を渡せばよいんだそうです。
<!-- Tree.vue --> <template> <div class="tree"> <ul v-for="item in items" :key="item.id"> <li> {{ item.name }} <Tree v-if="item.children !== null" // 子要素があるときだけ機能する :items="item.children" @loadChildren="$emit('loadChildren', $event)" // 引数に $event を指定する /> <a v-else-if="item.hasChild" @click="$emit('loadChildren', item)"> // 引数に item を指定する + </a> </li> </ul> </div> </template>
ここに例がありました。
【メモ】Nuxt.js で「Uncaught Error: [nuxt] store/index.js should export a method that returns a Vuex instance.」
storeの中に new Vuex.Store
を返す index.js
を作成したらエラー
ファイル名を store/index.js
から store/store.js
に変えたら直った。
store/index.js
はNuxtの中では特別な意味があるファイルなのか。
【メモ】openapi-generatorで たくさん出るエラーを無かったことにする
その場しのぎメモ
swagger.json
から openapi-generator generate
でエラーがたくさん出てしまう、おろかなわたしの swagger.json
。。。
openapi-generator generate -i http://localhost:3000/docs/swagger.json -o static/api -g html … Errors: #こういうエラーがモリモリ出てgenerateされない。pathパラメータの定義を$refでしてるからなのかなーわからん -attribute paths.'/api/users/{id}'. Declared path parameter id needs to be defined as a path parameter in path or operation level
コンソールのメッセージにあるのですが、 --skip-validate-spec
オプションをつけるとエラーを無視してgenerateしてくれます。
openapi-generator generate --skip-validate-spec -i http://localhost:3000/docs/swagger.json -o static/api -g html
DSLから生成した swagger.json
の構文エラーは直すのが大変なので、その場しのぎ大変助かります。