20210405のvue.jsに関する記事は6件です。

【メモ】【Vue.js】transitionタグの使い方

Vue.jsのtransitionタグとは? Vue.jsの独自タグ。HTMLファイルの中で使用し、transitionタグで囲むとアニメーションをつけることができる。 CSSのtransitionプロパティがアニメーション全般に使用できるのに対し、transitionタグはDOMの追加時と削除時に使用できる。 <transition> <!-- アニメーションさせたい要素を書く --> </transition> transition-groupタグ transition-groupタグで囲うことで複数の要素をアニメーションさせることができる。 <transition-group> <!-- アニメーションさせたい要素を書く --> </transition-group > CSSトランジション アニメーションは予め用意されたcss名で設定する必要がある。 /*現れる時*/ /*現れる前の状態*/ .v-enter { プロパティ: 値;} /*現れる間の動き*/ .v-enter-active { プロパティ: 値;} /*現れた後の状態*/ .v-enter-to { プロパティ: 値;} /*消える時*/ /*消える前の状態*/ .v-leave { プロパティ: 値;} /*消えている間の動き*/ .v-leave-actiove { プロパティ: 値;} /*消えた後の状態*/ .v-leave-to { プロパティ: 値;} /*移動中*/ /*移動中の動き*/ .v-move { プロパティ: 値;} 参考文献: 【Vue.js】transitionタグでアニメーション効果をつける Vue.js の transition ってなに?
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

親コンポーネントから子コンポーネントへのデータの渡し方

データの渡し方を忘れないように、メモとして残しておこうと思います。 v-bindとpropsを使いました。 App.vue <template> <div id="app"> <Number :number="number"></Number> </div> </template> <script> import Number from "./components/Number.vue"; export default { data() { return { number: 10, }; }, components: { Number } }; </script> Number.vue <template> <div id="Header"> <p>{{ number }}</p> </div> </template> <script> export default { props: ["number"], }; </script>
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JavaScript(ES6)の配列メソッドについて学習したのでまとめてみた

Vue.jsを利用したポートフォリオを作成している段階で、JavaScriptの知識が浅はか過ぎると実感した為、Udemyの教材を参考に改めて勉強することにしました。 今回は、配列メソッドについて学んだことを自分用のメモとしてアプトプットしていきます。 参考教材 世界で3万人が受講】JavaScriptエンジニアのためのES6完全ガイド https://www.udemy.com/course/javascriptes6/ forEachメソッド 配列内の各要素を抽出することができる main.js const users = [ 'yamada', 'ooshima', 'suzuki' ] users.forEach(user => { console.log(user) } // yamada, ooshima, suzuki findメソッド 配列内の指定要素を一つだけ抽出できるメソッド main.js const users = [ { name: 'yamada', country: 'japan', age: 28 }, { name: 'ooshima', country: 'japan', age: 23 }, { name: 'michael', country: 'usa', age: 31 }, ] let japanese = users.find(user => { return user.country === 'japan' }) console.log(japanese) /* { name: 'yamada', country: 'japan', age: 28 } findメソッドは指定要素を1つ抽出すると実行が終了する */ filterメソッド 配列内の指定した要素を全て抽出することができるメソッド javascript/main.js let stations = [ { name: '東京駅', line: '中央線' }, { name: '新宿', line: '山手線' }, { name: '北千住', line: '常磐線' }, { mame: '恵比寿', line: '山手線' } ] let yamanoteLine = stations.filter(station => { return station.line === '山手線' }) console.log(yamanoteLine) /* { name: '新宿', line: '山手線' }, { name: '恵比寿', line: '山手線' } findメソッドとは異なり、指定要素を全て抽出することができる */ mapメソッド 新しい配列を作り格納するメソッド javascript/main.js const developTeams = [ { name: 'yamada', age: 34, position: 'director' }, { name: 'sakurai', age: 25, position: 'manager' }, { name: 'suzuki', age: 21, position: 'engineer' }, { name: 'saito', age: 22, position: 'engineer' }, ] let teamMemberNames = developTeams.map(developTeam => { return developTeam.name }) console.log(teamMemberNames) /* [ 'yamada', 'sakurai', 'suzuki', 'saito' ] teamMemberNamesという新しい配列に格納される */ reduceメソッド 第一引数に各要素に関数を実行し、値を単一にすることができるメソッド javascript/main.js const tests = [ { subject: '国語', score: 69 }, { subject: '数学', score: 79 }, { subject: '英語', score: 87 }, { subject: '理科', score: 53 }, { subject: '社会', score: 91 }, ] let total = tests.reduce((sum, test) => { return sum += test.score }, 0) console.log(total) // 379 今回は、ポートフォリオ作成時に使えそうな配列メソッドをピックアップしてアウトプットしました。 今後もどんどんアウトプットしていきたいと思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

VueのSSR時におけるハイドレーションエラー対処法

参考記事 What to do when Vue hydration fails Client Side Hydration (Vue)ハイドレーションとは? ハイドレーションは、Vueがサーバー側でレンダリングされたマークアップを変換し、それをリアクティブにして、Vueからの動的な変更を反映できるようにするプロセス。 Vueが期待しているマークアップと、実際にレンダリングされたHTMLが異なるとハイドレーションエラーとなる。 Vueで開発中に以下のようなWarningに出会す時があります。 [Vue warn]: The client-side rendered virtual DOM tree is not matching server-rendered content. This is likely caused by incorrect HTML markup, for example nesting block-level elements inside <p>, or missing <tbody>. Bailing hydration and performing full client-side render. Warningの内容↓ クライアント側でレンダリングされた仮想DOMツリーがサーバーでレンダリングされたものと一致していません このWarningは開発環境でしか表示されません。 本番環境ではエラーとして出力されたり、レンダリングが完了しなかったりします。 なのでこの問題は解決しておきべきです。 今回はこのエラーの発生箇所を特定する方法についてメモしておきます。 ちなみに、すでに上記Warningの二つ上あたりに、以下ログが出ていたらそこが発生箇所です。 Parent: <~~>...</~~> ただ、これが人によっては表示されなかったりするので別の特定方法を提示します。 また発生原因も。 発生元を特定 Warningの詳細を開くと以下のようになっています。 ここで hydrateの呼び出し元をクリックします。 画像で言うと hydrate @ vue.runtime.esm.js?2b0e:6378 のところです。 するとVueのハイドレーション機能のソースコードが展開され、 展開された行の少し上あたりにこのようなコードがあります。 if (process.env.NODE_ENV !== 'production') { if (!assertNodeMatch(elm, vnode, inVPre)) { return false } } ここの6374行目の部分にデバッガーを設定します。(6374のところをクリック) return false そしてこの状態で画面をリロードすると、レンダリングが途中で止まります。 あとはDevToolのConsoleタブやElmentsタブから、 ハイドレーションに失敗したDOM要素を特定していきます。 (最終的に表示されるDOM要素と異なるのでそこで特定できます。) 発生原因/修正方法等 考えられる原因としては以下。 1. サーバ側とクライアント側の状態が異なる この原因が一番多いそうで、 この場合の解決策としては、データの取得方法やタイミングを修正するなどです。 2. 無効なHTMLを記述している 無効なHTMLを記述していないか確認。 例えば以下のようなHTMLを記述した場合、 正しくはtableタグの中にtbodyタグがないといけません。 [不正なHTML] <table> <tr><td>hoge</td></tr> </table> [有効なHTML] <table> <tbody> <tr><td>hoge</td></tr> </tbody> </table> しかしブラウザではこの不正なHTMLに自動的にtbodyタグを挿入してくれます。 そのため、DOMツリーに不整合が生じます。 3. 最終手段 client-onlyタグでラップし、サーバー側でのレンダリングを避けます。 <client-only></client-only> ※余談 開発環境では、 クライアントとサーバーでレンダリングされたDOMツリーが一致していなくても、 既存のDOMを破棄して最初からレンダリングし直してくれています。 しかし本番環境では、 パファーマンスを最大化するためにこの機能は無効になっています。 また、ハイドレーションは最初にページがサーバーによってレンダリングされた時(初回リクエスト時)にのみ発生します。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

メモ:nuxt/imageでSSGする際に処理する画像が多いとipxがエラー吐きまくる問題

画像が多いサイトで、nuxt/imageでSSG(静的サイトジェネレーター)で書き出ししようとするとエラーが出て、ネット上に解決方法が見つからなかったのでメモ。 nuxt/imageとは? nuxtの公式の画像最適化用のコンポーネントで、next.jsでいう next/image と同じような位置付けのコンポーネントです。 エラーの詳細 画像の多いサイトで、以下のコマンドで書き出ししようとすると yarn generate このようなエラーがたくさん出て画像の書き出しに失敗します。 ERROR request to http://localhost:57406/_ipx/images/hoge.jpg?s=640_298 failed, reason: connect ECONNRESET 127.0.0.1:57406 Githubにこのようなissueがありましたが、ちゃんと解決に至っていません。 https://github.com/nuxt/image/issues/198 原因を探ってみると画像変換に使っている ipx というローカルサーバへのアクセス過多でエラー吐いているようだったので、とりあえず応急処置的に対応しました。画像ファイルの処理を一斉に行わず少しずつ遅延させながら処理するようにしています。 @nuxt/image の /src/generate.ts を以下のように修正しました。 export function setupStaticGeneration (nuxt: any, options: ModuleOptions) { const staticImages = {} // url ~> hashed file name nuxt.hook('vue-renderer:ssr:prepareContext', (renderContext) => { renderContext.image = renderContext.image || {} renderContext.image.mapToStatic = <MapToStatic> function ({ url, format }: ResolvedImage) { if (!staticImages[url]) { const ext = (format && `.${format}`) || extname(parseURL(url).pathname) || '.png' staticImages[url] = hash(url) + ext } return staticImages[url] } }) nuxt.hook('generate:done', async () => { const { dir: generateDir } = nuxt.options.generate let delay = 0 // ← この行を追加 const downloads = Object.entries(staticImages).map(([url, name]) => { if (!hasProtocol(url)) { url = joinURL(options.internalUrl, url) } delay += delayOffset // ← この行を追加 return downloadImage({ url, name, outDir: resolve(generateDir, '_nuxt/image' /* TODO: staticImagesBase */), delay // ← この行を追加 }) }) await Promise.all(downloads) }) } async function downloadImage ({ url, name, outDir, delay }) { // 引数にdelayを追加 try { await new Promise(resolve => setTimeout(resolve, delay)) // ← この行を追加 const response = await fetch(url) if (!response.ok) { throw new Error(`Unexpected response ${response.statusText}`) } const dstFile = join(outDir, name) await mkdirp(dirname(dstFile)) await pipeline(response.body, createWriteStream(dstFile)) logger.success('Generated static image ' + relative(process.cwd(), dstFile)) } catch (error) { logger.error(error.message) } } 本当は上記のissueにもコメントされてますが、本当は最大の並行処理数を決めて、処理の完了を監視して次の処理をやるみたいなことをやるべきですが、とりあえず動けば良いという雑なやり方です。 一応GithubでForkしています。 追記: nuxtを使ったプロジェクトの package.json の @nuxt/image を以下のように書き換えるとこちらのForkを読み込むようになりますが、設定が足りていないのか、普通に yarn install しても buildコマンドが走らずdistディレクトリが生成されないです。 "dependencies": { "@nuxt/image": "git+https://github.com/kjkmr/nuxt-image.git#main" } とりあえずForkしたプロジェクトを npm run build することで吐き出されるdistディレクトリを nuxtのプロジェクトの node_modules/@nuxt/image 以下にコピーして無理矢理解決しています。(今度ちゃんとやり方調べたい。。。)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

オブジェクトにreduceを用いる

vueでreduceメソッドを久しぶりに用いて混乱した部分があるので整理した。 また、オブジェクトにreduceを用いて解説した記事はなかったので自分でまとめた。 ソースコード index.html <!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> </head> <body> <div id="app"> <p>合計:{{ totalPrice }}</p> </div> <script> const items = [ { name: '鉛筆', price: 300, quantity: 3 }, { name: 'ノート', price: 400, quantity: 4 }, { name: '消しゴム', price: 500, quantity: 1 }, ] const vm = new Vue({ el: '#app', data: { items: items }, computed: { totalPrice: function () { return this.items.reduce(function (sum, item) { return sum + (item.price * item.quantity) },0) }, } }) </script> </body> この時の reduce の挙動を totalPrice のなかで初期値などを変えつつ整理する ケース1:初期値を0としたとき ソースコード index.html totalPrice: function () { return this.items.reduce(function (sum, item) { return sum + (item.price * item.quantity) },0) 1回目 2回目 3回目 sum 0 900 2500 item オブジェクト(鉛筆の内容) オブジェクト(ノートの内容) オブジェクト(消しゴムの内容) reduce は配列の内容を出力するので1回目の item はオブジェクト(鉛筆の内容)となります。 2回目の sum では1回目の戻り値が入るので、 sum(初期値0) + (300 * 3) の値となり900 となります。 3回目の sum では2回目の戻り値が入るので、 sum(0 + 900) + (400 * 4) の値となり2500 となります。 最後の return sum + (item.price * item.quantity) では3回目の戻り値が sum に入り 2500 + (500(消しゴムの値段) * 1)となるので 3000 となります。 ケース2:初期値を設定しないとき ソースコード index.html totalPrice: function () { return this.items.reduce(function (sum, item) { return sum + (item.price * item.quantity) }) 1回目 2回目 3回目 sum オブジェクト(鉛筆の内容) [object Object]1600 なし item オブジェクト(ノートの内容) オブジェクト(消しゴムの内容) なし 1回目の sum に入る値は items[0] つまり鉛筆のオブジェクトとなるので各値は上記のようになります。 1回目の item は 配列の2番目の要素が入るので、index[1]が対象となり、 オブジェクト(ノートの内容) となります。 2回目の sum は1回目の戻り値が入るので オブジェクト(ノートの内容) + (400 * 4)となり [object Object]1600 となります。 2回目の item は配列の3番目の要素が入るので、index[2] が対象となり、 オブジェクト(消しゴムの内容) となります。 3回目の sum はすでに2回目の item で items の要素を出力し切っているので実行されません。 3回目の item はこちらも試行回数は終わっているので実行されません。 最後の return sum + (item.price * item.quantity) では2回目の戻り値が sum に入るので、 [object Object]1600 + 500となります。[object Object]1600は文字列とみなされてこのような表記になると思います。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む