[{"data":1,"prerenderedAt":19717},["ShallowReactive",2],{"posts-categories-by-ux-1":3,"posts-categories-ux-all-count":409},[4,176,2238,5410,8402,9218,16389,16816,18371],{"id":5,"title":6,"body":7,"categories":163,"description":165,"draft":166,"extension":167,"meta":168,"navigation":169,"path":170,"priority":171,"publishedAt":172,"secret":166,"seo":173,"stem":174,"updatedAt":172,"__hash__":175},"posts\u002Ftech\u002Fux-exam.md","エンジニアが UX 検定(基礎)を受けてみた話",{"type":8,"value":9,"toc":153},"minimark",[10,14,18,25,28,31,34,53,56,60,63,66,69,72,75,117,120,123,126,132,135,138,141,144,147,150],[11,12,13],"h2",{"id":13},"はじめに",[15,16,17],"p",{},"2026年7月に UX 検定(基礎)を受験し、晴れて合格しました。記憶が新しいうちに振り返りたく、この記事では合格までの体験記を綴ります。",[15,19,20],{},[21,22],"img",{"alt":23,"src":24},"合格","\u002Fcontent\u002Fux-exam\u002Fresult.png",[15,26,27],{},"試験を通じて、UX への考え方が大きく変わりました。受験前は、センスや才能のある人だけが UX を作れるものだと思っていたり、使いやすさは人によって千差万別で収拾がつかないなど、学ぶべきだとは思いつつハードルを感じていました。しかし実際に学んでみると、理論・プロセス・考え方のいずれも後天的に習得できるものばかりだと気づきました。この記事では、試験対策として取り組んだ勉強法だけでなく、学びを通じて変化した UX への見方についても書いていきます。UI\u002FUX に力を入れたいエンジニアや、試験に興味のある方の参考になれば幸いです。",[11,29,30],{"id":30},"試験の概要",[15,32,33],{},"UX 検定基礎は、UX を学び始めた人が UX 向上の取組みに向けたマインドセットと基礎スキルを学ぶことができる資格です。",[35,36,37,41,44,47,50],"ul",{},[38,39,40],"li",{},"受験料：税込10,890円",[38,42,43],{},"試験時間：100分",[38,45,46],{},"問題数：100問",[38,48,49],{},"実施方式：オンライン（自宅受験）",[38,51,52],{},"学習推薦図書：4冊",[15,54,55],{},"※ 次の開催日程や学習推薦図書などの詳細は、下記公式サイトをご確認ください。",[57,58],"link-card",{"link":59},"https:\u002F\u002Fwww.uxia.or.jp\u002Fcertification\u002Fbasic\u002F",[11,61,62],{"id":62},"なぜ受験しようと思ったか",[15,64,65],{},"以前の現場でデザイナーが何人か受験・合格したと聞いたことがきっかけです。これまで UX の考案やデザイン業務を担当した経験はなく、モバイルと Web のフロント開発を専門にしてきた身としては、新たな強みへの期待とキャリアアップを兼ねて受験を決めました。",[15,67,68],{},"また、普段の業務では決められたデザインを実装するだけでなく、企画側やデザイナーとの議論にも加われるようになりたいという気持ちもありました。個人でアプリを開発するうえでも、「使いやすい」かどうかを自分で判断できる基準を持ちたいと思っていました。",[11,70,71],{"id":71},"勉強方法",[15,73,74],{},"シンプルに言えば、課題図書を読んでシラバスにある語彙の意味を把握することが基本的な勉強法です。",[35,76,77,89,96,103,110],{},[38,78,79],{},[80,81,88],"a",{"href":82,"rel":83,"target":87},"https:\u002F\u002Fwww.uxia.or.jp\u002Fcertification\u002F202607_ux_syllabus.pdf",[84,85,86],"nofollow","noopener","noreferrer","_blank","シラバス",[38,90,91],{},[80,92,95],{"href":93,"rel":94,"target":87},"https:\u002F\u002Fwww.amazon.co.jp\u002F%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%93%E3%83%AA%E3%83%86%E3%82%A3%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%83%AA%E3%83%B3%E3%82%B0-%E7%AC%AC2%E7%89%88-%E2%80%95%E3%83%A6%E3%83%BC%E3%82%B6%E3%82%A8%E3%82%AF%E3%82%B9%E3%83%9A%E3%83%AA%E3%82%A8%E3%83%B3%E3%82%B9%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E8%AA%BF%E6%9F%BB%E3%80%81%E8%A8%AD%E8%A8%88%E3%80%81%E8%A9%95%E4%BE%A1%E6%89%8B%E6%B3%95%E2%80%95-%E6%A8%BD%E6%9C%AC-%E5%BE%B9%E4%B9%9F\u002Fdp\u002F4274214834",[84,85,86],"ユーザビリティエンジニアリング: ユーザエクスペリエンスのための調査、設計、評価手法",[38,97,98],{},[80,99,102],{"href":100,"rel":101,"target":87},"https:\u002F\u002Fwww.amazon.co.jp\u002F%E3%82%A2%E3%83%95%E3%82%BF%E3%83%BC%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB2-UX%E3%81%A8%E8%87%AA%E7%94%B1-%E8%97%A4%E4%BA%95-%E4%BF%9D%E6%96%87\u002Fdp\u002F4296106317\u002Fref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1B8W4JVMNP477&dib=eyJ2IjoiMSJ9.YwftZj430791_QKQJKFq0TjYc7RujSNnC_NhPDc6y9zGjHj071QN20LucGBJIEps.WJE_jAyGyKl8pe4Xca7vo_pJvaLa4Qbi_UuAQ93hA0g&dib_tag=se&keywords=%E3%82%A2%E3%83%95%E3%82%BF%E3%83%BC%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB2+UX%E3%81%A8%E8%87%AA%E7%94%B1&qid=1786161664&s=books&sprefix=%2Cstripbooks%2C177&sr=1-1",[84,85,86],"アフターデジタル2 UXと自由",[38,104,105],{},[80,106,109],{"href":107,"rel":108,"target":87},"https:\u002F\u002Fwww.amazon.co.jp\u002F%EF%BC%B5%EF%BC%B8%E3%82%B0%E3%83%AD%E3%83%BC%E3%82%B9%E3%83%A2%E3%83%87%E3%83%AB-%E3%82%A2%E3%83%95%E3%82%BF%E3%83%BC%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%82%92%E7%94%9F%E3%81%8D%E6%8A%9C%E3%81%8F%E5%AE%9F%E8%B7%B5%E6%96%B9%E6%B3%95%E8%AB%96-%E8%97%A4%E4%BA%95-%E4%BF%9D%E6%96%87-ebook\u002Fdp\u002FB09G5RX1BN\u002Fref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=1JXVNDWBTTNCU&dib=eyJ2IjoiMSJ9.uy19Vu6VbPmBMhnio72mjNLbVr77XWXXRb4Y1sls6voHFO3iz7w181_Xkavw-5qm.5Vh3LYB26bB1dIBcsqzCfpPx-clYfNoK-DcMgwoSQUA&dib_tag=se&keywords=UX%E3%82%B0%E3%83%AD%E3%83%BC%E3%82%B9%E3%83%A2%E3%83%87%E3%83%AB+%E3%82%A2%E3%83%95%E3%82%BF%E3%83%BC%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E3%82%92%E7%94%9F%E3%81%8D%E6%8A%9C%E3%81%8F%E5%AE%9F%E8%B7%B5%E6%96%B9%E6%B3%95%E8%AB%96&qid=1786161676&s=books&sprefix=%E3%82%A2%E3%83%95%E3%82%BF%E3%83%BC%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB2+ux%E3%81%A8%E8%87%AA%E7%94%B1%2Cstripbooks%2C217&sr=1-1",[84,85,86],"UXグロースモデル　アフターデジタルを生き抜く実践方法論",[38,111,112],{},[80,113,116],{"href":114,"rel":115,"target":87},"https:\u002F\u002Fwww.amazon.co.jp\u002F%E4%BA%BA%E9%96%93%E4%B8%AD%E5%BF%83%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80-HCD%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%BC-%E5%B1%B1%E5%B4%8E-%E5%92%8C%E5%BD%A6\u002Fdp\u002F476490506X\u002Fref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=14KXGXFUNJUQV&dib=eyJ2IjoiMSJ9.41iYar3zBUYjs1XVyJDYUQ-Ck1iDCaW_weYEuLXCzo-kiPaLOyyfhw0CTlJCf-q-lmdvk-yJa5xrM4zUb6-pfiVoXdY3TmtMTwHIFpW03pdaIKioCVvJUTX85_bGE1v7E9flrDGT5J5HX6OUnT2A4w.xSBaFGl17Lvjgkau3ucYcfOWmy_78THn6ZmpMitUzRU&dib_tag=se&keywords=%E4%BA%BA%E9%96%93%E4%B8%AD%E5%BF%83%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80%EF%BC%88HCD%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%BC%E7%AC%AC%EF%BC%90%E5%B7%BB%EF%BC%89&qid=1786161686&s=books&sprefix=%E4%BA%BA%E9%96%93%E4%B8%AD%E5%BF%83%E8%A8%AD%E8%A8%88%E5%85%A5%E9%96%80+hcd%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA%E3%83%BC%E7%AC%AC0%E5%B7%BB+%2Cstripbooks%2C233&sr=1-1",[84,85,86],"人間中心設計入門（HCDライブラリー第０巻）",[15,118,119],{},"試験の 2 ヶ月前から勉強を始めましたが、4 冊の課題図書をそれぞれじっくり読み、要約を作るだけの時間的リソースを確保できるか不安でした。そこで、試験勉強に AI を取り入れて効率化できないかと考え、Gemini Notebook（旧 NotebookLM）を活用しました。",[57,121],{"link":122},"https:\u002F\u002Fnotebooklm.google\u002F?hl=ja",[15,124,125],{},"Gemini Notebook とは、PDF・Google ドキュメント・YouTube 動画などの特定ソースをアップロードすると、AI が要約や質問への回答を行ってくれるサービスです。課題図書の PDF をアップロードし、各章やセクションの要約を聞きながら、わからない点は掘り下げて聞くというスタイルで学習を進めました。AI 自身が関連する質問を提案してくれることもあり、インプットのハードルが格段に下がりました。",[15,127,128],{},[21,129],{"alt":130,"src":131},"サマリー","\u002Fcontent\u002Fux-exam\u002Fsummary.png",[11,133,134],{"id":134},"試験を受けてみて",[15,136,137],{},"冒頭に貼った結果の通り、ギリギリ合格点といった次第でした。100 問を 100 分で解く構成なので、1 問に 1 分以上かけると時間が足りなくなります。見切りをつける基準をあらかじめ決めておくと、本番で慌てずに済むでしょう。自信のない問題にはフラグをつけられるため、あとで見返すことができます。",[15,139,140],{},"対策としては、語彙やその定義を覚えるだけでなく、それぞれの特徴や背景にある理由まで理解しておくことが重要です。特に、語彙を別の言い方で問われるケースが多い印象でした。過去問が公開されていないため、問題の傾向をつかめないまま本番を迎えることになりますが、どんな問われ方をしても答えられるよう網羅的に内容を整理していくのがいちばんの対策かもしれません。（なお、試験終了後もどの問題が誤りだったかは公表されないため、問題の流出を徹底して防いでいる印象です。）",[15,142,143],{},"合格して、肝心の UX への理解が深まったかというと、即効性のあるテクニックを習得したというよりも、UX とは何かを広く学ぶことができました。小手先の改善よりも、仮説・実装・検証のサイクルを繰り返し、地道に改善を続けることの重要性が、課題図書を通じて何度も説かれていました。ユーザーの行動の理由は心理的なものではなく、その人が置かれた「状況・文脈（外部環境）」との因果関係にある、行動の理由を聞くときに「なぜ」を使うのはアンチパターンである、といった知見も印象的でした。モノを売って終わりの「バリューチェーン型」から、顧客の成功に寄り添い続ける「バリュージャーニー型」への転換が求められる今だからこそ、改善し続けること自体が UX をつくることだと学びました。",[11,145,146],{"id":146},"これから受ける人に向けて",[15,148,149],{},"「UX はとっつきにくい、難しそう」と感じているなら、受験前の自分と同じ気持ちだと思います。しかし、正解がなく抽象度が高いからこそ、一つひとつ理解を積み上げることで最後までやり切ることができました。UX 検定基礎は、知識を完璧に覚えているかを問う試験ではなく、UX をどう考えるか、その前提を理解しているかを確認する試験だと感じています。完璧を目指しすぎず、わからないところをその都度調べながら進めるだけでも、十分意味のある学びになるはずです。",[15,151,152],{},"この記事が、UX 検定を受けるか迷っている方の一つの参考になれば幸いです。",{"title":154,"searchDepth":155,"depth":155,"links":156},"",2,[157,158,159,160,161,162],{"id":13,"depth":155,"text":13},{"id":30,"depth":155,"text":30},{"id":62,"depth":155,"text":62},{"id":71,"depth":155,"text":71},{"id":134,"depth":155,"text":134},{"id":146,"depth":155,"text":146},[164],"UX","2026年7月に UX 検定(基礎)を受けたので、その振り返りをします",false,"md",{},true,"\u002Ftech\u002Fux-exam",null,"2026-08-07",{"title":6,"description":165},"tech\u002Fux-exam","zu9G2PRwIUM0TqUNGngEkO0ZQYys4XQjPnZQURIr-mQ",{"id":177,"title":178,"body":179,"categories":2228,"description":2231,"draft":166,"extension":167,"meta":2232,"navigation":169,"path":2233,"priority":171,"publishedAt":2234,"secret":166,"seo":2235,"stem":2236,"updatedAt":2234,"__hash__":2237},"posts\u002Ftech\u002Fnuxt-content-v3-migration.md","Nuxt Content v3 マイグレーションガイド",{"type":8,"value":180,"toc":2214},[181,189,192,195,199,207,211,214,217,220,223,226,229,232,235,238,241,244,249,260,263,681,691,720,729,740,966,977,987,1611,1615,1625,1759,1762,1778,1862,1868,1993,2004,2110,2124,2135,2159,2189,2192,2195,2198,2207,2210],[15,182,183,184,188],{},"今年 2025 年の 1 月にメジャーバージョンの v3 がリリースされたので、メジャーバージョンの v2 を利用しているこのブログでも v3 へマイグレートしました。(参考: ",[80,185,187],{"href":186},"\u002Fposts\u002Ftech\u002Fbuilt-portofolio-by-nuxt-content-ssg","offich.me をささえる技術",")",[57,190],{"link":191},"https:\u002F\u002Fcontent.nuxt.com\u002Fblog\u002Fv3",[15,193,194],{},"予想以上に詰まったことが多く、せっかくなら作業ログを残す形で、同じく現在 v2 を利用していて v3 へマイグレートする方へのヒントになるような記事を目指します。",[11,196,198],{"id":197},"nuxt-content-とは","Nuxt Content とは",[15,200,201,202,206],{},"そもそも ",[203,204,205],"code",{},"Nuxt Content"," とは、Nuxt 用のヘッドレス CMS ライクなコンテンツ管理モジュールです。Markdown（.md）、JSON（.json）、YAML（.yml）、CSV（.csv）などのファイルを簡単に管理・表示できます。それらのファイルの内容をそのままページコンテンツにでき、検索やフィルタ、ソート機能などコンテンツを管理する方法を多く提供しています。マークダウンの中でカスタム Vue コンポーネントを呼び出すことができ、文章だけではなくリッチなコンテンツを構築できます。そのため、ブログや企業公式サイトで使われることが多いです。",[11,208,210],{"id":209},"v2-からの-v3-への変更点","v2 からの v3 への変更点",[15,212,213],{},"マイグレーションガイドを読んで、v2 と比較しての一番の大きな変更点はコンテンツのデータの管理と取得方法です。",[57,215],{"link":216},"https:\u002F\u002Fcontent.nuxt.com\u002Fblog\u002Fv3#serverless-compatibility",[57,218],{"link":219},"https:\u002F\u002Fcontent.nuxt.com\u002Fdocs\u002Fadvanced\u002Fdatabase",[15,221,222],{},"今までの nuxt content v2 は、コンテンツ管理をストレージシステムをファイルベースとしており、データについてはすべてプロジェクトの中で完結するのが魅力でした。それぞれのコンテンツに対してキャッシュファイルを作成するのですが、必然とすべてのキャッシュファイルをロードすることになり、プロダクション環境での I\u002FO が大幅になっていました。",[15,224,225],{},"そのため、多くのコンテンツを持つプロジェクトだと、リクエストの度にゼロからサーバーを起動するサーバーレス環境とは相性が悪かったみたいです。状態を持たないサーバーレス環境の中でサーバー内のメモリやファイルベースのデータベースは使えないので、v3 からは永続化されたデータベースからデータを取得する変更にしました。",[15,227,228],{},"今回 v3 では、AST へ変換したコンテンツを事前に定義したスキーマと沿っているかを確かめるのを兼ねて、テーブルに入れ、dump ファイルに落とし込みます。そして、コードスタート時にその dump ファイルをデータベースへデータをリストアするとのことです。コンテンツはもちろん最新のものだったり、重複を弾くなどの工夫はしているようです。",[15,230,231],{},"このデータベースにデータをリストアするアプローチがクライアントのナビゲーションでも応用されていることについて魅力的に感じました。最初クエリが発行されたときに、dump ファイルを取得し、ブラウザ内のデータベースへデータをリストアすることで、サーバーへの通信がなくなります。これにより、データ取得がクライアント内で完結します。つまり、レスポンスも早くなり、オフライン環境でもコンテンツを見ることが可能になります。",[11,233,234],{"id":234},"マイグレーション内容",[15,236,237],{},"マイグレーションガイド自体は nuxt content の公式サイトにあるので、まずはそれに目を通すことを推奨します。v2 のころから提供されているコンポーネントのリネームや削除、上記に記載したようにコンテンツが SQL データベースで保存されることから、取得 API の名前や方法がまるっと変更されています。",[57,239],{"link":240},"https:\u002F\u002Fcontent.nuxt.com",[15,242,243],{},"以下には、このブログにおいて印象だった変更をまとめます。",[245,246,248],"h3",{"id":247},"collection-の定義","Collection の定義",[15,250,251,252,255,256,259],{},"v3 からコンテンツを関連したものを ",[203,253,254],{},"Collection"," でグルーピングするという考えができました。これからコンテンツをデータベースで管理するというのも相まって、それぞれのグループのスキーマを定義します。その定義をするために、v3 から ",[203,257,258],{},"content.config.ts"," というファイルをルートに置く必要があります。",[15,261,262],{},"以下はこのブログでの内容です。",[264,265,269],"pre",{"className":266,"code":267,"filename":258,"language":268,"meta":154,"style":154},"language-ts shiki shiki-themes material-theme","import path from 'path'\n\nimport { defineCollection, defineContentConfig, z } from '@nuxt\u002Fcontent'\n\nexport default defineContentConfig({\n  collections: {\n    posts: defineCollection({\n      type: 'page',\n      source: {\n        cwd: path.resolve('src\u002Fcontent'),\n        include: '**',\n      },\n      schema: z.object({\n        title: z.string(),\n        description: z.string(),\n        publishedAt: z.string(),\n        updatedAt: z.string(),\n        categories: z.array(z.string()),\n        draft: z.boolean(),\n        secret: z.boolean(),\n        priority: z.number(),\n      }),\n    }),\n  },\n})\n","ts",[203,270,271,298,303,338,343,361,374,388,407,417,447,464,470,489,509,527,545,563,590,609,627,646,656,666,672],{"__ignoreMap":154},[272,273,276,280,284,287,291,295],"span",{"class":274,"line":275},"line",1,[272,277,279],{"class":278},"s6cf3","import",[272,281,283],{"class":282},"svy0-"," path ",[272,285,286],{"class":278},"from",[272,288,290],{"class":289},"sAklC"," '",[272,292,294],{"class":293},"sfyAc","path",[272,296,297],{"class":289},"'\n",[272,299,300],{"class":274,"line":155},[272,301,302],{"emptyLinePlaceholder":169},"\n",[272,304,306,308,311,314,317,320,322,325,328,331,333,336],{"class":274,"line":305},3,[272,307,279],{"class":278},[272,309,310],{"class":289}," {",[272,312,313],{"class":282}," defineCollection",[272,315,316],{"class":289},",",[272,318,319],{"class":282}," defineContentConfig",[272,321,316],{"class":289},[272,323,324],{"class":282}," z",[272,326,327],{"class":289}," }",[272,329,330],{"class":278}," from",[272,332,290],{"class":289},[272,334,335],{"class":293},"@nuxt\u002Fcontent",[272,337,297],{"class":289},[272,339,341],{"class":274,"line":340},4,[272,342,302],{"emptyLinePlaceholder":169},[272,344,346,349,352,355,358],{"class":274,"line":345},5,[272,347,348],{"class":278},"export",[272,350,351],{"class":278}," default",[272,353,319],{"class":354},"sdLwU",[272,356,357],{"class":282},"(",[272,359,360],{"class":289},"{\n",[272,362,364,368,371],{"class":274,"line":363},6,[272,365,367],{"class":366},"s-wAU","  collections",[272,369,370],{"class":289},":",[272,372,373],{"class":289}," {\n",[272,375,377,380,382,384,386],{"class":274,"line":376},7,[272,378,379],{"class":366},"    posts",[272,381,370],{"class":289},[272,383,313],{"class":354},[272,385,357],{"class":282},[272,387,360],{"class":289},[272,389,391,394,396,398,401,404],{"class":274,"line":390},8,[272,392,393],{"class":366},"      type",[272,395,370],{"class":289},[272,397,290],{"class":289},[272,399,400],{"class":293},"page",[272,402,403],{"class":289},"'",[272,405,406],{"class":289},",\n",[272,408,410,413,415],{"class":274,"line":409},9,[272,411,412],{"class":366},"      source",[272,414,370],{"class":289},[272,416,373],{"class":289},[272,418,420,423,425,428,431,434,436,438,441,443,445],{"class":274,"line":419},10,[272,421,422],{"class":366},"        cwd",[272,424,370],{"class":289},[272,426,427],{"class":282}," path",[272,429,430],{"class":289},".",[272,432,433],{"class":354},"resolve",[272,435,357],{"class":282},[272,437,403],{"class":289},[272,439,440],{"class":293},"src\u002Fcontent",[272,442,403],{"class":289},[272,444,188],{"class":282},[272,446,406],{"class":289},[272,448,450,453,455,457,460,462],{"class":274,"line":449},11,[272,451,452],{"class":366},"        include",[272,454,370],{"class":289},[272,456,290],{"class":289},[272,458,459],{"class":293},"**",[272,461,403],{"class":289},[272,463,406],{"class":289},[272,465,467],{"class":274,"line":466},12,[272,468,469],{"class":289},"      },\n",[272,471,473,476,478,480,482,485,487],{"class":274,"line":472},13,[272,474,475],{"class":366},"      schema",[272,477,370],{"class":289},[272,479,324],{"class":282},[272,481,430],{"class":289},[272,483,484],{"class":354},"object",[272,486,357],{"class":282},[272,488,360],{"class":289},[272,490,492,495,497,499,501,504,507],{"class":274,"line":491},14,[272,493,494],{"class":366},"        title",[272,496,370],{"class":289},[272,498,324],{"class":282},[272,500,430],{"class":289},[272,502,503],{"class":354},"string",[272,505,506],{"class":282},"()",[272,508,406],{"class":289},[272,510,512,515,517,519,521,523,525],{"class":274,"line":511},15,[272,513,514],{"class":366},"        description",[272,516,370],{"class":289},[272,518,324],{"class":282},[272,520,430],{"class":289},[272,522,503],{"class":354},[272,524,506],{"class":282},[272,526,406],{"class":289},[272,528,530,533,535,537,539,541,543],{"class":274,"line":529},16,[272,531,532],{"class":366},"        publishedAt",[272,534,370],{"class":289},[272,536,324],{"class":282},[272,538,430],{"class":289},[272,540,503],{"class":354},[272,542,506],{"class":282},[272,544,406],{"class":289},[272,546,548,551,553,555,557,559,561],{"class":274,"line":547},17,[272,549,550],{"class":366},"        updatedAt",[272,552,370],{"class":289},[272,554,324],{"class":282},[272,556,430],{"class":289},[272,558,503],{"class":354},[272,560,506],{"class":282},[272,562,406],{"class":289},[272,564,566,569,571,573,575,578,581,583,585,588],{"class":274,"line":565},18,[272,567,568],{"class":366},"        categories",[272,570,370],{"class":289},[272,572,324],{"class":282},[272,574,430],{"class":289},[272,576,577],{"class":354},"array",[272,579,580],{"class":282},"(z",[272,582,430],{"class":289},[272,584,503],{"class":354},[272,586,587],{"class":282},"())",[272,589,406],{"class":289},[272,591,593,596,598,600,602,605,607],{"class":274,"line":592},19,[272,594,595],{"class":366},"        draft",[272,597,370],{"class":289},[272,599,324],{"class":282},[272,601,430],{"class":289},[272,603,604],{"class":354},"boolean",[272,606,506],{"class":282},[272,608,406],{"class":289},[272,610,612,615,617,619,621,623,625],{"class":274,"line":611},20,[272,613,614],{"class":366},"        secret",[272,616,370],{"class":289},[272,618,324],{"class":282},[272,620,430],{"class":289},[272,622,604],{"class":354},[272,624,506],{"class":282},[272,626,406],{"class":289},[272,628,630,633,635,637,639,642,644],{"class":274,"line":629},21,[272,631,632],{"class":366},"        priority",[272,634,370],{"class":289},[272,636,324],{"class":282},[272,638,430],{"class":289},[272,640,641],{"class":354},"number",[272,643,506],{"class":282},[272,645,406],{"class":289},[272,647,649,652,654],{"class":274,"line":648},22,[272,650,651],{"class":289},"      }",[272,653,188],{"class":282},[272,655,406],{"class":289},[272,657,659,662,664],{"class":274,"line":658},23,[272,660,661],{"class":289},"    }",[272,663,188],{"class":282},[272,665,406],{"class":289},[272,667,669],{"class":274,"line":668},24,[272,670,671],{"class":289},"  },\n",[272,673,675,678],{"class":274,"line":674},25,[272,676,677],{"class":289},"}",[272,679,680],{"class":282},")\n",[15,682,683,686,687,690],{},[203,684,685],{},"zod"," を使ってコンテンツの型を定義できるようになったのは、非常に便利だと感じました。今までだと自分で interface を定義して、",[203,688,689],{},"queryContent"," に型情報を渡して初めて、型が付与されたのですが最初から型が付与される形となりました。",[15,692,693,694,697,698,701,702,704,705,707,708,711,712,714,715,719],{},"Nuxt content ではデフォルトでコンテンツの保管場所を ",[203,695,696],{},"content"," という名前で Nuxt プロジェクトのルートディレクトリの中を指定しています。しかし、その保管場所を変更でき、",[203,699,700],{},"source"," プロパティにその保管場所を伝えることで可能になります。このブログでは、コンテンツの場所は ",[203,703,440],{}," ディレクトリになっているので、",[203,706,700],{}," プロパティの ",[203,709,710],{},"cwd"," を書き換えています。ここで注意すべきなのは、",[203,713,710],{}," プロパティには ",[716,717,718],"strong",{},"絶対パス"," を渡すことです。最初 Nuxt プロジェクトの相対パスを渡していましたが、dev server 起動中の hot reload が効かなくて、数時間溶かしました。コンテンツの中身に変更があったときは、以下のようなログが出力されます。",[264,721,727],{"className":722,"code":724,"filename":725,"language":726,"meta":154},[723],"language-text","[@nuxt\u002Fcontent 18:02:45] ℹ File tech\u002Fnuxt-content-v3-migration.md changed on posts collection\n","changed.txt","text",[203,728,724],{"__ignoreMap":154},[15,730,731,732,735,736,739],{},"Collection の定義が書けたら、",[203,733,734],{},"nuxi prepare"," コマンドを実行して、型を生成します。これからコンテンツについてのプロパティ参照するときは、",[203,737,738],{},"PostsCollectionItem"," からプロパティを選択します。",[264,741,744],{"className":266,"code":742,"filename":743,"language":268,"meta":154,"style":154},"import type { PageCollectionItemBase, DataCollectionItemBase } from '@nuxt\u002Fcontent'\n\ndeclare module '@nuxt\u002Fcontent' {\n  interface PostsCollectionItem extends PageCollectionItemBase {\n    title: string;\n    description: string;\n    publishedAt: string;\n    updatedAt: string;\n    categories: string[];\n    draft: boolean;\n    secret: boolean;\n    priority: number;\n  }\n\n  interface PageCollections {\n    posts: PostsCollectionItem\n  }\n\n  interface Collections {\n    posts: PostsCollectionItem\n  }\n}\n",".nuxt\u002Fcontent\u002Ftypes.d.ts",[203,745,746,773,777,794,810,823,834,845,856,870,882,893,905,910,914,923,932,936,940,949,957,961],{"__ignoreMap":154},[272,747,748,750,753,755,758,760,763,765,767,769,771],{"class":274,"line":275},[272,749,279],{"class":278},[272,751,752],{"class":278}," type",[272,754,310],{"class":289},[272,756,757],{"class":282}," PageCollectionItemBase",[272,759,316],{"class":289},[272,761,762],{"class":282}," DataCollectionItemBase",[272,764,327],{"class":289},[272,766,330],{"class":278},[272,768,290],{"class":289},[272,770,335],{"class":293},[272,772,297],{"class":289},[272,774,775],{"class":274,"line":155},[272,776,302],{"emptyLinePlaceholder":169},[272,778,779,783,786,788,790,792],{"class":274,"line":305},[272,780,782],{"class":781},"sJ14y","declare",[272,784,785],{"class":781}," module",[272,787,290],{"class":289},[272,789,335],{"class":293},[272,791,403],{"class":289},[272,793,373],{"class":289},[272,795,796,799,803,806,808],{"class":274,"line":340},[272,797,798],{"class":781},"  interface",[272,800,802],{"class":801},"s5Dmg"," PostsCollectionItem",[272,804,805],{"class":781}," extends",[272,807,757],{"class":801},[272,809,373],{"class":289},[272,811,812,815,817,820],{"class":274,"line":345},[272,813,814],{"class":366},"    title",[272,816,370],{"class":289},[272,818,819],{"class":801}," string",[272,821,822],{"class":289},";\n",[272,824,825,828,830,832],{"class":274,"line":363},[272,826,827],{"class":366},"    description",[272,829,370],{"class":289},[272,831,819],{"class":801},[272,833,822],{"class":289},[272,835,836,839,841,843],{"class":274,"line":376},[272,837,838],{"class":366},"    publishedAt",[272,840,370],{"class":289},[272,842,819],{"class":801},[272,844,822],{"class":289},[272,846,847,850,852,854],{"class":274,"line":390},[272,848,849],{"class":366},"    updatedAt",[272,851,370],{"class":289},[272,853,819],{"class":801},[272,855,822],{"class":289},[272,857,858,861,863,865,868],{"class":274,"line":409},[272,859,860],{"class":366},"    categories",[272,862,370],{"class":289},[272,864,819],{"class":801},[272,866,867],{"class":366},"[]",[272,869,822],{"class":289},[272,871,872,875,877,880],{"class":274,"line":419},[272,873,874],{"class":366},"    draft",[272,876,370],{"class":289},[272,878,879],{"class":801}," boolean",[272,881,822],{"class":289},[272,883,884,887,889,891],{"class":274,"line":449},[272,885,886],{"class":366},"    secret",[272,888,370],{"class":289},[272,890,879],{"class":801},[272,892,822],{"class":289},[272,894,895,898,900,903],{"class":274,"line":466},[272,896,897],{"class":366},"    priority",[272,899,370],{"class":289},[272,901,902],{"class":801}," number",[272,904,822],{"class":289},[272,906,907],{"class":274,"line":472},[272,908,909],{"class":289},"  }\n",[272,911,912],{"class":274,"line":491},[272,913,302],{"emptyLinePlaceholder":169},[272,915,916,918,921],{"class":274,"line":511},[272,917,798],{"class":781},[272,919,920],{"class":801}," PageCollections",[272,922,373],{"class":289},[272,924,925,927,929],{"class":274,"line":529},[272,926,379],{"class":366},[272,928,370],{"class":289},[272,930,931],{"class":801}," PostsCollectionItem\n",[272,933,934],{"class":274,"line":547},[272,935,909],{"class":289},[272,937,938],{"class":274,"line":565},[272,939,302],{"emptyLinePlaceholder":169},[272,941,942,944,947],{"class":274,"line":592},[272,943,798],{"class":781},[272,945,946],{"class":801}," Collections",[272,948,373],{"class":289},[272,950,951,953,955],{"class":274,"line":611},[272,952,379],{"class":366},[272,954,370],{"class":289},[272,956,931],{"class":801},[272,958,959],{"class":274,"line":629},[272,960,909],{"class":289},[272,962,963],{"class":274,"line":648},[272,964,965],{"class":289},"}\n",[245,967,969,972,973,976],{"id":968},"markdown-に関する設定を-build-プロパティでラップするように",[203,970,971],{},"markdown"," に関する設定を ",[203,974,975],{},"build"," プロパティでラップするように",[15,978,979,980,983,984,986],{},"マイグレーションガイドには特に記載はなかったのですが、",[203,981,982],{},"nuxt.config.ts"," に書くマークダウンに関する設定たちを ",[203,985,975],{}," プロパティでラップします。",[264,988,992],{"className":989,"code":990,"filename":982,"language":991,"meta":154,"style":154},"language-diff shiki shiki-themes material-theme","diff --git a\u002Fnuxt.config.ts b\u002Fnuxt.config.ts\nindex c1858fd..c8995e4 100644\n--- a\u002Fnuxt.config.ts\n+++ b\u002Fnuxt.config.ts\n@@ -42,45 +42,45 @@ export default defineNuxtConfig({\n   },\n\n   content: {\n-    markdown: {\n-      rehypePlugins: [\n-        [\n-          'rehype-external-links', {\n+    build: {\n+      markdown: {\n+        rehypePlugins: {\n+          'rehype-external-links': {\n             target: '_blank',\n             rel: 'nofollow noopener noreferrer',\n           },\n-        ],\n-      ],\n-    },\n+        },\n\n-    highlight: {\n-      theme: {\n-        default: 'material-theme',\n-      },\n+        highlight: {\n+          theme: {\n+            default: 'material-theme',\n+          },\n\n-      langs: [\n-        'json',\n-        'js',\n-        'ts',\n-        'html',\n-        'css',\n-        'vue',\n-        'shell',\n-        'mdc',\n-        'md',\n-        'yaml',\n-        'dart',\n-        'xml',\n-        'csv',\n-        'ruby',\n-        'go',\n-        'diff',\n-        'docker',\n-        'dotenv',\n-        'python',\n-        'scss',\n-        'sql',\n-      ],\n+          langs: [\n+            'json',\n+            'js',\n+            'ts',\n+            'html',\n+            'css',\n+            'vue',\n+            'shell',\n+            'mdc',\n+            'md',\n+            'yaml',\n+            'dart',\n+            'xml',\n+            'csv',\n+            'ruby',\n+            'go',\n+            'diff',\n+            'docker',\n+            'dotenv',\n+            'python',\n+            'scss',\n+            'sql',\n+          ],\n+        },\n+      },\n     },\n   },\n","diff",[203,993,994,999,1004,1012,1020,1033,1038,1042,1047,1055,1062,1069,1076,1084,1091,1098,1105,1110,1115,1120,1127,1134,1141,1148,1152,1159,1167,1175,1182,1190,1198,1206,1214,1219,1227,1235,1243,1251,1259,1267,1275,1283,1291,1299,1307,1315,1323,1331,1339,1347,1355,1363,1371,1379,1387,1395,1402,1410,1418,1426,1434,1442,1450,1458,1466,1474,1482,1490,1498,1506,1514,1522,1530,1538,1546,1554,1562,1570,1578,1586,1593,1600,1606],{"__ignoreMap":154},[272,995,996],{"class":274,"line":275},[272,997,998],{"class":282},"diff --git a\u002Fnuxt.config.ts b\u002Fnuxt.config.ts\n",[272,1000,1001],{"class":274,"line":155},[272,1002,1003],{"class":282},"index c1858fd..c8995e4 100644\n",[272,1005,1006,1009],{"class":274,"line":305},[272,1007,1008],{"class":289},"---",[272,1010,1011],{"class":282}," a\u002Fnuxt.config.ts\n",[272,1013,1014,1017],{"class":274,"line":340},[272,1015,1016],{"class":289},"+++",[272,1018,1019],{"class":282}," b\u002Fnuxt.config.ts\n",[272,1021,1022,1025,1028,1030],{"class":274,"line":345},[272,1023,1024],{"class":289},"@@",[272,1026,1027],{"class":282}," -42,45 +42,45 ",[272,1029,1024],{"class":289},[272,1031,1032],{"class":282}," export default defineNuxtConfig({\n",[272,1034,1035],{"class":274,"line":363},[272,1036,1037],{"class":282},"   },\n",[272,1039,1040],{"class":274,"line":376},[272,1041,302],{"emptyLinePlaceholder":169},[272,1043,1044],{"class":274,"line":390},[272,1045,1046],{"class":282},"   content: {\n",[272,1048,1049,1052],{"class":274,"line":409},[272,1050,1051],{"class":289},"-",[272,1053,1054],{"class":366},"    markdown: {\n",[272,1056,1057,1059],{"class":274,"line":419},[272,1058,1051],{"class":289},[272,1060,1061],{"class":366},"      rehypePlugins: [\n",[272,1063,1064,1066],{"class":274,"line":449},[272,1065,1051],{"class":289},[272,1067,1068],{"class":366},"        [\n",[272,1070,1071,1073],{"class":274,"line":466},[272,1072,1051],{"class":289},[272,1074,1075],{"class":366},"          'rehype-external-links', {\n",[272,1077,1078,1081],{"class":274,"line":472},[272,1079,1080],{"class":289},"+",[272,1082,1083],{"class":293},"    build: {\n",[272,1085,1086,1088],{"class":274,"line":491},[272,1087,1080],{"class":289},[272,1089,1090],{"class":293},"      markdown: {\n",[272,1092,1093,1095],{"class":274,"line":511},[272,1094,1080],{"class":289},[272,1096,1097],{"class":293},"        rehypePlugins: {\n",[272,1099,1100,1102],{"class":274,"line":529},[272,1101,1080],{"class":289},[272,1103,1104],{"class":293},"          'rehype-external-links': {\n",[272,1106,1107],{"class":274,"line":547},[272,1108,1109],{"class":282},"             target: '_blank',\n",[272,1111,1112],{"class":274,"line":565},[272,1113,1114],{"class":282},"             rel: 'nofollow noopener noreferrer',\n",[272,1116,1117],{"class":274,"line":592},[272,1118,1119],{"class":282},"           },\n",[272,1121,1122,1124],{"class":274,"line":611},[272,1123,1051],{"class":289},[272,1125,1126],{"class":366},"        ],\n",[272,1128,1129,1131],{"class":274,"line":629},[272,1130,1051],{"class":289},[272,1132,1133],{"class":366},"      ],\n",[272,1135,1136,1138],{"class":274,"line":648},[272,1137,1051],{"class":289},[272,1139,1140],{"class":366},"    },\n",[272,1142,1143,1145],{"class":274,"line":658},[272,1144,1080],{"class":289},[272,1146,1147],{"class":293},"        },\n",[272,1149,1150],{"class":274,"line":668},[272,1151,302],{"emptyLinePlaceholder":169},[272,1153,1154,1156],{"class":274,"line":674},[272,1155,1051],{"class":289},[272,1157,1158],{"class":366},"    highlight: {\n",[272,1160,1162,1164],{"class":274,"line":1161},26,[272,1163,1051],{"class":289},[272,1165,1166],{"class":366},"      theme: {\n",[272,1168,1170,1172],{"class":274,"line":1169},27,[272,1171,1051],{"class":289},[272,1173,1174],{"class":366},"        default: 'material-theme',\n",[272,1176,1178,1180],{"class":274,"line":1177},28,[272,1179,1051],{"class":289},[272,1181,469],{"class":366},[272,1183,1185,1187],{"class":274,"line":1184},29,[272,1186,1080],{"class":289},[272,1188,1189],{"class":293},"        highlight: {\n",[272,1191,1193,1195],{"class":274,"line":1192},30,[272,1194,1080],{"class":289},[272,1196,1197],{"class":293},"          theme: {\n",[272,1199,1201,1203],{"class":274,"line":1200},31,[272,1202,1080],{"class":289},[272,1204,1205],{"class":293},"            default: 'material-theme',\n",[272,1207,1209,1211],{"class":274,"line":1208},32,[272,1210,1080],{"class":289},[272,1212,1213],{"class":293},"          },\n",[272,1215,1217],{"class":274,"line":1216},33,[272,1218,302],{"emptyLinePlaceholder":169},[272,1220,1222,1224],{"class":274,"line":1221},34,[272,1223,1051],{"class":289},[272,1225,1226],{"class":366},"      langs: [\n",[272,1228,1230,1232],{"class":274,"line":1229},35,[272,1231,1051],{"class":289},[272,1233,1234],{"class":366},"        'json',\n",[272,1236,1238,1240],{"class":274,"line":1237},36,[272,1239,1051],{"class":289},[272,1241,1242],{"class":366},"        'js',\n",[272,1244,1246,1248],{"class":274,"line":1245},37,[272,1247,1051],{"class":289},[272,1249,1250],{"class":366},"        'ts',\n",[272,1252,1254,1256],{"class":274,"line":1253},38,[272,1255,1051],{"class":289},[272,1257,1258],{"class":366},"        'html',\n",[272,1260,1262,1264],{"class":274,"line":1261},39,[272,1263,1051],{"class":289},[272,1265,1266],{"class":366},"        'css',\n",[272,1268,1270,1272],{"class":274,"line":1269},40,[272,1271,1051],{"class":289},[272,1273,1274],{"class":366},"        'vue',\n",[272,1276,1278,1280],{"class":274,"line":1277},41,[272,1279,1051],{"class":289},[272,1281,1282],{"class":366},"        'shell',\n",[272,1284,1286,1288],{"class":274,"line":1285},42,[272,1287,1051],{"class":289},[272,1289,1290],{"class":366},"        'mdc',\n",[272,1292,1294,1296],{"class":274,"line":1293},43,[272,1295,1051],{"class":289},[272,1297,1298],{"class":366},"        'md',\n",[272,1300,1302,1304],{"class":274,"line":1301},44,[272,1303,1051],{"class":289},[272,1305,1306],{"class":366},"        'yaml',\n",[272,1308,1310,1312],{"class":274,"line":1309},45,[272,1311,1051],{"class":289},[272,1313,1314],{"class":366},"        'dart',\n",[272,1316,1318,1320],{"class":274,"line":1317},46,[272,1319,1051],{"class":289},[272,1321,1322],{"class":366},"        'xml',\n",[272,1324,1326,1328],{"class":274,"line":1325},47,[272,1327,1051],{"class":289},[272,1329,1330],{"class":366},"        'csv',\n",[272,1332,1334,1336],{"class":274,"line":1333},48,[272,1335,1051],{"class":289},[272,1337,1338],{"class":366},"        'ruby',\n",[272,1340,1342,1344],{"class":274,"line":1341},49,[272,1343,1051],{"class":289},[272,1345,1346],{"class":366},"        'go',\n",[272,1348,1350,1352],{"class":274,"line":1349},50,[272,1351,1051],{"class":289},[272,1353,1354],{"class":366},"        'diff',\n",[272,1356,1358,1360],{"class":274,"line":1357},51,[272,1359,1051],{"class":289},[272,1361,1362],{"class":366},"        'docker',\n",[272,1364,1366,1368],{"class":274,"line":1365},52,[272,1367,1051],{"class":289},[272,1369,1370],{"class":366},"        'dotenv',\n",[272,1372,1374,1376],{"class":274,"line":1373},53,[272,1375,1051],{"class":289},[272,1377,1378],{"class":366},"        'python',\n",[272,1380,1382,1384],{"class":274,"line":1381},54,[272,1383,1051],{"class":289},[272,1385,1386],{"class":366},"        'scss',\n",[272,1388,1390,1392],{"class":274,"line":1389},55,[272,1391,1051],{"class":289},[272,1393,1394],{"class":366},"        'sql',\n",[272,1396,1398,1400],{"class":274,"line":1397},56,[272,1399,1051],{"class":289},[272,1401,1133],{"class":366},[272,1403,1405,1407],{"class":274,"line":1404},57,[272,1406,1080],{"class":289},[272,1408,1409],{"class":293},"          langs: [\n",[272,1411,1413,1415],{"class":274,"line":1412},58,[272,1414,1080],{"class":289},[272,1416,1417],{"class":293},"            'json',\n",[272,1419,1421,1423],{"class":274,"line":1420},59,[272,1422,1080],{"class":289},[272,1424,1425],{"class":293},"            'js',\n",[272,1427,1429,1431],{"class":274,"line":1428},60,[272,1430,1080],{"class":289},[272,1432,1433],{"class":293},"            'ts',\n",[272,1435,1437,1439],{"class":274,"line":1436},61,[272,1438,1080],{"class":289},[272,1440,1441],{"class":293},"            'html',\n",[272,1443,1445,1447],{"class":274,"line":1444},62,[272,1446,1080],{"class":289},[272,1448,1449],{"class":293},"            'css',\n",[272,1451,1453,1455],{"class":274,"line":1452},63,[272,1454,1080],{"class":289},[272,1456,1457],{"class":293},"            'vue',\n",[272,1459,1461,1463],{"class":274,"line":1460},64,[272,1462,1080],{"class":289},[272,1464,1465],{"class":293},"            'shell',\n",[272,1467,1469,1471],{"class":274,"line":1468},65,[272,1470,1080],{"class":289},[272,1472,1473],{"class":293},"            'mdc',\n",[272,1475,1477,1479],{"class":274,"line":1476},66,[272,1478,1080],{"class":289},[272,1480,1481],{"class":293},"            'md',\n",[272,1483,1485,1487],{"class":274,"line":1484},67,[272,1486,1080],{"class":289},[272,1488,1489],{"class":293},"            'yaml',\n",[272,1491,1493,1495],{"class":274,"line":1492},68,[272,1494,1080],{"class":289},[272,1496,1497],{"class":293},"            'dart',\n",[272,1499,1501,1503],{"class":274,"line":1500},69,[272,1502,1080],{"class":289},[272,1504,1505],{"class":293},"            'xml',\n",[272,1507,1509,1511],{"class":274,"line":1508},70,[272,1510,1080],{"class":289},[272,1512,1513],{"class":293},"            'csv',\n",[272,1515,1517,1519],{"class":274,"line":1516},71,[272,1518,1080],{"class":289},[272,1520,1521],{"class":293},"            'ruby',\n",[272,1523,1525,1527],{"class":274,"line":1524},72,[272,1526,1080],{"class":289},[272,1528,1529],{"class":293},"            'go',\n",[272,1531,1533,1535],{"class":274,"line":1532},73,[272,1534,1080],{"class":289},[272,1536,1537],{"class":293},"            'diff',\n",[272,1539,1541,1543],{"class":274,"line":1540},74,[272,1542,1080],{"class":289},[272,1544,1545],{"class":293},"            'docker',\n",[272,1547,1549,1551],{"class":274,"line":1548},75,[272,1550,1080],{"class":289},[272,1552,1553],{"class":293},"            'dotenv',\n",[272,1555,1557,1559],{"class":274,"line":1556},76,[272,1558,1080],{"class":289},[272,1560,1561],{"class":293},"            'python',\n",[272,1563,1565,1567],{"class":274,"line":1564},77,[272,1566,1080],{"class":289},[272,1568,1569],{"class":293},"            'scss',\n",[272,1571,1573,1575],{"class":274,"line":1572},78,[272,1574,1080],{"class":289},[272,1576,1577],{"class":293},"            'sql',\n",[272,1579,1581,1583],{"class":274,"line":1580},79,[272,1582,1080],{"class":289},[272,1584,1585],{"class":293},"          ],\n",[272,1587,1589,1591],{"class":274,"line":1588},80,[272,1590,1080],{"class":289},[272,1592,1147],{"class":293},[272,1594,1596,1598],{"class":274,"line":1595},81,[272,1597,1080],{"class":289},[272,1599,469],{"class":293},[272,1601,1603],{"class":274,"line":1602},82,[272,1604,1605],{"class":282},"     },\n",[272,1607,1609],{"class":274,"line":1608},83,[272,1610,1037],{"class":282},[245,1612,1614],{"id":1613},"コンテンツの内部プロパティ名から-_-の接頭語をなくす","コンテンツの内部プロパティ名から _ の接頭語をなくす",[15,1616,1617,1618,1621,1622,1624],{},"取得したコンテンツの内部プロパティは接頭語を外したものにリネームされました。このブログでは記事へのパスを参照しているので、プロパティを ",[203,1619,1620],{},"_path"," から ",[203,1623,294],{}," に変更しました。",[264,1626,1629],{"className":989,"code":1627,"filename":1628,"language":991,"meta":154,"style":154},"diff --git a\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue b\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\nindex f119d51..085f0c1 100644\n--- a\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\n+++ b\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\n@@ -9,7 +9,7 @@ const props = defineProps\u003C{\n }>()\n\n const thumbnailPath = computed(() => {\n-  return `\u002Fcontent\u002F${props.content._path?.split('\u002F')[2]}\u002Fthumbnail.png`\n+  return `\u002Fcontent\u002F${props.content.path?.split('\u002F')[2]}\u002Fthumbnail.png`\n })\n \u003C\u002Fscript>\n\n@@ -21,7 +21,7 @@ const thumbnailPath = computed(() => {\n     \u003CULink\n       :tabindex=\"-1\"\n       :aria-hidden=\"true\"\n-      :to=\"`\u002Fposts${content._path}`\"\n+      :to=\"`\u002Fposts${content.path}`\"\n       class=\"absolute inset-0\"\n     \u002F>\n","PostCard.diff",[203,1630,1631,1636,1641,1648,1655,1667,1672,1676,1681,1688,1695,1700,1705,1709,1720,1725,1730,1735,1742,1749,1754],{"__ignoreMap":154},[272,1632,1633],{"class":274,"line":275},[272,1634,1635],{"class":282},"diff --git a\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue b\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\n",[272,1637,1638],{"class":274,"line":155},[272,1639,1640],{"class":282},"index f119d51..085f0c1 100644\n",[272,1642,1643,1645],{"class":274,"line":305},[272,1644,1008],{"class":289},[272,1646,1647],{"class":282}," a\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\n",[272,1649,1650,1652],{"class":274,"line":340},[272,1651,1016],{"class":289},[272,1653,1654],{"class":282}," b\u002Fsrc\u002Fcomponents\u002Fpost\u002FPostCard.vue\n",[272,1656,1657,1659,1662,1664],{"class":274,"line":345},[272,1658,1024],{"class":289},[272,1660,1661],{"class":282}," -9,7 +9,7 ",[272,1663,1024],{"class":289},[272,1665,1666],{"class":282}," const props = defineProps\u003C{\n",[272,1668,1669],{"class":274,"line":363},[272,1670,1671],{"class":282}," }>()\n",[272,1673,1674],{"class":274,"line":376},[272,1675,302],{"emptyLinePlaceholder":169},[272,1677,1678],{"class":274,"line":390},[272,1679,1680],{"class":282}," const thumbnailPath = computed(() => {\n",[272,1682,1683,1685],{"class":274,"line":409},[272,1684,1051],{"class":289},[272,1686,1687],{"class":366},"  return `\u002Fcontent\u002F${props.content._path?.split('\u002F')[2]}\u002Fthumbnail.png`\n",[272,1689,1690,1692],{"class":274,"line":419},[272,1691,1080],{"class":289},[272,1693,1694],{"class":293},"  return `\u002Fcontent\u002F${props.content.path?.split('\u002F')[2]}\u002Fthumbnail.png`\n",[272,1696,1697],{"class":274,"line":449},[272,1698,1699],{"class":282}," })\n",[272,1701,1702],{"class":274,"line":466},[272,1703,1704],{"class":282}," \u003C\u002Fscript>\n",[272,1706,1707],{"class":274,"line":472},[272,1708,302],{"emptyLinePlaceholder":169},[272,1710,1711,1713,1716,1718],{"class":274,"line":491},[272,1712,1024],{"class":289},[272,1714,1715],{"class":282}," -21,7 +21,7 ",[272,1717,1024],{"class":289},[272,1719,1680],{"class":282},[272,1721,1722],{"class":274,"line":511},[272,1723,1724],{"class":282},"     \u003CULink\n",[272,1726,1727],{"class":274,"line":529},[272,1728,1729],{"class":282},"       :tabindex=\"-1\"\n",[272,1731,1732],{"class":274,"line":547},[272,1733,1734],{"class":282},"       :aria-hidden=\"true\"\n",[272,1736,1737,1739],{"class":274,"line":565},[272,1738,1051],{"class":289},[272,1740,1741],{"class":366},"      :to=\"`\u002Fposts${content._path}`\"\n",[272,1743,1744,1746],{"class":274,"line":592},[272,1745,1080],{"class":289},[272,1747,1748],{"class":293},"      :to=\"`\u002Fposts${content.path}`\"\n",[272,1750,1751],{"class":274,"line":611},[272,1752,1753],{"class":282},"       class=\"absolute inset-0\"\n",[272,1755,1756],{"class":274,"line":629},[272,1757,1758],{"class":282},"     \u002F>\n",[245,1760,1761],{"id":1761},"記事の取得方法の変更",[15,1763,1764,1765,1767,1768,1621,1770,1773,1774,1777],{},"表示するコンテンツを変更するには定義した ",[203,1766,254],{}," から動的に取得します。",[203,1769,689],{},[203,1771,1772],{},"queryCollection"," にリネームされ、collection を指定することで使えます。",[203,1775,1776],{},"MongoDB"," のような NoSQL ベースのクエリから、SQL ベースのクエリに変更されました。",[264,1779,1782],{"className":989,"code":1780,"filename":1781,"language":991,"meta":154,"style":154}," const fetchAllCountByCategories = async (): Promise\u003Cnumber> => {\n-  return queryContent\u003CCustomParsedContent>()\n-    .where({\n-      categories: { $contains: cateogryParams.value },\n-      draft: { $not: true },\n-      secret: { $not: true },\n-    })\n+  return queryCollection('posts')\n+    .where('categories', 'LIKE', `%${cateogryParams.value}%`)\n+    .andWhere((query) => query.where('draft', 'IS NULL').where('secret', 'IS NULL'))\n     .count()\n }\n","queryCollection.diff",[203,1783,1784,1789,1796,1803,1810,1817,1824,1831,1838,1845,1852,1857],{"__ignoreMap":154},[272,1785,1786],{"class":274,"line":275},[272,1787,1788],{"class":282}," const fetchAllCountByCategories = async (): Promise\u003Cnumber> => {\n",[272,1790,1791,1793],{"class":274,"line":155},[272,1792,1051],{"class":289},[272,1794,1795],{"class":366},"  return queryContent\u003CCustomParsedContent>()\n",[272,1797,1798,1800],{"class":274,"line":305},[272,1799,1051],{"class":289},[272,1801,1802],{"class":366},"    .where({\n",[272,1804,1805,1807],{"class":274,"line":340},[272,1806,1051],{"class":289},[272,1808,1809],{"class":366},"      categories: { $contains: cateogryParams.value },\n",[272,1811,1812,1814],{"class":274,"line":345},[272,1813,1051],{"class":289},[272,1815,1816],{"class":366},"      draft: { $not: true },\n",[272,1818,1819,1821],{"class":274,"line":363},[272,1820,1051],{"class":289},[272,1822,1823],{"class":366},"      secret: { $not: true },\n",[272,1825,1826,1828],{"class":274,"line":376},[272,1827,1051],{"class":289},[272,1829,1830],{"class":366},"    })\n",[272,1832,1833,1835],{"class":274,"line":390},[272,1834,1080],{"class":289},[272,1836,1837],{"class":293},"  return queryCollection('posts')\n",[272,1839,1840,1842],{"class":274,"line":409},[272,1841,1080],{"class":289},[272,1843,1844],{"class":293},"    .where('categories', 'LIKE', `%${cateogryParams.value}%`)\n",[272,1846,1847,1849],{"class":274,"line":419},[272,1848,1080],{"class":289},[272,1850,1851],{"class":293},"    .andWhere((query) => query.where('draft', 'IS NULL').where('secret', 'IS NULL'))\n",[272,1853,1854],{"class":274,"line":449},[272,1855,1856],{"class":282},"     .count()\n",[272,1858,1859],{"class":274,"line":466},[272,1860,1861],{"class":282}," }\n",[15,1863,1864,1865,1867],{},"nitro のサーバー側でもリネームの変更を受け、同じく ",[203,1866,1772],{}," を使います。このブログでは、Google Search Console に sitemap を登録しており、nitro を利用して sitemap.xml を返却するエンドポイントを用意しています。",[264,1869,1872],{"className":989,"code":1870,"filename":1871,"language":991,"meta":154,"style":154},"diff --git a\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts b\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\nindex ab867c1..050a821 100644\n--- a\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\n+++ b\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\n@@ -1,13 +1,10 @@\n import { join } from 'path'\n\n-import { defineEventHandler } from '#imports'\n+import { defineEventHandler, queryCollection } from '#imports'\n import { SitemapStream, streamToPromise } from 'sitemap'\n\n-import { serverQueryContent } from '#content\u002Fserver'\n-import type { CustomParsedContent } from '~\u002Ftypes\u002Fcontent'\n-\n export default defineEventHandler(async (event) => {\n-  const docs = await serverQueryContent\u003CCustomParsedContent>(event).find()\n+  const docs = await queryCollection(event, 'posts').all()\n   const sitemap = new SitemapStream({\n     hostname: 'https:\u002F\u002Foffich.me',\n     lastmodDateOnly: true,\n","sitemap.diff",[203,1873,1874,1879,1884,1891,1898,1908,1913,1917,1924,1931,1936,1940,1947,1954,1959,1964,1971,1978,1983,1988],{"__ignoreMap":154},[272,1875,1876],{"class":274,"line":275},[272,1877,1878],{"class":282},"diff --git a\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts b\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\n",[272,1880,1881],{"class":274,"line":155},[272,1882,1883],{"class":282},"index ab867c1..050a821 100644\n",[272,1885,1886,1888],{"class":274,"line":305},[272,1887,1008],{"class":289},[272,1889,1890],{"class":282}," a\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\n",[272,1892,1893,1895],{"class":274,"line":340},[272,1894,1016],{"class":289},[272,1896,1897],{"class":282}," b\u002Fsrc\u002Fserver\u002Froutes\u002Fsitemap.xml.ts\n",[272,1899,1900,1902,1905],{"class":274,"line":345},[272,1901,1024],{"class":289},[272,1903,1904],{"class":282}," -1,13 +1,10 ",[272,1906,1907],{"class":289},"@@\n",[272,1909,1910],{"class":274,"line":363},[272,1911,1912],{"class":282}," import { join } from 'path'\n",[272,1914,1915],{"class":274,"line":376},[272,1916,302],{"emptyLinePlaceholder":169},[272,1918,1919,1921],{"class":274,"line":390},[272,1920,1051],{"class":289},[272,1922,1923],{"class":366},"import { defineEventHandler } from '#imports'\n",[272,1925,1926,1928],{"class":274,"line":409},[272,1927,1080],{"class":289},[272,1929,1930],{"class":293},"import { defineEventHandler, queryCollection } from '#imports'\n",[272,1932,1933],{"class":274,"line":419},[272,1934,1935],{"class":282}," import { SitemapStream, streamToPromise } from 'sitemap'\n",[272,1937,1938],{"class":274,"line":449},[272,1939,302],{"emptyLinePlaceholder":169},[272,1941,1942,1944],{"class":274,"line":466},[272,1943,1051],{"class":289},[272,1945,1946],{"class":366},"import { serverQueryContent } from '#content\u002Fserver'\n",[272,1948,1949,1951],{"class":274,"line":472},[272,1950,1051],{"class":289},[272,1952,1953],{"class":366},"import type { CustomParsedContent } from '~\u002Ftypes\u002Fcontent'\n",[272,1955,1956],{"class":274,"line":491},[272,1957,1958],{"class":289},"-\n",[272,1960,1961],{"class":274,"line":511},[272,1962,1963],{"class":282}," export default defineEventHandler(async (event) => {\n",[272,1965,1966,1968],{"class":274,"line":529},[272,1967,1051],{"class":289},[272,1969,1970],{"class":366},"  const docs = await serverQueryContent\u003CCustomParsedContent>(event).find()\n",[272,1972,1973,1975],{"class":274,"line":547},[272,1974,1080],{"class":289},[272,1976,1977],{"class":293},"  const docs = await queryCollection(event, 'posts').all()\n",[272,1979,1980],{"class":274,"line":565},[272,1981,1982],{"class":282},"   const sitemap = new SitemapStream({\n",[272,1984,1985],{"class":274,"line":592},[272,1986,1987],{"class":282},"     hostname: 'https:\u002F\u002Foffich.me',\n",[272,1989,1990],{"class":274,"line":611},[272,1991,1992],{"class":282},"     lastmodDateOnly: true,\n",[15,1994,1995,1996,1999,2000,2003],{},"コンテンツの前後のものを取得する ",[203,1997,1998],{},"findSurround"," も ",[203,2001,2002],{},"queryCollectionItemSurroundings"," という API と使って取得します。",[264,2005,2008],{"className":989,"code":2006,"filename":2007,"language":991,"meta":154,"style":154},"diff --git a\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue b\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\nindex cfde233..02e684f 100644\n--- a\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\n+++ b\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\n@@ -38,9 +36,9 @@ useSeoMeta({\n const { data: surround } = await useAsyncData(\n   `docs-${routePath.value}-surround`,\n   () => {\n-    return queryContent\u003CCustomParsedContent>()\n-      .where({ _extension: 'md', navigation: { $ne: false }, draft: { $not: true }, secret: { $not: true } })\n-      .findSurround(routePath.value)\n+    return queryCollectionItemSurroundings('posts', routePath.value, { fields: ['title', 'description'] })\n+      .andWhere((query) => query.where('draft', 'IS NULL').where('secret', 'IS NULL'))\n   },\n   { default: () => [] },\n )\n","findSurround.diff",[203,2009,2010,2015,2020,2027,2034,2046,2051,2056,2061,2068,2075,2082,2089,2096,2100,2105],{"__ignoreMap":154},[272,2011,2012],{"class":274,"line":275},[272,2013,2014],{"class":282},"diff --git a\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue b\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\n",[272,2016,2017],{"class":274,"line":155},[272,2018,2019],{"class":282},"index cfde233..02e684f 100644\n",[272,2021,2022,2024],{"class":274,"line":305},[272,2023,1008],{"class":289},[272,2025,2026],{"class":282}," a\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\n",[272,2028,2029,2031],{"class":274,"line":340},[272,2030,1016],{"class":289},[272,2032,2033],{"class":282}," b\u002Fsrc\u002Fpages\u002Fposts\u002F[...slug].vue\n",[272,2035,2036,2038,2041,2043],{"class":274,"line":345},[272,2037,1024],{"class":289},[272,2039,2040],{"class":282}," -38,9 +36,9 ",[272,2042,1024],{"class":289},[272,2044,2045],{"class":282}," useSeoMeta({\n",[272,2047,2048],{"class":274,"line":363},[272,2049,2050],{"class":282}," const { data: surround } = await useAsyncData(\n",[272,2052,2053],{"class":274,"line":376},[272,2054,2055],{"class":282},"   `docs-${routePath.value}-surround`,\n",[272,2057,2058],{"class":274,"line":390},[272,2059,2060],{"class":282},"   () => {\n",[272,2062,2063,2065],{"class":274,"line":409},[272,2064,1051],{"class":289},[272,2066,2067],{"class":366},"    return queryContent\u003CCustomParsedContent>()\n",[272,2069,2070,2072],{"class":274,"line":419},[272,2071,1051],{"class":289},[272,2073,2074],{"class":366},"      .where({ _extension: 'md', navigation: { $ne: false }, draft: { $not: true }, secret: { $not: true } })\n",[272,2076,2077,2079],{"class":274,"line":449},[272,2078,1051],{"class":289},[272,2080,2081],{"class":366},"      .findSurround(routePath.value)\n",[272,2083,2084,2086],{"class":274,"line":466},[272,2085,1080],{"class":289},[272,2087,2088],{"class":293},"    return queryCollectionItemSurroundings('posts', routePath.value, { fields: ['title', 'description'] })\n",[272,2090,2091,2093],{"class":274,"line":472},[272,2092,1080],{"class":289},[272,2094,2095],{"class":293},"      .andWhere((query) => query.where('draft', 'IS NULL').where('secret', 'IS NULL'))\n",[272,2097,2098],{"class":274,"line":491},[272,2099,1037],{"class":282},[272,2101,2102],{"class":274,"line":511},[272,2103,2104],{"class":282},"   { default: () => [] },\n",[272,2106,2107],{"class":274,"line":529},[272,2108,2109],{"class":282}," )\n",[245,2111,2113,2116,2117,2116,2120,2123],{"id":2112},"prosepreprosecodeprosecodeinline-コンポーネントの統合",[203,2114,2115],{},"ProsePre","、",[203,2118,2119],{},"ProseCode",[203,2121,2122],{},"ProseCodeInline"," コンポーネントの統合",[15,2125,2126,2127,2130,2131,2134],{},"Nuxt content は MDC (Markdown Components) syntax を採用しており、コンテンツの内容に応じてコンポーネントが割り当てられ、HTML タグが描画されます。マークダウンの記法で、",[203,2128,2129],{},"`","(1 点バッグスラッシュ) と ",[203,2132,2133],{},"```","(3 点バックスラッシュ)を使うと、MDC がそれぞれインラインかブロックコードを描画します。",[15,2136,2137,2138,2141,2142,2147,2148,2151,2152,2116,2154,2116,2156,2158],{},"v3 は改めてそのコードを描画するコンポーネントたちの整理がされました。Nuxt content は ",[203,2139,2140],{},"@nuxtjs\u002Fmdc"," が提供している",[80,2143,2146],{"href":2144,"rel":2145,"target":87},"https:\u002F\u002Fgithub.com\u002Fnuxt-modules\u002Fmdc\u002Ftree\u002Fmain\u002Fsrc\u002Fruntime\u002Fcomponents\u002Fprose",[84,85,86],"コード描画のコンポーネント","(= Prose Components) を使用しています。",[203,2149,2150],{},"components\u002Fcontent"," ディレクトリに同じ名前のコンポーネントを作成することで、どう描画するかを自分で決められます。このとき ",[203,2153,2122],{},[203,2155,2119],{},[203,2157,2115],{}," をコンポーネントを自前で用意している人はマイグレート作業が発生します。",[15,2160,2161,2162,2164,2165,2167,2168,2170,2171,2173,2174,2176,2177,2179,2180,2182,2183,2185,2186,2188],{},"v2 で ",[203,2163,2122],{}," がただの ",[203,2166,2119],{}," のラッパーであることから、v3 ではインラインで書いてあるコードは ",[203,2169,2119],{}," と処理されます。またブロックコードは ",[203,2172,2119],{}," の代わりに、",[203,2175,2115],{}," として処理されます。そのため、",[203,2178,2122],{}," を ",[203,2181,2119],{}," にリネームし、",[203,2184,2119],{}," にあるロジックを ",[203,2187,2115],{}," に移動させれば、v3 へマイグレートできます。",[57,2190],{"link":2191},"https:\u002F\u002Fcontent.nuxt.com\u002Fdocs\u002Fgetting-started\u002Fmigration#consolidate-prosepre-prosecode-and-prosecodeinline-components",[11,2193,2194],{"id":2194},"まとめ",[15,2196,2197],{},"いかがだったでしょうか。Nuxt content についてのマイグレーションガイドを書きましたが、変更点が多いものとなりました。上記に書いたのはほんの一部で、場合によっては記載しなかったマイグレート作業が発生するので、注意が必要です。",[15,2199,2200,2201,2206],{},"特にデータベースの準備は破壊的変更だと感じました。幸いこのブログは SSG でビルドしている(",[80,2202,2205],{"href":2203,"rel":2204,"target":87},"https:\u002F\u002Fcontent.nuxt.com\u002Fdocs\u002Fdeploy\u002Fstatic#what-about-the-database",[84,85,86],"Static Hosting",")ので、データベースを用意する必要はありませんでしたが、大きな作業かと感じるのでリリースする前に動作検証をおすすめします。",[15,2208,2209],{},"v3 がリリースされたのは 1 月ですが、3 月末の現在でも新しいバージョンが次々とリリースされています。個人的にはブログを完成させてくれた技術というのもあり、これから使い続けるので、何かまた変更があれば、このブログでまとめたいと考えています。",[2211,2212,2213],"style",{},"html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}",{"title":154,"searchDepth":155,"depth":155,"links":2215},[2216,2217,2218,2227],{"id":197,"depth":155,"text":198},{"id":209,"depth":155,"text":210},{"id":234,"depth":155,"text":234,"children":2219},[2220,2221,2223,2224,2225],{"id":247,"depth":305,"text":248},{"id":968,"depth":305,"text":2222},"markdown に関する設定を build プロパティでラップするように",{"id":1613,"depth":305,"text":1614},{"id":1761,"depth":305,"text":1761},{"id":2112,"depth":305,"text":2226},"ProsePre、ProseCode、ProseCodeInline コンポーネントの統合",{"id":2194,"depth":155,"text":2194},[2229,2230],"Tech","Nuxt.js","Nuxt Content 2 から Nuxt Content 3 への移行に関するガイド",{},"\u002Ftech\u002Fnuxt-content-v3-migration","2025-03-28",{"title":178,"description":2231},"tech\u002Fnuxt-content-v3-migration","SfinixK_8I4k5tBTQcKPhboVfHkYr-VwQy3u3tAWa3Y",{"id":2239,"title":2240,"body":2241,"categories":5401,"description":2240,"draft":166,"extension":167,"meta":5404,"navigation":169,"path":5405,"priority":171,"publishedAt":5406,"secret":166,"seo":5407,"stem":5408,"updatedAt":5406,"__hash__":5409},"posts\u002Ftech\u002Fintroduction-to-ast.md","ts-morph で学ぶ AST 入門",{"type":8,"value":2242,"toc":5385},[2243,2246,2253,2256,2264,2268,2275,2278,2348,2357,2364,2367,2370,2384,2391,2394,2558,2562,2565,2568,2571,2889,2953,2956,2970,3380,3390,3394,3404,3407,3417,3653,3787,3797,3969,3973,3989,3993,4004,4007,4236,4391,4516,4520,4526,4547,4628,4631,5206,5210,5213,5353,5355,5358,5361,5364,5367,5370,5373,5376,5379,5382],[15,2244,2245],{},"過去の現場でフレームワークやライブラリの API がバージョンアップからの breaking change で、なかなかの書き換え作業を行なったことがある。そこで AST を使っての一括置換の手段があることを知った。2024 年は中規模以上のプロジェクトを 1 つ 1 つ手動で書き換えていくことの大変さを非常に痛感したので、しっかり身につけたいと感じる。",[15,2247,2248,2249,2252],{},"AST を利用してのソースコード書き換えは TypeScript Complier API で可能になるが、今回はそのラッパーライブラリの ",[203,2250,2251],{},"ts-morph"," を使っていきたい。ファイル内のソースコード置き換えをゴールにし、それまでの過程をまとめる。書き換え対象のソースコードは、TypeScript でのスクリプトの内容だけではなく、Vue.js SFC の script 内のコードの一部も含める。",[11,2254,2255],{"id":2255},"実行環境",[35,2257,2258,2261],{},[38,2259,2260],{},"TypeScript: 5.7.2",[38,2262,2263],{},"Deno: 2.1.4",[11,2265,2267],{"id":2266},"そもそも-ast-とは","そもそも AST とは",[15,2269,2270,2271,2274],{},"そもそも AST とは、 ",[203,2272,2273],{},"Abstract Syntax Tree"," の略で、ソースコードを構造化して表現した木構造のデータを指す。解析や加工ツールなどで使用され、コードを機械的に解釈・操作するために機能し、自分で手を加えることなくハックが可能となる。AST を利用している具体的ツールとしては、静的解析の eslint やフォーマッターの prettier などがある。",[15,2276,2277],{},"例えば、こんなコードを AST で表現したときに、",[264,2279,2282],{"className":266,"code":2280,"filename":2281,"language":268,"meta":154,"style":154},"const x = 10;\nif (x > 5) {\n  console.log(\"Hello\");\n}\n","source_file_example.ts",[203,2283,2284,2301,2320,2344],{"__ignoreMap":154},[272,2285,2286,2289,2292,2295,2299],{"class":274,"line":275},[272,2287,2288],{"class":781},"const",[272,2290,2291],{"class":282}," x ",[272,2293,2294],{"class":289},"=",[272,2296,2298],{"class":2297},"sx098"," 10",[272,2300,822],{"class":289},[272,2302,2303,2306,2309,2312,2315,2318],{"class":274,"line":155},[272,2304,2305],{"class":278},"if",[272,2307,2308],{"class":282}," (x ",[272,2310,2311],{"class":289},">",[272,2313,2314],{"class":2297}," 5",[272,2316,2317],{"class":282},") ",[272,2319,360],{"class":289},[272,2321,2322,2325,2327,2330,2332,2335,2338,2340,2342],{"class":274,"line":305},[272,2323,2324],{"class":282},"  console",[272,2326,430],{"class":289},[272,2328,2329],{"class":354},"log",[272,2331,357],{"class":366},[272,2333,2334],{"class":289},"\"",[272,2336,2337],{"class":293},"Hello",[272,2339,2334],{"class":289},[272,2341,188],{"class":366},[272,2343,822],{"class":289},[272,2345,2346],{"class":274,"line":340},[272,2347,965],{"class":289},[15,2349,2350,2351,2356],{},"こう表せる。解析した結果、枝分かれを作り、各々それぞれの枝のノードを ",[80,2352,2355],{"href":2353,"rel":2354,"target":87},"https:\u002F\u002Fgithub.com\u002Fmicrosoft\u002FTypeScript\u002Fblob\u002F56a08250f3516b3f5bc120d6c7ab4450a9a69352\u002Fsrc\u002Fcompiler\u002Ftypes.ts#L39-L490",[84,85,86],"SyntaxKind"," のどれかを当てはめている。対象の文言で検索をかけたり、置換対象のコードを探すときは、該当する SyntaxKind に当てはまるか否かの処理を書いていく。",[264,2358,2362],{"className":2359,"code":2360,"filename":2361,"language":726,"meta":154},[723],"Program\n├── VariableDeclaration (変数宣言)\n│   ├── Identifier (\"x\") (識別子)\n│   ├── NumericLiteral (10) (数字リテラル)\n├── IfStatement (if 構文)\n│   ├── BinaryExpression (x > 5) (バイナリ式)\n│   │   ├── Identifier (\"x\") (識別子)\n│   │   ├── NumericLiteral (5) (数字リテラル)\n│   ├── BlockStatement (ブロック構文)\n│       ├── ExpressionStatement　(式構文)\n│           ├── CallExpression (console.log) (式呼び出し)\n│               ├── MemberExpression (メンバー呼び出し)\n│               │   ├── Identifier (\"console\") (識別子)\n│               │   ├── Identifier (\"log\") (識別子)\n│               ├── StringLiteral (\"Hello\") (文字列リテラル)\n","source_file_abstract_syntax_tree.txt",[203,2363,2360],{"__ignoreMap":154},[15,2365,2366],{},"ソースコードを AST へ変換した結果は、このサイトで確認できる。",[57,2368],{"link":2369},"https:\u002F\u002Fts-ast-viewer.com",[15,2371,2372,2373,2376,2377,2376,2380,2383],{},"あとは用語として覚えておいくといいのが、 ",[203,2374,2375],{},"parser"," \u002F ",[203,2378,2379],{},"traverser, vistor or walker",[203,2381,2382],{},"generator"," の 3 つになる。ソースを解析して AST に当てはめるのと、AST を再起的に参照と変更を加え、そこからソースコードへ変換するまでの一連の流れになる。",[15,2385,2386,2387,2390],{},"余談だが、以前 textlint の既存ルールからのエラーを回避しようと、ソースコードの中を見ていくと、下のライブラリを使っていることがわかった。上で AST は静的解析ツールとして使われると言及したが、textlint もそれに該当する。用語を覚えることで、このライブラリが再起的にコードを参照する ",[203,2388,2389],{},"visitor"," を提供するライブラリであることがわかった。",[57,2392],{"link":2393},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002Funist-util-visit",[264,2395,2398],{"className":266,"code":2396,"filename":2397,"language":268,"meta":154,"style":154},"import { fromMarkdown } from 'mdast-util-from-markdown'\nimport { visit } from 'unist-util-visit'\n\nconst tree = fromMarkdown('Some *emphasis*, **strong**, and `code`.')\n\nvisit(tree, 'text', function (node, index, parent) {\n  console.log([node.value, parent ? parent.type : index])\n})\n","visit.ts",[203,2399,2400,2420,2440,2444,2466,2470,2512,2552],{"__ignoreMap":154},[272,2401,2402,2404,2406,2409,2411,2413,2415,2418],{"class":274,"line":275},[272,2403,279],{"class":278},[272,2405,310],{"class":289},[272,2407,2408],{"class":282}," fromMarkdown",[272,2410,327],{"class":289},[272,2412,330],{"class":278},[272,2414,290],{"class":289},[272,2416,2417],{"class":293},"mdast-util-from-markdown",[272,2419,297],{"class":289},[272,2421,2422,2424,2426,2429,2431,2433,2435,2438],{"class":274,"line":155},[272,2423,279],{"class":278},[272,2425,310],{"class":289},[272,2427,2428],{"class":282}," visit",[272,2430,327],{"class":289},[272,2432,330],{"class":278},[272,2434,290],{"class":289},[272,2436,2437],{"class":293},"unist-util-visit",[272,2439,297],{"class":289},[272,2441,2442],{"class":274,"line":305},[272,2443,302],{"emptyLinePlaceholder":169},[272,2445,2446,2448,2451,2453,2455,2457,2459,2462,2464],{"class":274,"line":340},[272,2447,2288],{"class":781},[272,2449,2450],{"class":282}," tree ",[272,2452,2294],{"class":289},[272,2454,2408],{"class":354},[272,2456,357],{"class":282},[272,2458,403],{"class":289},[272,2460,2461],{"class":293},"Some *emphasis*, **strong**, and `code`.",[272,2463,403],{"class":289},[272,2465,680],{"class":282},[272,2467,2468],{"class":274,"line":345},[272,2469,302],{"emptyLinePlaceholder":169},[272,2471,2472,2475,2478,2480,2482,2484,2486,2488,2491,2494,2498,2500,2503,2505,2508,2510],{"class":274,"line":363},[272,2473,2474],{"class":354},"visit",[272,2476,2477],{"class":282},"(tree",[272,2479,316],{"class":289},[272,2481,290],{"class":289},[272,2483,726],{"class":293},[272,2485,403],{"class":289},[272,2487,316],{"class":289},[272,2489,2490],{"class":781}," function",[272,2492,2493],{"class":289}," (",[272,2495,2497],{"class":2496},"sLFUT","node",[272,2499,316],{"class":289},[272,2501,2502],{"class":2496}," index",[272,2504,316],{"class":289},[272,2506,2507],{"class":2496}," parent",[272,2509,188],{"class":289},[272,2511,373],{"class":289},[272,2513,2514,2516,2518,2520,2523,2525,2527,2530,2532,2534,2537,2539,2541,2544,2547,2549],{"class":274,"line":376},[272,2515,2324],{"class":282},[272,2517,430],{"class":289},[272,2519,2329],{"class":354},[272,2521,2522],{"class":366},"([",[272,2524,2497],{"class":282},[272,2526,430],{"class":289},[272,2528,2529],{"class":282},"value",[272,2531,316],{"class":289},[272,2533,2507],{"class":282},[272,2535,2536],{"class":289}," ?",[272,2538,2507],{"class":282},[272,2540,430],{"class":289},[272,2542,2543],{"class":282},"type",[272,2545,2546],{"class":289}," :",[272,2548,2502],{"class":282},[272,2550,2551],{"class":366},"])\n",[272,2553,2554,2556],{"class":274,"line":390},[272,2555,677],{"class":289},[272,2557,680],{"class":282},[11,2559,2561],{"id":2560},"typescript-compiler-api-を使う","TypeScript Compiler API を使う",[15,2563,2564],{},"AST がどんなものを知れた後は、実際に各ノードを取得して、置換や生成していくのをどうやって行うかを見ていく。(ちなみにサンプルコードは Deno で動かしています。TypeScript で書ける node 開発環境をすぐ用意できました。Deno 便利。)",[245,2566,2567],{"id":2567},"各ノードの種類を出力する",[15,2569,2570],{},"AST へ変換したときにどんなノードたちで構成されているかを知れるコードです。",[264,2572,2575],{"className":266,"code":2573,"filename":2574,"language":268,"meta":154,"style":154},"import {\n  createSourceFile,\n  forEachChild,\n  Node,\n  ScriptKind,\n  ScriptTarget,\n  SourceFile,\n  SyntaxKind,\n} from \"typescript\";\n\n\u002F\u002F ソースコードを解析\nconst sourceCode = `\n  const x = 10;\n  if (x > 5) {\n    console.log(\"Hello\");\n  }\n`;\n\n\u002F\u002F ソースコードを AST に変換\nconst sourceFile = createSourceFile(\n  \"example.ts\", \u002F\u002F ファイル名 (仮の名前)\n  sourceCode,   \u002F\u002F 解析対象のコード\n  ScriptTarget.Latest, \u002F\u002F 言語レベル (最新を指定)\n  true           \u002F\u002F トークン解析を有効化\n);\n\n\u002F\u002F ノードを巡回して出力する関数\nfunction visit(node: Node) {\n  console.log(`${SyntaxKind[node.kind]}: ${node.getText()}`);\n  forEachChild(node, visit); \u002F\u002F 子ノードを再帰的に巡回\n}\n\n\u002F\u002F AST を巡回してノード情報を出力\nvisit(sourceFile);\n","print_syntax_kind.ts",[203,2576,2577,2583,2590,2597,2604,2611,2618,2625,2632,2648,2652,2658,2670,2675,2680,2685,2689,2695,2699,2704,2719,2734,2744,2758,2767,2773,2777,2782,2802,2847,2867,2871,2875,2880],{"__ignoreMap":154},[272,2578,2579,2581],{"class":274,"line":275},[272,2580,279],{"class":278},[272,2582,373],{"class":289},[272,2584,2585,2588],{"class":274,"line":155},[272,2586,2587],{"class":282},"  createSourceFile",[272,2589,406],{"class":289},[272,2591,2592,2595],{"class":274,"line":305},[272,2593,2594],{"class":282},"  forEachChild",[272,2596,406],{"class":289},[272,2598,2599,2602],{"class":274,"line":340},[272,2600,2601],{"class":282},"  Node",[272,2603,406],{"class":289},[272,2605,2606,2609],{"class":274,"line":345},[272,2607,2608],{"class":282},"  ScriptKind",[272,2610,406],{"class":289},[272,2612,2613,2616],{"class":274,"line":363},[272,2614,2615],{"class":282},"  ScriptTarget",[272,2617,406],{"class":289},[272,2619,2620,2623],{"class":274,"line":376},[272,2621,2622],{"class":282},"  SourceFile",[272,2624,406],{"class":289},[272,2626,2627,2630],{"class":274,"line":390},[272,2628,2629],{"class":282},"  SyntaxKind",[272,2631,406],{"class":289},[272,2633,2634,2636,2638,2641,2644,2646],{"class":274,"line":409},[272,2635,677],{"class":289},[272,2637,330],{"class":278},[272,2639,2640],{"class":289}," \"",[272,2642,2643],{"class":293},"typescript",[272,2645,2334],{"class":289},[272,2647,822],{"class":289},[272,2649,2650],{"class":274,"line":419},[272,2651,302],{"emptyLinePlaceholder":169},[272,2653,2654],{"class":274,"line":449},[272,2655,2657],{"class":2656},"s0_hs","\u002F\u002F ソースコードを解析\n",[272,2659,2660,2662,2665,2667],{"class":274,"line":466},[272,2661,2288],{"class":781},[272,2663,2664],{"class":282}," sourceCode ",[272,2666,2294],{"class":289},[272,2668,2669],{"class":289}," `\n",[272,2671,2672],{"class":274,"line":472},[272,2673,2674],{"class":293},"  const x = 10;\n",[272,2676,2677],{"class":274,"line":491},[272,2678,2679],{"class":293},"  if (x > 5) {\n",[272,2681,2682],{"class":274,"line":511},[272,2683,2684],{"class":293},"    console.log(\"Hello\");\n",[272,2686,2687],{"class":274,"line":529},[272,2688,909],{"class":293},[272,2690,2691,2693],{"class":274,"line":547},[272,2692,2129],{"class":289},[272,2694,822],{"class":289},[272,2696,2697],{"class":274,"line":565},[272,2698,302],{"emptyLinePlaceholder":169},[272,2700,2701],{"class":274,"line":592},[272,2702,2703],{"class":2656},"\u002F\u002F ソースコードを AST に変換\n",[272,2705,2706,2708,2711,2713,2716],{"class":274,"line":611},[272,2707,2288],{"class":781},[272,2709,2710],{"class":282}," sourceFile ",[272,2712,2294],{"class":289},[272,2714,2715],{"class":354}," createSourceFile",[272,2717,2718],{"class":282},"(\n",[272,2720,2721,2724,2727,2729,2731],{"class":274,"line":629},[272,2722,2723],{"class":289},"  \"",[272,2725,2726],{"class":293},"example.ts",[272,2728,2334],{"class":289},[272,2730,316],{"class":289},[272,2732,2733],{"class":2656}," \u002F\u002F ファイル名 (仮の名前)\n",[272,2735,2736,2739,2741],{"class":274,"line":648},[272,2737,2738],{"class":282},"  sourceCode",[272,2740,316],{"class":289},[272,2742,2743],{"class":2656},"   \u002F\u002F 解析対象のコード\n",[272,2745,2746,2748,2750,2753,2755],{"class":274,"line":658},[272,2747,2615],{"class":282},[272,2749,430],{"class":289},[272,2751,2752],{"class":282},"Latest",[272,2754,316],{"class":289},[272,2756,2757],{"class":2656}," \u002F\u002F 言語レベル (最新を指定)\n",[272,2759,2760,2764],{"class":274,"line":668},[272,2761,2763],{"class":2762},"sbqyR","  true",[272,2765,2766],{"class":2656},"           \u002F\u002F トークン解析を有効化\n",[272,2768,2769,2771],{"class":274,"line":674},[272,2770,188],{"class":282},[272,2772,822],{"class":289},[272,2774,2775],{"class":274,"line":1161},[272,2776,302],{"emptyLinePlaceholder":169},[272,2778,2779],{"class":274,"line":1169},[272,2780,2781],{"class":2656},"\u002F\u002F ノードを巡回して出力する関数\n",[272,2783,2784,2787,2789,2791,2793,2795,2798,2800],{"class":274,"line":1177},[272,2785,2786],{"class":781},"function",[272,2788,2428],{"class":354},[272,2790,357],{"class":289},[272,2792,2497],{"class":2496},[272,2794,370],{"class":289},[272,2796,2797],{"class":801}," Node",[272,2799,188],{"class":289},[272,2801,373],{"class":289},[272,2803,2804,2806,2808,2810,2812,2815,2818,2820,2823,2825,2828,2831,2833,2835,2838,2840,2843,2845],{"class":274,"line":1184},[272,2805,2324],{"class":282},[272,2807,430],{"class":289},[272,2809,2329],{"class":354},[272,2811,357],{"class":366},[272,2813,2814],{"class":289},"`${",[272,2816,2817],{"class":282},"SyntaxKind[node",[272,2819,430],{"class":289},[272,2821,2822],{"class":282},"kind]",[272,2824,677],{"class":289},[272,2826,2827],{"class":293},": ",[272,2829,2830],{"class":289},"${",[272,2832,2497],{"class":282},[272,2834,430],{"class":289},[272,2836,2837],{"class":354},"getText",[272,2839,506],{"class":282},[272,2841,2842],{"class":289},"}`",[272,2844,188],{"class":366},[272,2846,822],{"class":289},[272,2848,2849,2851,2853,2855,2857,2859,2861,2864],{"class":274,"line":1192},[272,2850,2594],{"class":354},[272,2852,357],{"class":366},[272,2854,2497],{"class":282},[272,2856,316],{"class":289},[272,2858,2428],{"class":282},[272,2860,188],{"class":366},[272,2862,2863],{"class":289},";",[272,2865,2866],{"class":2656}," \u002F\u002F 子ノードを再帰的に巡回\n",[272,2868,2869],{"class":274,"line":1200},[272,2870,965],{"class":289},[272,2872,2873],{"class":274,"line":1208},[272,2874,302],{"emptyLinePlaceholder":169},[272,2876,2877],{"class":274,"line":1216},[272,2878,2879],{"class":2656},"\u002F\u002F AST を巡回してノード情報を出力\n",[272,2881,2882,2884,2887],{"class":274,"line":1221},[272,2883,2474],{"class":354},[272,2885,2886],{"class":282},"(sourceFile)",[272,2888,822],{"class":289},[264,2890,2895],{"className":2891,"code":2892,"filename":2893,"language":2894,"meta":154,"style":154},"language-txt shiki shiki-themes material-theme","SourceFile: const x = 10;\n  if (x > 5) {\n    console.log(\"Hello\");\n  }\n\nExpressionStatement: console.log(\"Hello\");\nCallExpression: console.log(\"Hello\")\nPropertyAccessExpression: console.log\nIdentifier: console\nIdentifier: log\nStringLiteral: \"Hello\"\nEndOfFileToken:\n","result.txt","txt",[203,2896,2897,2902,2906,2910,2914,2918,2923,2928,2933,2938,2943,2948],{"__ignoreMap":154},[272,2898,2899],{"class":274,"line":275},[272,2900,2901],{},"SourceFile: const x = 10;\n",[272,2903,2904],{"class":274,"line":155},[272,2905,2679],{},[272,2907,2908],{"class":274,"line":305},[272,2909,2684],{},[272,2911,2912],{"class":274,"line":340},[272,2913,909],{},[272,2915,2916],{"class":274,"line":345},[272,2917,302],{"emptyLinePlaceholder":169},[272,2919,2920],{"class":274,"line":363},[272,2921,2922],{},"ExpressionStatement: console.log(\"Hello\");\n",[272,2924,2925],{"class":274,"line":376},[272,2926,2927],{},"CallExpression: console.log(\"Hello\")\n",[272,2929,2930],{"class":274,"line":390},[272,2931,2932],{},"PropertyAccessExpression: console.log\n",[272,2934,2935],{"class":274,"line":409},[272,2936,2937],{},"Identifier: console\n",[272,2939,2940],{"class":274,"line":419},[272,2941,2942],{},"Identifier: log\n",[272,2944,2945],{"class":274,"line":449},[272,2946,2947],{},"StringLiteral: \"Hello\"\n",[272,2949,2950],{"class":274,"line":466},[272,2951,2952],{},"EndOfFileToken:\n",[245,2954,2955],{"id":2955},"特定ノードのテキストを変換する",[15,2957,2958,2961,2962,2965,2966,2969],{},[203,2959,2960],{},"transformer"," を自ら作成し、対象のソースコードを変換できる。ポイントは再起的にツリー構造を見ていること。このスクリプトを実行すると、",[203,2963,2964],{},"x"," の部分を ",[203,2967,2968],{},"y"," に変更できる。",[264,2971,2974],{"className":266,"code":2972,"filename":2973,"language":268,"meta":154,"style":154},"\u002F\u002F ソースコード\nconst sourceCode = `\n  const x: number = 42;\n`;\n\n\u002F\u002F ソースコードを AST に変換\nconst sourceFile = createSourceFile(\n  \"example.ts\",\n  sourceCode,\n  ScriptTarget.Latest,\n  true,\n);\n\nconst renameTransformer = (): TransformerFactory\u003CSourceFile> => {\n  return (context) => (sourceFile) => {\n    const visitNode = (node: Node): Node => {\n      if (isIdentifier(node) && node.text === \"x\") {\n        return factory.createIdentifier(\"y\");\n      }\n\n      return visitEachChild(node, visitNode, context);\n    };\n\n    return visitEachChild(sourceFile, visitNode, context);\n  };\n};\n\n\u002F\u002F トランスフォーマーを適用\nconst result = transform(hogehoge, [renameTransformer()]);\n\n\u002F\u002F 新しい AST をコードとして出力\nconst printer = createPrinter();\nconsole.log(printer.printFile(result.transformed[0]));\n","transform.ts",[203,2975,2976,2981,2991,2996,3002,3006,3010,3022,3032,3038,3048,3054,3060,3064,3092,3117,3145,3184,3209,3214,3218,3243,3248,3252,3275,3280,3285,3289,3294,3322,3326,3331,3347],{"__ignoreMap":154},[272,2977,2978],{"class":274,"line":275},[272,2979,2980],{"class":2656},"\u002F\u002F ソースコード\n",[272,2982,2983,2985,2987,2989],{"class":274,"line":155},[272,2984,2288],{"class":781},[272,2986,2664],{"class":282},[272,2988,2294],{"class":289},[272,2990,2669],{"class":289},[272,2992,2993],{"class":274,"line":305},[272,2994,2995],{"class":293},"  const x: number = 42;\n",[272,2997,2998,3000],{"class":274,"line":340},[272,2999,2129],{"class":289},[272,3001,822],{"class":289},[272,3003,3004],{"class":274,"line":345},[272,3005,302],{"emptyLinePlaceholder":169},[272,3007,3008],{"class":274,"line":363},[272,3009,2703],{"class":2656},[272,3011,3012,3014,3016,3018,3020],{"class":274,"line":376},[272,3013,2288],{"class":781},[272,3015,2710],{"class":282},[272,3017,2294],{"class":289},[272,3019,2715],{"class":354},[272,3021,2718],{"class":282},[272,3023,3024,3026,3028,3030],{"class":274,"line":390},[272,3025,2723],{"class":289},[272,3027,2726],{"class":293},[272,3029,2334],{"class":289},[272,3031,406],{"class":289},[272,3033,3034,3036],{"class":274,"line":409},[272,3035,2738],{"class":282},[272,3037,406],{"class":289},[272,3039,3040,3042,3044,3046],{"class":274,"line":419},[272,3041,2615],{"class":282},[272,3043,430],{"class":289},[272,3045,2752],{"class":282},[272,3047,406],{"class":289},[272,3049,3050,3052],{"class":274,"line":449},[272,3051,2763],{"class":2762},[272,3053,406],{"class":289},[272,3055,3056,3058],{"class":274,"line":466},[272,3057,188],{"class":282},[272,3059,822],{"class":289},[272,3061,3062],{"class":274,"line":472},[272,3063,302],{"emptyLinePlaceholder":169},[272,3065,3066,3068,3071,3073,3076,3079,3082,3085,3087,3090],{"class":274,"line":491},[272,3067,2288],{"class":781},[272,3069,3070],{"class":282}," renameTransformer ",[272,3072,2294],{"class":289},[272,3074,3075],{"class":289}," ():",[272,3077,3078],{"class":801}," TransformerFactory",[272,3080,3081],{"class":289},"\u003C",[272,3083,3084],{"class":801},"SourceFile",[272,3086,2311],{"class":289},[272,3088,3089],{"class":781}," =>",[272,3091,373],{"class":289},[272,3093,3094,3097,3099,3102,3104,3106,3108,3111,3113,3115],{"class":274,"line":511},[272,3095,3096],{"class":278},"  return",[272,3098,2493],{"class":289},[272,3100,3101],{"class":2496},"context",[272,3103,188],{"class":289},[272,3105,3089],{"class":781},[272,3107,2493],{"class":289},[272,3109,3110],{"class":2496},"sourceFile",[272,3112,188],{"class":289},[272,3114,3089],{"class":781},[272,3116,373],{"class":289},[272,3118,3119,3122,3125,3128,3130,3132,3134,3136,3139,3141,3143],{"class":274,"line":529},[272,3120,3121],{"class":781},"    const",[272,3123,3124],{"class":282}," visitNode",[272,3126,3127],{"class":289}," =",[272,3129,2493],{"class":289},[272,3131,2497],{"class":2496},[272,3133,370],{"class":289},[272,3135,2797],{"class":801},[272,3137,3138],{"class":289},"):",[272,3140,2797],{"class":801},[272,3142,3089],{"class":781},[272,3144,373],{"class":289},[272,3146,3147,3150,3152,3155,3157,3159,3161,3164,3167,3169,3171,3174,3176,3178,3180,3182],{"class":274,"line":547},[272,3148,3149],{"class":278},"      if",[272,3151,2493],{"class":366},[272,3153,3154],{"class":354},"isIdentifier",[272,3156,357],{"class":366},[272,3158,2497],{"class":282},[272,3160,2317],{"class":366},[272,3162,3163],{"class":289},"&&",[272,3165,3166],{"class":282}," node",[272,3168,430],{"class":289},[272,3170,726],{"class":282},[272,3172,3173],{"class":289}," ===",[272,3175,2640],{"class":289},[272,3177,2964],{"class":293},[272,3179,2334],{"class":289},[272,3181,2317],{"class":366},[272,3183,360],{"class":289},[272,3185,3186,3189,3192,3194,3197,3199,3201,3203,3205,3207],{"class":274,"line":565},[272,3187,3188],{"class":278},"        return",[272,3190,3191],{"class":282}," factory",[272,3193,430],{"class":289},[272,3195,3196],{"class":354},"createIdentifier",[272,3198,357],{"class":366},[272,3200,2334],{"class":289},[272,3202,2968],{"class":293},[272,3204,2334],{"class":289},[272,3206,188],{"class":366},[272,3208,822],{"class":289},[272,3210,3211],{"class":274,"line":592},[272,3212,3213],{"class":289},"      }\n",[272,3215,3216],{"class":274,"line":611},[272,3217,302],{"emptyLinePlaceholder":169},[272,3219,3220,3223,3226,3228,3230,3232,3234,3236,3239,3241],{"class":274,"line":629},[272,3221,3222],{"class":278},"      return",[272,3224,3225],{"class":354}," visitEachChild",[272,3227,357],{"class":366},[272,3229,2497],{"class":282},[272,3231,316],{"class":289},[272,3233,3124],{"class":282},[272,3235,316],{"class":289},[272,3237,3238],{"class":282}," context",[272,3240,188],{"class":366},[272,3242,822],{"class":289},[272,3244,3245],{"class":274,"line":648},[272,3246,3247],{"class":289},"    };\n",[272,3249,3250],{"class":274,"line":658},[272,3251,302],{"emptyLinePlaceholder":169},[272,3253,3254,3257,3259,3261,3263,3265,3267,3269,3271,3273],{"class":274,"line":668},[272,3255,3256],{"class":278},"    return",[272,3258,3225],{"class":354},[272,3260,357],{"class":366},[272,3262,3110],{"class":282},[272,3264,316],{"class":289},[272,3266,3124],{"class":282},[272,3268,316],{"class":289},[272,3270,3238],{"class":282},[272,3272,188],{"class":366},[272,3274,822],{"class":289},[272,3276,3277],{"class":274,"line":674},[272,3278,3279],{"class":289},"  };\n",[272,3281,3282],{"class":274,"line":1161},[272,3283,3284],{"class":289},"};\n",[272,3286,3287],{"class":274,"line":1169},[272,3288,302],{"emptyLinePlaceholder":169},[272,3290,3291],{"class":274,"line":1177},[272,3292,3293],{"class":2656},"\u002F\u002F トランスフォーマーを適用\n",[272,3295,3296,3298,3301,3303,3306,3309,3311,3314,3317,3320],{"class":274,"line":1184},[272,3297,2288],{"class":781},[272,3299,3300],{"class":282}," result ",[272,3302,2294],{"class":289},[272,3304,3305],{"class":354}," transform",[272,3307,3308],{"class":282},"(hogehoge",[272,3310,316],{"class":289},[272,3312,3313],{"class":282}," [",[272,3315,3316],{"class":354},"renameTransformer",[272,3318,3319],{"class":282},"()])",[272,3321,822],{"class":289},[272,3323,3324],{"class":274,"line":1192},[272,3325,302],{"emptyLinePlaceholder":169},[272,3327,3328],{"class":274,"line":1200},[272,3329,3330],{"class":2656},"\u002F\u002F 新しい AST をコードとして出力\n",[272,3332,3333,3335,3338,3340,3343,3345],{"class":274,"line":1208},[272,3334,2288],{"class":781},[272,3336,3337],{"class":282}," printer ",[272,3339,2294],{"class":289},[272,3341,3342],{"class":354}," createPrinter",[272,3344,506],{"class":282},[272,3346,822],{"class":289},[272,3348,3349,3352,3354,3356,3359,3361,3364,3367,3369,3372,3375,3378],{"class":274,"line":1216},[272,3350,3351],{"class":282},"console",[272,3353,430],{"class":289},[272,3355,2329],{"class":354},[272,3357,3358],{"class":282},"(printer",[272,3360,430],{"class":289},[272,3362,3363],{"class":354},"printFile",[272,3365,3366],{"class":282},"(result",[272,3368,430],{"class":289},[272,3370,3371],{"class":282},"transformed[",[272,3373,3374],{"class":2297},"0",[272,3376,3377],{"class":282},"]))",[272,3379,822],{"class":289},[264,3381,3384],{"className":2891,"code":3382,"filename":3383,"language":2894,"meta":154,"style":154},"const y: number = 42;\n","transform_result.txt",[203,3385,3386],{"__ignoreMap":154},[272,3387,3388],{"class":274,"line":275},[272,3389,3382],{},[11,3391,3393],{"id":3392},"ts-morph-を使う","ts-morph を使う",[15,3395,3396,3397,3403],{},"ここで TypeScript Compiler API のラッパーである ",[80,3398,3401],{"href":3399,"rel":3400,"target":87},"https:\u002F\u002Fgithub.com\u002Fdsherret\u002Fts-morph",[84,85,86],[203,3402,2251],{}," を紹介する。",[57,3405],{"link":3406},"https:\u002F\u002Fts-morph.com\u002F",[15,3408,3409,3410,3413,3414,3416],{},"TypeScript Compiler API に比べて、AST に詳しくなる学習コストが必要ないのと、単純な操作でも少ないコードで、コードの参照、改修ができる。\n以下は、参照系のスクリプトだが、試しに ",[203,3411,3412],{},"TypeScript Compiler API"," と ",[203,3415,2251],{}," で同じ動作をするスクリプトを用意したところ、簡略されているのがわかる。",[264,3418,3421],{"className":266,"code":3419,"filename":3420,"language":268,"meta":154,"style":154},"import * as ts from \"typescript\";\n\nconst sourceCode = \"const x = 10;\";\nconst sourceFile = ts.createSourceFile(\"example.ts\", sourceCode, ts.ScriptTarget.Latest, true);\n\n\u002F\u002F AST を巡回して変数名を取得\nconst visit = (node: ts.Node): void => {\n  if (ts.isVariableDeclaration(node)) {\n    console.log(node.name.getText());\n  }\n\n  ts.forEachChild(node, visit);\n}\n\nvisit(sourceFile);\n","compiler_api.ts",[203,3422,3423,3446,3450,3467,3518,3522,3527,3558,3581,3607,3611,3615,3637,3641,3645],{"__ignoreMap":154},[272,3424,3425,3427,3430,3433,3436,3438,3440,3442,3444],{"class":274,"line":275},[272,3426,279],{"class":278},[272,3428,3429],{"class":289}," *",[272,3431,3432],{"class":278}," as",[272,3434,3435],{"class":282}," ts ",[272,3437,286],{"class":278},[272,3439,2640],{"class":289},[272,3441,2643],{"class":293},[272,3443,2334],{"class":289},[272,3445,822],{"class":289},[272,3447,3448],{"class":274,"line":155},[272,3449,302],{"emptyLinePlaceholder":169},[272,3451,3452,3454,3456,3458,3460,3463,3465],{"class":274,"line":305},[272,3453,2288],{"class":781},[272,3455,2664],{"class":282},[272,3457,2294],{"class":289},[272,3459,2640],{"class":289},[272,3461,3462],{"class":293},"const x = 10;",[272,3464,2334],{"class":289},[272,3466,822],{"class":289},[272,3468,3469,3471,3473,3475,3478,3480,3483,3485,3487,3489,3491,3493,3496,3498,3500,3502,3505,3507,3509,3511,3514,3516],{"class":274,"line":340},[272,3470,2288],{"class":781},[272,3472,2710],{"class":282},[272,3474,2294],{"class":289},[272,3476,3477],{"class":282}," ts",[272,3479,430],{"class":289},[272,3481,3482],{"class":354},"createSourceFile",[272,3484,357],{"class":282},[272,3486,2334],{"class":289},[272,3488,2726],{"class":293},[272,3490,2334],{"class":289},[272,3492,316],{"class":289},[272,3494,3495],{"class":282}," sourceCode",[272,3497,316],{"class":289},[272,3499,3477],{"class":282},[272,3501,430],{"class":289},[272,3503,3504],{"class":282},"ScriptTarget",[272,3506,430],{"class":289},[272,3508,2752],{"class":282},[272,3510,316],{"class":289},[272,3512,3513],{"class":2762}," true",[272,3515,188],{"class":282},[272,3517,822],{"class":289},[272,3519,3520],{"class":274,"line":345},[272,3521,302],{"emptyLinePlaceholder":169},[272,3523,3524],{"class":274,"line":363},[272,3525,3526],{"class":2656},"\u002F\u002F AST を巡回して変数名を取得\n",[272,3528,3529,3531,3534,3536,3538,3540,3542,3544,3546,3549,3551,3554,3556],{"class":274,"line":376},[272,3530,2288],{"class":781},[272,3532,3533],{"class":282}," visit ",[272,3535,2294],{"class":289},[272,3537,2493],{"class":289},[272,3539,2497],{"class":2496},[272,3541,370],{"class":289},[272,3543,3477],{"class":801},[272,3545,430],{"class":289},[272,3547,3548],{"class":801},"Node",[272,3550,3138],{"class":289},[272,3552,3553],{"class":801}," void",[272,3555,3089],{"class":781},[272,3557,373],{"class":289},[272,3559,3560,3563,3565,3567,3569,3572,3574,3576,3579],{"class":274,"line":390},[272,3561,3562],{"class":278},"  if",[272,3564,2493],{"class":366},[272,3566,268],{"class":282},[272,3568,430],{"class":289},[272,3570,3571],{"class":354},"isVariableDeclaration",[272,3573,357],{"class":366},[272,3575,2497],{"class":282},[272,3577,3578],{"class":366},")) ",[272,3580,360],{"class":289},[272,3582,3583,3586,3588,3590,3592,3594,3596,3599,3601,3603,3605],{"class":274,"line":409},[272,3584,3585],{"class":282},"    console",[272,3587,430],{"class":289},[272,3589,2329],{"class":354},[272,3591,357],{"class":366},[272,3593,2497],{"class":282},[272,3595,430],{"class":289},[272,3597,3598],{"class":282},"name",[272,3600,430],{"class":289},[272,3602,2837],{"class":354},[272,3604,587],{"class":366},[272,3606,822],{"class":289},[272,3608,3609],{"class":274,"line":419},[272,3610,909],{"class":289},[272,3612,3613],{"class":274,"line":449},[272,3614,302],{"emptyLinePlaceholder":169},[272,3616,3617,3620,3622,3625,3627,3629,3631,3633,3635],{"class":274,"line":466},[272,3618,3619],{"class":282},"  ts",[272,3621,430],{"class":289},[272,3623,3624],{"class":354},"forEachChild",[272,3626,357],{"class":366},[272,3628,2497],{"class":282},[272,3630,316],{"class":289},[272,3632,2428],{"class":282},[272,3634,188],{"class":366},[272,3636,822],{"class":289},[272,3638,3639],{"class":274,"line":472},[272,3640,965],{"class":289},[272,3642,3643],{"class":274,"line":491},[272,3644,302],{"emptyLinePlaceholder":169},[272,3646,3647,3649,3651],{"class":274,"line":511},[272,3648,2474],{"class":354},[272,3650,2886],{"class":282},[272,3652,822],{"class":289},[264,3654,3657],{"className":266,"code":3655,"filename":3656,"language":268,"meta":154,"style":154},"import { Project } from \"ts-morph\";\n\nconst project = new Project();\nconst sourceFile = project.createSourceFile(\"example.ts\", \"const x = 10;\");\nconst variable = sourceFile.getVariableDeclaration(\"x\");\nconsole.log(variable?.getName());\n","ts_morph.ts",[203,3658,3659,3680,3684,3702,3737,3766],{"__ignoreMap":154},[272,3660,3661,3663,3665,3668,3670,3672,3674,3676,3678],{"class":274,"line":275},[272,3662,279],{"class":278},[272,3664,310],{"class":289},[272,3666,3667],{"class":282}," Project",[272,3669,327],{"class":289},[272,3671,330],{"class":278},[272,3673,2640],{"class":289},[272,3675,2251],{"class":293},[272,3677,2334],{"class":289},[272,3679,822],{"class":289},[272,3681,3682],{"class":274,"line":155},[272,3683,302],{"emptyLinePlaceholder":169},[272,3685,3686,3688,3691,3693,3696,3698,3700],{"class":274,"line":305},[272,3687,2288],{"class":781},[272,3689,3690],{"class":282}," project ",[272,3692,2294],{"class":289},[272,3694,3695],{"class":289}," new",[272,3697,3667],{"class":354},[272,3699,506],{"class":282},[272,3701,822],{"class":289},[272,3703,3704,3706,3708,3710,3713,3715,3717,3719,3721,3723,3725,3727,3729,3731,3733,3735],{"class":274,"line":340},[272,3705,2288],{"class":781},[272,3707,2710],{"class":282},[272,3709,2294],{"class":289},[272,3711,3712],{"class":282}," project",[272,3714,430],{"class":289},[272,3716,3482],{"class":354},[272,3718,357],{"class":282},[272,3720,2334],{"class":289},[272,3722,2726],{"class":293},[272,3724,2334],{"class":289},[272,3726,316],{"class":289},[272,3728,2640],{"class":289},[272,3730,3462],{"class":293},[272,3732,2334],{"class":289},[272,3734,188],{"class":282},[272,3736,822],{"class":289},[272,3738,3739,3741,3744,3746,3749,3751,3754,3756,3758,3760,3762,3764],{"class":274,"line":345},[272,3740,2288],{"class":781},[272,3742,3743],{"class":282}," variable ",[272,3745,2294],{"class":289},[272,3747,3748],{"class":282}," sourceFile",[272,3750,430],{"class":289},[272,3752,3753],{"class":354},"getVariableDeclaration",[272,3755,357],{"class":282},[272,3757,2334],{"class":289},[272,3759,2964],{"class":293},[272,3761,2334],{"class":289},[272,3763,188],{"class":282},[272,3765,822],{"class":289},[272,3767,3768,3770,3772,3774,3777,3780,3783,3785],{"class":274,"line":363},[272,3769,3351],{"class":282},[272,3771,430],{"class":289},[272,3773,2329],{"class":354},[272,3775,3776],{"class":282},"(variable",[272,3778,3779],{"class":289},"?.",[272,3781,3782],{"class":354},"getName",[272,3784,587],{"class":282},[272,3786,822],{"class":289},[15,3788,3789,3790,3793,3794,3796],{},"ユーティリティ関数も用意されている。例えば、型オブジェクトを取得する ",[203,3791,3792],{},"getType"," や、さらにそこから該当の型の名前を取得できる ",[203,3795,2837],{}," の関数がある。",[264,3798,3801],{"className":266,"code":3799,"filename":3800,"language":268,"meta":154,"style":154},"import { Project } from \"https:\u002F\u002Fdeno.land\u002Fx\u002Fts_morph\u002Fmod.ts\";\n\nconst project = new Project();\nconst sourceFile = project.createSourceFile(\n  \"example.ts\",\n  \"const x: number = 10;\",\n);\nconst variable = sourceFile.getVariableDeclarationOrThrow(\"x\");\nconsole.log(variable.getType().getText()); \u002F\u002F -> number\nconsole.log(variable.getType().isNumber()); \u002F\u002F -> true\n","ts_morph_util.ts",[203,3802,3803,3824,3828,3844,3860,3870,3881,3887,3914,3941],{"__ignoreMap":154},[272,3804,3805,3807,3809,3811,3813,3815,3817,3820,3822],{"class":274,"line":275},[272,3806,279],{"class":278},[272,3808,310],{"class":289},[272,3810,3667],{"class":282},[272,3812,327],{"class":289},[272,3814,330],{"class":278},[272,3816,2640],{"class":289},[272,3818,3819],{"class":293},"https:\u002F\u002Fdeno.land\u002Fx\u002Fts_morph\u002Fmod.ts",[272,3821,2334],{"class":289},[272,3823,822],{"class":289},[272,3825,3826],{"class":274,"line":155},[272,3827,302],{"emptyLinePlaceholder":169},[272,3829,3830,3832,3834,3836,3838,3840,3842],{"class":274,"line":305},[272,3831,2288],{"class":781},[272,3833,3690],{"class":282},[272,3835,2294],{"class":289},[272,3837,3695],{"class":289},[272,3839,3667],{"class":354},[272,3841,506],{"class":282},[272,3843,822],{"class":289},[272,3845,3846,3848,3850,3852,3854,3856,3858],{"class":274,"line":340},[272,3847,2288],{"class":781},[272,3849,2710],{"class":282},[272,3851,2294],{"class":289},[272,3853,3712],{"class":282},[272,3855,430],{"class":289},[272,3857,3482],{"class":354},[272,3859,2718],{"class":282},[272,3861,3862,3864,3866,3868],{"class":274,"line":345},[272,3863,2723],{"class":289},[272,3865,2726],{"class":293},[272,3867,2334],{"class":289},[272,3869,406],{"class":289},[272,3871,3872,3874,3877,3879],{"class":274,"line":363},[272,3873,2723],{"class":289},[272,3875,3876],{"class":293},"const x: number = 10;",[272,3878,2334],{"class":289},[272,3880,406],{"class":289},[272,3882,3883,3885],{"class":274,"line":376},[272,3884,188],{"class":282},[272,3886,822],{"class":289},[272,3888,3889,3891,3893,3895,3897,3899,3902,3904,3906,3908,3910,3912],{"class":274,"line":390},[272,3890,2288],{"class":781},[272,3892,3743],{"class":282},[272,3894,2294],{"class":289},[272,3896,3748],{"class":282},[272,3898,430],{"class":289},[272,3900,3901],{"class":354},"getVariableDeclarationOrThrow",[272,3903,357],{"class":282},[272,3905,2334],{"class":289},[272,3907,2964],{"class":293},[272,3909,2334],{"class":289},[272,3911,188],{"class":282},[272,3913,822],{"class":289},[272,3915,3916,3918,3920,3922,3924,3926,3928,3930,3932,3934,3936,3938],{"class":274,"line":409},[272,3917,3351],{"class":282},[272,3919,430],{"class":289},[272,3921,2329],{"class":354},[272,3923,3776],{"class":282},[272,3925,430],{"class":289},[272,3927,3792],{"class":354},[272,3929,506],{"class":282},[272,3931,430],{"class":289},[272,3933,2837],{"class":354},[272,3935,587],{"class":282},[272,3937,2863],{"class":289},[272,3939,3940],{"class":2656}," \u002F\u002F -> number\n",[272,3942,3943,3945,3947,3949,3951,3953,3955,3957,3959,3962,3964,3966],{"class":274,"line":419},[272,3944,3351],{"class":282},[272,3946,430],{"class":289},[272,3948,2329],{"class":354},[272,3950,3776],{"class":282},[272,3952,430],{"class":289},[272,3954,3792],{"class":354},[272,3956,506],{"class":282},[272,3958,430],{"class":289},[272,3960,3961],{"class":354},"isNumber",[272,3963,587],{"class":282},[272,3965,2863],{"class":289},[272,3967,3968],{"class":2656}," \u002F\u002F -> true\n",[11,3970,3972],{"id":3971},"vuejs-sfc-の-script-を改修する","Vue.js SFC の script を改修する",[15,3974,3975,3977,3978,3981,3982,1621,3985,3988],{},[203,3976,2251],{}," でできることを見たので、本題の Vue.js SFC の script 部分を改修していく。今回は ",[203,3979,3980],{},"defineProps"," のプロパティ名を ",[203,3983,3984],{},"prefix",[203,3986,3987],{},"suffix"," へ変更することを目標にする。",[245,3990,3992],{"id":3991},"_1-vuejs-sfc-の-script-を取得する","1. Vue.js SFC の script を取得する",[15,3994,3995,3996,3999,4000,4003],{},"sfc の script の部分を取得するには、",[203,3997,3998],{},"@vue\u002Fcompiler-sfc"," を使う。下の例を見ると、提供されている ",[203,4001,4002],{},"parse"," 関数を使って、置換対象のスクリプトを取得できる。",[57,4005],{"link":4006},"https:\u002F\u002Fwww.npmjs.com\u002Fpackage\u002F@vue\u002Fcompiler-sfc",[264,4008,4013],{"className":4009,"code":4010,"filename":4011,"language":4012,"meta":154,"style":154},"language-vue shiki shiki-themes material-theme","\u003Cscript lang=\"ts\" setup>\nimport { ref } from '#imports'\n\ndefineProps\u003C{ prefix: string }>()\n\nconst hoge = ref('hogehoge')\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cdiv class=\"fugafuga\">\n    \u003Cp>{{ hoge }}\u003C\u002Fp>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cstyle lang=\"scss\" scoped>\n.fugafuga {\n  font-size: 16px;\n}\n\u003C\u002Fstyle>\n","before.vue","vue",[203,4014,4015,4039,4059,4063,4083,4087,4109,4118,4122,4131,4153,4171,4180,4188,4192,4214,4219,4224,4228],{"__ignoreMap":154},[272,4016,4017,4019,4022,4025,4027,4029,4031,4033,4036],{"class":274,"line":275},[272,4018,3081],{"class":289},[272,4020,4021],{"class":366},"script",[272,4023,4024],{"class":781}," lang",[272,4026,2294],{"class":289},[272,4028,2334],{"class":289},[272,4030,268],{"class":293},[272,4032,2334],{"class":289},[272,4034,4035],{"class":781}," setup",[272,4037,4038],{"class":289},">\n",[272,4040,4041,4043,4045,4048,4050,4052,4054,4057],{"class":274,"line":155},[272,4042,279],{"class":278},[272,4044,310],{"class":289},[272,4046,4047],{"class":282}," ref",[272,4049,327],{"class":289},[272,4051,330],{"class":278},[272,4053,290],{"class":289},[272,4055,4056],{"class":293},"#imports",[272,4058,297],{"class":289},[272,4060,4061],{"class":274,"line":305},[272,4062,302],{"emptyLinePlaceholder":169},[272,4064,4065,4067,4070,4073,4075,4077,4080],{"class":274,"line":340},[272,4066,3980],{"class":354},[272,4068,4069],{"class":289},"\u003C{",[272,4071,4072],{"class":366}," prefix",[272,4074,370],{"class":289},[272,4076,819],{"class":801},[272,4078,4079],{"class":289}," }>",[272,4081,4082],{"class":282},"()\n",[272,4084,4085],{"class":274,"line":345},[272,4086,302],{"emptyLinePlaceholder":169},[272,4088,4089,4091,4094,4096,4098,4100,4102,4105,4107],{"class":274,"line":363},[272,4090,2288],{"class":781},[272,4092,4093],{"class":282}," hoge ",[272,4095,2294],{"class":289},[272,4097,4047],{"class":354},[272,4099,357],{"class":282},[272,4101,403],{"class":289},[272,4103,4104],{"class":293},"hogehoge",[272,4106,403],{"class":289},[272,4108,680],{"class":282},[272,4110,4111,4114,4116],{"class":274,"line":376},[272,4112,4113],{"class":289},"\u003C\u002F",[272,4115,4021],{"class":366},[272,4117,4038],{"class":289},[272,4119,4120],{"class":274,"line":390},[272,4121,302],{"emptyLinePlaceholder":169},[272,4123,4124,4126,4129],{"class":274,"line":409},[272,4125,3081],{"class":289},[272,4127,4128],{"class":366},"template",[272,4130,4038],{"class":289},[272,4132,4133,4136,4139,4142,4144,4146,4149,4151],{"class":274,"line":419},[272,4134,4135],{"class":289},"  \u003C",[272,4137,4138],{"class":366},"div",[272,4140,4141],{"class":781}," class",[272,4143,2294],{"class":289},[272,4145,2334],{"class":289},[272,4147,4148],{"class":293},"fugafuga",[272,4150,2334],{"class":289},[272,4152,4038],{"class":289},[272,4154,4155,4158,4160,4162,4165,4167,4169],{"class":274,"line":449},[272,4156,4157],{"class":289},"    \u003C",[272,4159,15],{"class":366},[272,4161,2311],{"class":289},[272,4163,4164],{"class":282},"{{ hoge }}",[272,4166,4113],{"class":289},[272,4168,15],{"class":366},[272,4170,4038],{"class":289},[272,4172,4173,4176,4178],{"class":274,"line":466},[272,4174,4175],{"class":289},"  \u003C\u002F",[272,4177,4138],{"class":366},[272,4179,4038],{"class":289},[272,4181,4182,4184,4186],{"class":274,"line":472},[272,4183,4113],{"class":289},[272,4185,4128],{"class":366},[272,4187,4038],{"class":289},[272,4189,4190],{"class":274,"line":491},[272,4191,302],{"emptyLinePlaceholder":169},[272,4193,4194,4196,4198,4200,4202,4204,4207,4209,4212],{"class":274,"line":511},[272,4195,3081],{"class":289},[272,4197,2211],{"class":366},[272,4199,4024],{"class":781},[272,4201,2294],{"class":289},[272,4203,2334],{"class":289},[272,4205,4206],{"class":293},"scss",[272,4208,2334],{"class":289},[272,4210,4211],{"class":781}," scoped",[272,4213,4038],{"class":289},[272,4215,4216],{"class":274,"line":529},[272,4217,4218],{"class":282},".fugafuga {\n",[272,4220,4221],{"class":274,"line":547},[272,4222,4223],{"class":282},"  font-size: 16px;\n",[272,4225,4226],{"class":274,"line":565},[272,4227,965],{"class":282},[272,4229,4230,4232,4234],{"class":274,"line":592},[272,4231,4113],{"class":289},[272,4233,2211],{"class":366},[272,4235,4038],{"class":289},[264,4237,4240],{"className":266,"code":4238,"filename":4239,"language":268,"meta":154,"style":154},"import { parse } from \"https:\u002F\u002Fdeno.land\u002Fx\u002Fvue_sfc_compiler\u002Fmod.ts\";\n\nconst sfc = await Deno.readTextFile(\".\u002Fbefore.vue\");\nconst { descriptor: { script, scriptSetup } } = parse(sfc);\n\nconsole.log({ script });\nconsole.log({ scriptSetup: scriptSetup.content });\n","convert.ts",[203,4241,4242,4264,4268,4301,4335,4339,4361],{"__ignoreMap":154},[272,4243,4244,4246,4248,4251,4253,4255,4257,4260,4262],{"class":274,"line":275},[272,4245,279],{"class":278},[272,4247,310],{"class":289},[272,4249,4250],{"class":282}," parse",[272,4252,327],{"class":289},[272,4254,330],{"class":278},[272,4256,2640],{"class":289},[272,4258,4259],{"class":293},"https:\u002F\u002Fdeno.land\u002Fx\u002Fvue_sfc_compiler\u002Fmod.ts",[272,4261,2334],{"class":289},[272,4263,822],{"class":289},[272,4265,4266],{"class":274,"line":155},[272,4267,302],{"emptyLinePlaceholder":169},[272,4269,4270,4272,4275,4277,4280,4283,4285,4288,4290,4292,4295,4297,4299],{"class":274,"line":305},[272,4271,2288],{"class":781},[272,4273,4274],{"class":282}," sfc ",[272,4276,2294],{"class":289},[272,4278,4279],{"class":278}," await",[272,4281,4282],{"class":282}," Deno",[272,4284,430],{"class":289},[272,4286,4287],{"class":354},"readTextFile",[272,4289,357],{"class":282},[272,4291,2334],{"class":289},[272,4293,4294],{"class":293},".\u002Fbefore.vue",[272,4296,2334],{"class":289},[272,4298,188],{"class":282},[272,4300,822],{"class":289},[272,4302,4303,4305,4307,4310,4312,4314,4317,4319,4322,4324,4326,4328,4330,4333],{"class":274,"line":340},[272,4304,2288],{"class":781},[272,4306,310],{"class":289},[272,4308,4309],{"class":366}," descriptor",[272,4311,370],{"class":289},[272,4313,310],{"class":289},[272,4315,4316],{"class":282}," script",[272,4318,316],{"class":289},[272,4320,4321],{"class":282}," scriptSetup ",[272,4323,677],{"class":289},[272,4325,327],{"class":289},[272,4327,3127],{"class":289},[272,4329,4250],{"class":354},[272,4331,4332],{"class":282},"(sfc)",[272,4334,822],{"class":289},[272,4336,4337],{"class":274,"line":345},[272,4338,302],{"emptyLinePlaceholder":169},[272,4340,4341,4343,4345,4347,4349,4352,4355,4357,4359],{"class":274,"line":363},[272,4342,3351],{"class":282},[272,4344,430],{"class":289},[272,4346,2329],{"class":354},[272,4348,357],{"class":282},[272,4350,4351],{"class":289},"{",[272,4353,4354],{"class":282}," script ",[272,4356,677],{"class":289},[272,4358,188],{"class":282},[272,4360,822],{"class":289},[272,4362,4363,4365,4367,4369,4371,4373,4376,4378,4380,4382,4385,4387,4389],{"class":274,"line":376},[272,4364,3351],{"class":282},[272,4366,430],{"class":289},[272,4368,2329],{"class":354},[272,4370,357],{"class":282},[272,4372,4351],{"class":289},[272,4374,4375],{"class":366}," scriptSetup",[272,4377,370],{"class":289},[272,4379,4375],{"class":282},[272,4381,430],{"class":289},[272,4383,4384],{"class":282},"content ",[272,4386,677],{"class":289},[272,4388,188],{"class":282},[272,4390,822],{"class":289},[264,4392,4395],{"className":2891,"code":4393,"filename":4394,"language":2894,"meta":154,"style":154},"{ script: null }\n{\n  scriptSetup: {\n    type: \"script\",\n    content: \"\\n\" +\n      \"import { ref } from '#imports'\\n\" +\n      \"\\n\" +\n      \"defineProps\u003C{ prefix: string }>()\\n\" +\n      \"\\n\" +\n      \"const hoge = ref('hogehoge')\\n\",\n    loc: {\n      source: \"\\n\" +\n        \"import { ref } from '#imports'\\n\" +\n        \"\\n\" +\n        \"defineProps\u003C{ prefix: string }>()\\n\" +\n        \"\\n\" +\n        \"const hoge = ref('hogehoge')\\n\",\n      start: { column: 25, line: 1, offset: 24 },\n      end: { column: 1, line: 7, offset: 121 }\n    },\n    attrs: { lang: \"ts\", setup: true },\n    lang: \"ts\",\n    setup: true\n  }\n}\n","convert.txt",[203,4396,4397,4402,4406,4411,4416,4421,4426,4431,4436,4440,4445,4450,4455,4460,4465,4470,4474,4479,4484,4489,4493,4498,4503,4508,4512],{"__ignoreMap":154},[272,4398,4399],{"class":274,"line":275},[272,4400,4401],{},"{ script: null }\n",[272,4403,4404],{"class":274,"line":155},[272,4405,360],{},[272,4407,4408],{"class":274,"line":305},[272,4409,4410],{},"  scriptSetup: {\n",[272,4412,4413],{"class":274,"line":340},[272,4414,4415],{},"    type: \"script\",\n",[272,4417,4418],{"class":274,"line":345},[272,4419,4420],{},"    content: \"\\n\" +\n",[272,4422,4423],{"class":274,"line":363},[272,4424,4425],{},"      \"import { ref } from '#imports'\\n\" +\n",[272,4427,4428],{"class":274,"line":376},[272,4429,4430],{},"      \"\\n\" +\n",[272,4432,4433],{"class":274,"line":390},[272,4434,4435],{},"      \"defineProps\u003C{ prefix: string }>()\\n\" +\n",[272,4437,4438],{"class":274,"line":409},[272,4439,4430],{},[272,4441,4442],{"class":274,"line":419},[272,4443,4444],{},"      \"const hoge = ref('hogehoge')\\n\",\n",[272,4446,4447],{"class":274,"line":449},[272,4448,4449],{},"    loc: {\n",[272,4451,4452],{"class":274,"line":466},[272,4453,4454],{},"      source: \"\\n\" +\n",[272,4456,4457],{"class":274,"line":472},[272,4458,4459],{},"        \"import { ref } from '#imports'\\n\" +\n",[272,4461,4462],{"class":274,"line":491},[272,4463,4464],{},"        \"\\n\" +\n",[272,4466,4467],{"class":274,"line":511},[272,4468,4469],{},"        \"defineProps\u003C{ prefix: string }>()\\n\" +\n",[272,4471,4472],{"class":274,"line":529},[272,4473,4464],{},[272,4475,4476],{"class":274,"line":547},[272,4477,4478],{},"        \"const hoge = ref('hogehoge')\\n\",\n",[272,4480,4481],{"class":274,"line":565},[272,4482,4483],{},"      start: { column: 25, line: 1, offset: 24 },\n",[272,4485,4486],{"class":274,"line":592},[272,4487,4488],{},"      end: { column: 1, line: 7, offset: 121 }\n",[272,4490,4491],{"class":274,"line":611},[272,4492,1140],{},[272,4494,4495],{"class":274,"line":629},[272,4496,4497],{},"    attrs: { lang: \"ts\", setup: true },\n",[272,4499,4500],{"class":274,"line":648},[272,4501,4502],{},"    lang: \"ts\",\n",[272,4504,4505],{"class":274,"line":658},[272,4506,4507],{},"    setup: true\n",[272,4509,4510],{"class":274,"line":668},[272,4511,909],{},[272,4513,4514],{"class":274,"line":674},[272,4515,965],{},[245,4517,4519],{"id":4518},"_2-props-のプロパティ名を書き換える","2. Props のプロパティ名を書き換える",[15,4521,4522,4523,4525],{},"対象の ",[203,4524,4021],{}," 部分を取得できたら、今度は対象ノードを探し、プロパティ名を書き換えていきます。",[15,4527,4528,4532,4533,4535,4536,4538,4539,4542,4543,4546],{},[80,4529,4531],{"href":2369,"rel":4530,"target":87},[84,85,86],"ts-ast-viewer"," で該当スクリプトの AST を確認する。\n",[203,4534,3980],{}," の ",[203,4537,2355],{}," は、",[203,4540,4541],{},"ExpressionStatement"," というのが分かり、そこから ",[203,4544,4545],{},"PropertySignature"," に辿りづくまで、下へ階層を掘り下げていく。毎回置換対象の AST がどんなものなのかを確認するのがおすすめ。",[264,4548,4551],{"className":2891,"code":4549,"filename":4550,"language":2894,"meta":154,"style":154},"Program\n├── ImportDeclaration (インポート文)\n│   ├── NamedImports (\"ref\") (名前付きインポート)\n│   ├── StringLiteral (\"#imports\") (文字列リテラル)\n├── ExpressionStatement (式文)\n│   ├── CallExpression (defineProps) (関数呼び出し)\n│       ├── Identifier (\"defineProps\") (識別子)\n│       ├── TypeLiteral (型リテラル)\n│           ├── PropertySignature (\"prefix\") (プロパティ定義)\n│               ├── StringKeyword (string) (型キーワード)\n├── VariableDeclaration (変数宣言)\n│   ├── Identifier (\"hoge\") (識別子)\n│   ├── CallExpression (ref) (関数呼び出し)\n│       ├── Identifier (\"ref\") (識別子)\n│       ├── StringLiteral (\"hogehoge\") (文字列リテラル)\n","ast.txt",[203,4552,4553,4558,4563,4568,4573,4578,4583,4588,4593,4598,4603,4608,4613,4618,4623],{"__ignoreMap":154},[272,4554,4555],{"class":274,"line":275},[272,4556,4557],{},"Program\n",[272,4559,4560],{"class":274,"line":155},[272,4561,4562],{},"├── ImportDeclaration (インポート文)\n",[272,4564,4565],{"class":274,"line":305},[272,4566,4567],{},"│   ├── NamedImports (\"ref\") (名前付きインポート)\n",[272,4569,4570],{"class":274,"line":340},[272,4571,4572],{},"│   ├── StringLiteral (\"#imports\") (文字列リテラル)\n",[272,4574,4575],{"class":274,"line":345},[272,4576,4577],{},"├── ExpressionStatement (式文)\n",[272,4579,4580],{"class":274,"line":363},[272,4581,4582],{},"│   ├── CallExpression (defineProps) (関数呼び出し)\n",[272,4584,4585],{"class":274,"line":376},[272,4586,4587],{},"│       ├── Identifier (\"defineProps\") (識別子)\n",[272,4589,4590],{"class":274,"line":390},[272,4591,4592],{},"│       ├── TypeLiteral (型リテラル)\n",[272,4594,4595],{"class":274,"line":409},[272,4596,4597],{},"│           ├── PropertySignature (\"prefix\") (プロパティ定義)\n",[272,4599,4600],{"class":274,"line":419},[272,4601,4602],{},"│               ├── StringKeyword (string) (型キーワード)\n",[272,4604,4605],{"class":274,"line":449},[272,4606,4607],{},"├── VariableDeclaration (変数宣言)\n",[272,4609,4610],{"class":274,"line":466},[272,4611,4612],{},"│   ├── Identifier (\"hoge\") (識別子)\n",[272,4614,4615],{"class":274,"line":472},[272,4616,4617],{},"│   ├── CallExpression (ref) (関数呼び出し)\n",[272,4619,4620],{"class":274,"line":491},[272,4621,4622],{},"│       ├── Identifier (\"ref\") (識別子)\n",[272,4624,4625],{"class":274,"line":511},[272,4626,4627],{},"│       ├── StringLiteral (\"hogehoge\") (文字列リテラル)\n",[15,4629,4630],{},"置換が完成するまでのスクリプトはこちら。ノードやプロパティを取得していく処理はドキュメントを読んで、そのときに該当するものを使用する。",[264,4632,4634],{"className":266,"code":4633,"filename":4239,"language":268,"meta":154,"style":154},"const oldPropName = \"prefix\";\nconst newPropName = \"suffix\";\n\nconst project = new Project({\n  compilerOptions: {\n    target: ScriptTarget.Latest,\n  },\n  useInMemoryFileSystem: true,\n});\n\nif (!scriptSetup || !scriptSetup.content) {\n  console.log(\"no script setup is found.\");\n  Deno.exit(1);\n}\n\nconst sourceFile = project.createSourceFile(\n  \"convert.ts\",\n  scriptSetup.content ?? \"\",\n);\n\nconst exprStatement = sourceFile.getStatementByKindOrThrow(\n  SyntaxKind.ExpressionStatement,\n);\n\u002F\u002F getExpression だと返り値のアサーションをしないといけないので、 `getExpressionIfKind` を使う。\nconst callExpr = exprStatement.getExpressionIfKind(SyntaxKind.CallExpression);\nif (!callExpr) {\n  console.log(\"no called function is found\");\n  Deno.exit(1);\n}\n\nconst firstTypeArg = callExpr.getTypeArguments()[0];\nif (!firstTypeArg) {\n  console.log(\"no type is found\");\n  Deno.exit(1);\n}\n\nconst typeLiteralNode = firstTypeArg.asKindOrThrow(SyntaxKind.TypeLiteral);\nconst properties = typeLiteralNode.getProperties();\nproperties.forEach((property) => {\n  if (property.getName() === oldPropName) {\n    property.rename(newPropName);\n  }\n});\n",[203,4635,4636,4653,4670,4674,4690,4699,4715,4719,4730,4738,4742,4770,4791,4810,4814,4818,4834,4844,4861,4867,4871,4889,4899,4905,4910,4937,4950,4971,4987,4991,4995,5022,5035,5056,5072,5076,5080,5106,5127,5150,5175,5194,5198],{"__ignoreMap":154},[272,4637,4638,4640,4643,4645,4647,4649,4651],{"class":274,"line":275},[272,4639,2288],{"class":781},[272,4641,4642],{"class":282}," oldPropName ",[272,4644,2294],{"class":289},[272,4646,2640],{"class":289},[272,4648,3984],{"class":293},[272,4650,2334],{"class":289},[272,4652,822],{"class":289},[272,4654,4655,4657,4660,4662,4664,4666,4668],{"class":274,"line":155},[272,4656,2288],{"class":781},[272,4658,4659],{"class":282}," newPropName ",[272,4661,2294],{"class":289},[272,4663,2640],{"class":289},[272,4665,3987],{"class":293},[272,4667,2334],{"class":289},[272,4669,822],{"class":289},[272,4671,4672],{"class":274,"line":305},[272,4673,302],{"emptyLinePlaceholder":169},[272,4675,4676,4678,4680,4682,4684,4686,4688],{"class":274,"line":340},[272,4677,2288],{"class":781},[272,4679,3690],{"class":282},[272,4681,2294],{"class":289},[272,4683,3695],{"class":289},[272,4685,3667],{"class":354},[272,4687,357],{"class":282},[272,4689,360],{"class":289},[272,4691,4692,4695,4697],{"class":274,"line":345},[272,4693,4694],{"class":366},"  compilerOptions",[272,4696,370],{"class":289},[272,4698,373],{"class":289},[272,4700,4701,4704,4706,4709,4711,4713],{"class":274,"line":363},[272,4702,4703],{"class":366},"    target",[272,4705,370],{"class":289},[272,4707,4708],{"class":282}," ScriptTarget",[272,4710,430],{"class":289},[272,4712,2752],{"class":282},[272,4714,406],{"class":289},[272,4716,4717],{"class":274,"line":376},[272,4718,671],{"class":289},[272,4720,4721,4724,4726,4728],{"class":274,"line":390},[272,4722,4723],{"class":366},"  useInMemoryFileSystem",[272,4725,370],{"class":289},[272,4727,3513],{"class":2762},[272,4729,406],{"class":289},[272,4731,4732,4734,4736],{"class":274,"line":409},[272,4733,677],{"class":289},[272,4735,188],{"class":282},[272,4737,822],{"class":289},[272,4739,4740],{"class":274,"line":419},[272,4741,302],{"emptyLinePlaceholder":169},[272,4743,4744,4746,4748,4751,4754,4757,4760,4763,4765,4768],{"class":274,"line":449},[272,4745,2305],{"class":278},[272,4747,2493],{"class":282},[272,4749,4750],{"class":289},"!",[272,4752,4753],{"class":282},"scriptSetup ",[272,4755,4756],{"class":289},"||",[272,4758,4759],{"class":289}," !",[272,4761,4762],{"class":282},"scriptSetup",[272,4764,430],{"class":289},[272,4766,4767],{"class":282},"content) ",[272,4769,360],{"class":289},[272,4771,4772,4774,4776,4778,4780,4782,4785,4787,4789],{"class":274,"line":466},[272,4773,2324],{"class":282},[272,4775,430],{"class":289},[272,4777,2329],{"class":354},[272,4779,357],{"class":366},[272,4781,2334],{"class":289},[272,4783,4784],{"class":293},"no script setup is found.",[272,4786,2334],{"class":289},[272,4788,188],{"class":366},[272,4790,822],{"class":289},[272,4792,4793,4796,4798,4801,4803,4806,4808],{"class":274,"line":472},[272,4794,4795],{"class":282},"  Deno",[272,4797,430],{"class":289},[272,4799,4800],{"class":354},"exit",[272,4802,357],{"class":366},[272,4804,4805],{"class":2297},"1",[272,4807,188],{"class":366},[272,4809,822],{"class":289},[272,4811,4812],{"class":274,"line":491},[272,4813,965],{"class":289},[272,4815,4816],{"class":274,"line":511},[272,4817,302],{"emptyLinePlaceholder":169},[272,4819,4820,4822,4824,4826,4828,4830,4832],{"class":274,"line":529},[272,4821,2288],{"class":781},[272,4823,2710],{"class":282},[272,4825,2294],{"class":289},[272,4827,3712],{"class":282},[272,4829,430],{"class":289},[272,4831,3482],{"class":354},[272,4833,2718],{"class":282},[272,4835,4836,4838,4840,4842],{"class":274,"line":547},[272,4837,2723],{"class":289},[272,4839,4239],{"class":293},[272,4841,2334],{"class":289},[272,4843,406],{"class":289},[272,4845,4846,4849,4851,4853,4856,4859],{"class":274,"line":565},[272,4847,4848],{"class":282},"  scriptSetup",[272,4850,430],{"class":289},[272,4852,4384],{"class":282},[272,4854,4855],{"class":289},"??",[272,4857,4858],{"class":289}," \"\"",[272,4860,406],{"class":289},[272,4862,4863,4865],{"class":274,"line":592},[272,4864,188],{"class":282},[272,4866,822],{"class":289},[272,4868,4869],{"class":274,"line":611},[272,4870,302],{"emptyLinePlaceholder":169},[272,4872,4873,4875,4878,4880,4882,4884,4887],{"class":274,"line":629},[272,4874,2288],{"class":781},[272,4876,4877],{"class":282}," exprStatement ",[272,4879,2294],{"class":289},[272,4881,3748],{"class":282},[272,4883,430],{"class":289},[272,4885,4886],{"class":354},"getStatementByKindOrThrow",[272,4888,2718],{"class":282},[272,4890,4891,4893,4895,4897],{"class":274,"line":648},[272,4892,2629],{"class":282},[272,4894,430],{"class":289},[272,4896,4541],{"class":282},[272,4898,406],{"class":289},[272,4900,4901,4903],{"class":274,"line":658},[272,4902,188],{"class":282},[272,4904,822],{"class":289},[272,4906,4907],{"class":274,"line":668},[272,4908,4909],{"class":2656},"\u002F\u002F getExpression だと返り値のアサーションをしないといけないので、 `getExpressionIfKind` を使う。\n",[272,4911,4912,4914,4917,4919,4922,4924,4927,4930,4932,4935],{"class":274,"line":674},[272,4913,2288],{"class":781},[272,4915,4916],{"class":282}," callExpr ",[272,4918,2294],{"class":289},[272,4920,4921],{"class":282}," exprStatement",[272,4923,430],{"class":289},[272,4925,4926],{"class":354},"getExpressionIfKind",[272,4928,4929],{"class":282},"(SyntaxKind",[272,4931,430],{"class":289},[272,4933,4934],{"class":282},"CallExpression)",[272,4936,822],{"class":289},[272,4938,4939,4941,4943,4945,4948],{"class":274,"line":1161},[272,4940,2305],{"class":278},[272,4942,2493],{"class":282},[272,4944,4750],{"class":289},[272,4946,4947],{"class":282},"callExpr) ",[272,4949,360],{"class":289},[272,4951,4952,4954,4956,4958,4960,4962,4965,4967,4969],{"class":274,"line":1169},[272,4953,2324],{"class":282},[272,4955,430],{"class":289},[272,4957,2329],{"class":354},[272,4959,357],{"class":366},[272,4961,2334],{"class":289},[272,4963,4964],{"class":293},"no called function is found",[272,4966,2334],{"class":289},[272,4968,188],{"class":366},[272,4970,822],{"class":289},[272,4972,4973,4975,4977,4979,4981,4983,4985],{"class":274,"line":1177},[272,4974,4795],{"class":282},[272,4976,430],{"class":289},[272,4978,4800],{"class":354},[272,4980,357],{"class":366},[272,4982,4805],{"class":2297},[272,4984,188],{"class":366},[272,4986,822],{"class":289},[272,4988,4989],{"class":274,"line":1184},[272,4990,965],{"class":289},[272,4992,4993],{"class":274,"line":1192},[272,4994,302],{"emptyLinePlaceholder":169},[272,4996,4997,4999,5002,5004,5007,5009,5012,5015,5017,5020],{"class":274,"line":1200},[272,4998,2288],{"class":781},[272,5000,5001],{"class":282}," firstTypeArg ",[272,5003,2294],{"class":289},[272,5005,5006],{"class":282}," callExpr",[272,5008,430],{"class":289},[272,5010,5011],{"class":354},"getTypeArguments",[272,5013,5014],{"class":282},"()[",[272,5016,3374],{"class":2297},[272,5018,5019],{"class":282},"]",[272,5021,822],{"class":289},[272,5023,5024,5026,5028,5030,5033],{"class":274,"line":1208},[272,5025,2305],{"class":278},[272,5027,2493],{"class":282},[272,5029,4750],{"class":289},[272,5031,5032],{"class":282},"firstTypeArg) ",[272,5034,360],{"class":289},[272,5036,5037,5039,5041,5043,5045,5047,5050,5052,5054],{"class":274,"line":1216},[272,5038,2324],{"class":282},[272,5040,430],{"class":289},[272,5042,2329],{"class":354},[272,5044,357],{"class":366},[272,5046,2334],{"class":289},[272,5048,5049],{"class":293},"no type is found",[272,5051,2334],{"class":289},[272,5053,188],{"class":366},[272,5055,822],{"class":289},[272,5057,5058,5060,5062,5064,5066,5068,5070],{"class":274,"line":1221},[272,5059,4795],{"class":282},[272,5061,430],{"class":289},[272,5063,4800],{"class":354},[272,5065,357],{"class":366},[272,5067,4805],{"class":2297},[272,5069,188],{"class":366},[272,5071,822],{"class":289},[272,5073,5074],{"class":274,"line":1229},[272,5075,965],{"class":289},[272,5077,5078],{"class":274,"line":1237},[272,5079,302],{"emptyLinePlaceholder":169},[272,5081,5082,5084,5087,5089,5092,5094,5097,5099,5101,5104],{"class":274,"line":1245},[272,5083,2288],{"class":781},[272,5085,5086],{"class":282}," typeLiteralNode ",[272,5088,2294],{"class":289},[272,5090,5091],{"class":282}," firstTypeArg",[272,5093,430],{"class":289},[272,5095,5096],{"class":354},"asKindOrThrow",[272,5098,4929],{"class":282},[272,5100,430],{"class":289},[272,5102,5103],{"class":282},"TypeLiteral)",[272,5105,822],{"class":289},[272,5107,5108,5110,5113,5115,5118,5120,5123,5125],{"class":274,"line":1253},[272,5109,2288],{"class":781},[272,5111,5112],{"class":282}," properties ",[272,5114,2294],{"class":289},[272,5116,5117],{"class":282}," typeLiteralNode",[272,5119,430],{"class":289},[272,5121,5122],{"class":354},"getProperties",[272,5124,506],{"class":282},[272,5126,822],{"class":289},[272,5128,5129,5132,5134,5137,5139,5141,5144,5146,5148],{"class":274,"line":1261},[272,5130,5131],{"class":282},"properties",[272,5133,430],{"class":289},[272,5135,5136],{"class":354},"forEach",[272,5138,357],{"class":282},[272,5140,357],{"class":289},[272,5142,5143],{"class":2496},"property",[272,5145,188],{"class":289},[272,5147,3089],{"class":781},[272,5149,373],{"class":289},[272,5151,5152,5154,5156,5158,5160,5162,5165,5168,5171,5173],{"class":274,"line":1269},[272,5153,3562],{"class":278},[272,5155,2493],{"class":366},[272,5157,5143],{"class":282},[272,5159,430],{"class":289},[272,5161,3782],{"class":354},[272,5163,5164],{"class":366},"() ",[272,5166,5167],{"class":289},"===",[272,5169,5170],{"class":282}," oldPropName",[272,5172,2317],{"class":366},[272,5174,360],{"class":289},[272,5176,5177,5180,5182,5185,5187,5190,5192],{"class":274,"line":1277},[272,5178,5179],{"class":282},"    property",[272,5181,430],{"class":289},[272,5183,5184],{"class":354},"rename",[272,5186,357],{"class":366},[272,5188,5189],{"class":282},"newPropName",[272,5191,188],{"class":366},[272,5193,822],{"class":289},[272,5195,5196],{"class":274,"line":1285},[272,5197,909],{"class":289},[272,5199,5200,5202,5204],{"class":274,"line":1293},[272,5201,677],{"class":289},[272,5203,188],{"class":282},[272,5205,822],{"class":289},[245,5207,5209],{"id":5208},"_3-ファイルへ書き換える","3. ファイルへ書き換える",[15,5211,5212],{},"後は最初取得した SFC の script 部分を置換していく。",[264,5214,5216],{"className":266,"code":5215,"filename":4239,"language":268,"meta":154,"style":154},"const replaced = sfc.replace(\n  \u002F\u003Cscript[\\s\\S]*?\u003C\\\u002Fscript>\u002F,\n  `\u003Cscript>${sourceFile.getText()}\u003C\u002Fscript>`,\n);\nawait Deno.writeTextFile(\".\u002Fafter.vue\", replaced);\n\nconsole.log(\"convert done\");\n",[203,5217,5218,5237,5267,5294,5300,5328,5332],{"__ignoreMap":154},[272,5219,5220,5222,5225,5227,5230,5232,5235],{"class":274,"line":275},[272,5221,2288],{"class":781},[272,5223,5224],{"class":282}," replaced ",[272,5226,2294],{"class":289},[272,5228,5229],{"class":282}," sfc",[272,5231,430],{"class":289},[272,5233,5234],{"class":354},"replace",[272,5236,2718],{"class":282},[272,5238,5239,5242,5245,5248,5251,5254,5256,5259,5262,5265],{"class":274,"line":155},[272,5240,5241],{"class":289},"  \u002F",[272,5243,5244],{"class":293},"\u003Cscript",[272,5246,5247],{"class":289},"[",[272,5249,5250],{"class":293},"\\s\\S",[272,5252,5253],{"class":289},"]*?",[272,5255,3081],{"class":293},[272,5257,5258],{"class":282},"\\\u002F",[272,5260,5261],{"class":293},"script>",[272,5263,5264],{"class":289},"\u002F",[272,5266,406],{"class":289},[272,5268,5269,5272,5275,5277,5279,5281,5283,5285,5287,5290,5292],{"class":274,"line":305},[272,5270,5271],{"class":289},"  `",[272,5273,5274],{"class":293},"\u003Cscript>",[272,5276,2830],{"class":289},[272,5278,3110],{"class":282},[272,5280,430],{"class":289},[272,5282,2837],{"class":354},[272,5284,506],{"class":282},[272,5286,677],{"class":289},[272,5288,5289],{"class":293},"\u003C\u002Fscript>",[272,5291,2129],{"class":289},[272,5293,406],{"class":289},[272,5295,5296,5298],{"class":274,"line":340},[272,5297,188],{"class":282},[272,5299,822],{"class":289},[272,5301,5302,5305,5307,5309,5312,5314,5316,5319,5321,5323,5326],{"class":274,"line":345},[272,5303,5304],{"class":278},"await",[272,5306,4282],{"class":282},[272,5308,430],{"class":289},[272,5310,5311],{"class":354},"writeTextFile",[272,5313,357],{"class":282},[272,5315,2334],{"class":289},[272,5317,5318],{"class":293},".\u002Fafter.vue",[272,5320,2334],{"class":289},[272,5322,316],{"class":289},[272,5324,5325],{"class":282}," replaced)",[272,5327,822],{"class":289},[272,5329,5330],{"class":274,"line":363},[272,5331,302],{"emptyLinePlaceholder":169},[272,5333,5334,5336,5338,5340,5342,5344,5347,5349,5351],{"class":274,"line":376},[272,5335,3351],{"class":282},[272,5337,430],{"class":289},[272,5339,2329],{"class":354},[272,5341,357],{"class":282},[272,5343,2334],{"class":289},[272,5345,5346],{"class":293},"convert done",[272,5348,2334],{"class":289},[272,5350,188],{"class":282},[272,5352,822],{"class":289},[11,5354,2194],{"id":2194},[15,5356,5357],{},"今回は AST の基本から ts-morph を使って Vue.js SFC の script 部分の書き換えまでを一通りまとめた。やはりファイルの内容を手動で置き換える必要がないのは、非常に魅力的であった。今回はファイル書き換えを目標に少し内容が薄く広いものになってしまったが、この記事にまとめるのをきっかけに AST の違う利用先を知っていきたい。Language Server Protocol を使い IDE とエディタがどう修飾子に色をつけているかなどやカスタムの eslint のルールを作成するときに役に立つことを期待している。そのときに学んだことは随時追記していくので、この記事がアウトプットの場として質を向上していく。",[11,5359,5360],{"id":5360},"参考にしたサイト",[57,5362],{"link":5363},"https:\u002F\u002Frabbit-house.tokyo\u002Fast-book-sample.pdf",[57,5365],{"link":5366},"https:\u002F\u002Fwww.docswell.com\u002Fs\u002Fhireroo\u002FK382Y1-tskaigi-2024-05-11-11-30",[57,5368],{"link":5369},"https:\u002F\u002Fcreators.bengo4.com\u002Fentry\u002F2024\u002F12\u002F16\u002F000000",[57,5371],{"link":5372},"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fflutter_ast",[57,5374],{"link":5375},"https:\u002F\u002Fzenn.dev\u002Fhakshu\u002Farticles\u002Freplace-ts-code-by-ast",[57,5377],{"link":5378},"https:\u002F\u002Fzenn.dev\u002Fgmomedia\u002Farticles\u002F127ca64e9b7018",[57,5380],{"link":5381},"https:\u002F\u002Fqiita.com\u002Ftomoasleep\u002Fitems\u002Fd05e05ae14dce1b80d9d",[2211,5383,5384],{},"html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .s0_hs, html code.shiki .s0_hs{--shiki-default:#546E7A;--shiki-default-font-style:italic}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}",{"title":154,"searchDepth":155,"depth":155,"links":5386},[5387,5388,5389,5393,5394,5399,5400],{"id":2255,"depth":155,"text":2255},{"id":2266,"depth":155,"text":2267},{"id":2560,"depth":155,"text":2561,"children":5390},[5391,5392],{"id":2567,"depth":305,"text":2567},{"id":2955,"depth":305,"text":2955},{"id":3392,"depth":155,"text":3393},{"id":3971,"depth":155,"text":3972,"children":5395},[5396,5397,5398],{"id":3991,"depth":305,"text":3992},{"id":4518,"depth":305,"text":4519},{"id":5208,"depth":305,"text":5209},{"id":2194,"depth":155,"text":2194},{"id":5360,"depth":155,"text":5360},[2229,5402,5403,2230],"TypeScript","Vue.js",{},"\u002Ftech\u002Fintroduction-to-ast","2025-01-02",{"title":2240,"description":2240},"tech\u002Fintroduction-to-ast","1pLoR4ZoJQy0g1aV6-Vx2vMlyoqKxfUqxg_zQv2nFAw",{"id":5411,"title":5412,"body":5413,"categories":8393,"description":8394,"draft":166,"extension":167,"meta":8395,"navigation":169,"path":8396,"priority":171,"publishedAt":8397,"secret":166,"seo":8398,"stem":8399,"updatedAt":8400,"__hash__":8401},"posts\u002Ftech\u002Flink-card-by-nuxt-server-component.md","Nuxt Server Components で作るリンクカード",{"type":8,"value":5414,"toc":8379},[5415,5424,5427,5434,5437,5440,5443,5446,5449,5462,5466,5469,5483,5492,5506,5509,5520,5568,5571,5582,6183,6186,6193,6294,6722,6725,6732,7301,7304,7307,7317,7351,7355,7358,7362,7373,7496,7502,7585,7595,7598,7601,7612,7861,7864,8292,8295,8301,8304,8360,8365,8368,8371,8373,8376],[15,5416,5417,5418,5423],{},"これは ",[80,5419,5422],{"href":5420,"rel":5421,"target":87},"https:\u002F\u002Fqiita.com\u002Fadvent-calendar\u002F2024\u002Fnuxt-and-unjs",[84,85,86],"Nuxt \u002F UnJS Advent Calendar 2024"," の 2 日目の記事です。",[11,5425,5426],{"id":5426},"概要",[15,5428,5429,5433],{},[80,5430,5432],{"href":5431},"\u002Ftech\u002Fbuilt-portfolio-by-nuxt-ssg","自ブログをリリース","して約 3 ヶ月ほど経ちますが、新しく記事を書いたり新機能を作ったりなど、ブログ開発が充実している毎日です。他人のブログを見る機会が増え、参考になるところは取り入れています。今回はそんな作成した機能の中で、Nuxt Server Components を使ってのリンクカードをリリースした話を記事にまとめました。",[11,5435,5436],{"id":5436},"作ったもの",[15,5438,5439],{},"表示内容としては下の感じになります。",[57,5441],{"link":5442},"https:\u002F\u002Fnuxt.com\u002F",[11,5444,5445],{"id":5445},"使用技術",[15,5447,5448],{},"ここでは、2 つの技術スタックで作るものとします。",[35,5450,5451,5458],{},[38,5452,5453,5454,5457],{},"Nuxt.js ",[203,5455,5456],{},"3.12.4"," (SSG アプリケーション)",[38,5459,5460],{},[203,5461,335],{},[11,5463,5465],{"id":5464},"nuxt-server-components-について","Nuxt Server Components について",[15,5467,5468],{},"Web アプリケーションを開発するにあたって、レンダリング方式をどれにするか決めることは避けられません。多くのケースで下の中から選択するのではないでしょうか。(ここではそれぞれがどんなレンダリング方式やメリット、デメリットについては割愛します。)",[35,5470,5471,5474,5477,5480],{},[38,5472,5473],{},"CSR(client-side rendering)",[38,5475,5476],{},"SSR(server-side rendering)",[38,5478,5479],{},"SSG(static-site generation)",[38,5481,5482],{},"ISR(incremental site generation)",[15,5484,5485,5486,5491],{},"Nuxt で Web アプリケーションを開発するときにも、どのレンダリング方式を使用するか決められます。今までの Nuxt 、少なくともメジャーバージョンが 2 のときは、レンダリング方式がアプリケーション全体で 1 つとなっていましたが、今ではページのパスごとで決められるようになりました。これは ",[80,5487,5490],{"href":5488,"rel":5489,"target":87},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fguide\u002Fconcepts\u002Frendering#hybrid-rendering",[84,85,86],"Hybrid Rendering"," と呼ばれ、公式サイトに詳しく書かれています。",[15,5493,5494,5495,3413,5500,5505],{},"ページ毎に変更できるだけで素晴らしいことでもすが、このレンダリング方式をコンポーネント単位で決めることも可能になりました。そこれで登場するのが ",[80,5496,5499],{"href":5497,"rel":5498,"target":87},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fguide\u002Fdirectory-structure\u002Fcomponents#client-components",[84,85,86],"Nuxt Client Components",[80,5501,5504],{"href":5502,"rel":5503,"target":87},"https:\u002F\u002Fnuxt.com\u002Fdocs\u002Fguide\u002Fdirectory-structure\u002Fcomponents#server-components",[84,85,86],"Nuxt Server Components"," になります。この記事では、Nuxt Server Components に焦点を当てます。",[15,5507,5508],{},"Nuxt Server Components は、文字通りコンポーネント 1 つ 1 つがサーバーでレンダリングされる仕組みです。クライアント用の JavaScript がブラウザから取得されないので、Web 開発のテーマの「SHIP LESS JavaScript」を推進するものになります。Hydration が発生しないため、ブラウザ側で実行される onMounted などのライスサイクルや input や button、 scroll イベントハンドリングが実行されません。内部変数のりアクティビティも失われます。さらに、DOM API も動作しないことを事前に考慮する必要があります。",[15,5510,5511,5512,5515,5516,5519],{},"下の ",[203,5513,5514],{},"experimental.componentIsLands"," オプションに true を渡し、コンポーネントに ",[203,5517,5518],{},".server.vue"," をつければ、動作検証が可能です。",[264,5521,5523],{"className":266,"code":5522,"filename":982,"language":268,"meta":154,"style":154},"export default defineNuxtConfig({\n  experimental: {\n    componentIslands: true,\n  },\n})\n",[203,5524,5525,5538,5547,5558,5562],{"__ignoreMap":154},[272,5526,5527,5529,5531,5534,5536],{"class":274,"line":275},[272,5528,348],{"class":278},[272,5530,351],{"class":278},[272,5532,5533],{"class":354}," defineNuxtConfig",[272,5535,357],{"class":282},[272,5537,360],{"class":289},[272,5539,5540,5543,5545],{"class":274,"line":155},[272,5541,5542],{"class":366},"  experimental",[272,5544,370],{"class":289},[272,5546,373],{"class":289},[272,5548,5549,5552,5554,5556],{"class":274,"line":305},[272,5550,5551],{"class":366},"    componentIslands",[272,5553,370],{"class":289},[272,5555,3513],{"class":2762},[272,5557,406],{"class":289},[272,5559,5560],{"class":274,"line":340},[272,5561,671],{"class":289},[272,5563,5564,5566],{"class":274,"line":345},[272,5565,677],{"class":289},[272,5567,680],{"class":282},[11,5569,5570],{"id":5570},"検討したきっかけ",[15,5572,5573,5574,5577,5578,5581],{},"リンクカードを実装するときに、頭を悩ませたのが、サイトの metadata をどのように適切なタイミングで取得するかでした。下のように、指定したサイトへリクエストを送るコンポーネントを開発していると、ローカルでページ遷移時に、 CORS 問題が出てきました。vite の hot update でブログの記事内容を更新するときに、クライアントのほうで ",[203,5575,5576],{},"useAsyncData"," や ",[203,5579,5580],{},"useFetch"," が実行され、同じ問題が起こります。",[264,5583,5586],{"className":4009,"code":5584,"filename":5585,"language":4012,"meta":154,"style":154},"\u003Cscript setup lang=\"ts\">\nimport { useAsyncData } from '#imports'\n\nimport type { SiteMetadata } from '~\u002Ftypes\u002Fmetedata'\n\nconst props = defineProps\u003C{\n  url: string\n}>()\n\nconst { data } = await useAsyncData\u003C{ metadata: SiteMetadata | null }>(`link-card-${props.url}`, () => {\n   try {\n    const response = await $fetch.native(url,\n      {\n        method: 'get',\n      })\n\n    const html = await response.text()\n    const metadata: SiteMetadata = { url, title: null }\n    const loaded = load(html)\n\n    const metaTags = loaded('meta')\n\n    for (const meta of metaTags) {\n      const property = meta.attribs.property\n\n      if (property === 'og:title') {\n        metadata.title = meta.attribs.content || null\n      }\n    }\n\n    return { metadata }\n  } catch {\n    return { metadata: null }\n  }\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Ca\n    v-if=\"data\"\n    :href=\"url\"\n  >\n    \u003Cdiv>\n      \u003Cp>\n        {{ data.metadata?.title || url }}\n      \u003C\u002Fp>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ftemplate>\n","components\u002FLinkCard.vue",[203,5587,5588,5608,5627,5631,5653,5657,5672,5682,5689,5693,5755,5762,5787,5792,5808,5814,5818,5837,5865,5884,5888,5910,5914,5935,5957,5961,5982,6010,6014,6019,6023,6033,6043,6057,6061,6067,6075,6079,6087,6094,6109,6122,6127,6135,6144,6149,6158,6167,6175],{"__ignoreMap":154},[272,5589,5590,5592,5594,5596,5598,5600,5602,5604,5606],{"class":274,"line":275},[272,5591,3081],{"class":289},[272,5593,4021],{"class":366},[272,5595,4035],{"class":781},[272,5597,4024],{"class":781},[272,5599,2294],{"class":289},[272,5601,2334],{"class":289},[272,5603,268],{"class":293},[272,5605,2334],{"class":289},[272,5607,4038],{"class":289},[272,5609,5610,5612,5614,5617,5619,5621,5623,5625],{"class":274,"line":155},[272,5611,279],{"class":278},[272,5613,310],{"class":289},[272,5615,5616],{"class":282}," useAsyncData",[272,5618,327],{"class":289},[272,5620,330],{"class":278},[272,5622,290],{"class":289},[272,5624,4056],{"class":293},[272,5626,297],{"class":289},[272,5628,5629],{"class":274,"line":305},[272,5630,302],{"emptyLinePlaceholder":169},[272,5632,5633,5635,5637,5639,5642,5644,5646,5648,5651],{"class":274,"line":340},[272,5634,279],{"class":278},[272,5636,752],{"class":278},[272,5638,310],{"class":289},[272,5640,5641],{"class":282}," SiteMetadata",[272,5643,327],{"class":289},[272,5645,330],{"class":278},[272,5647,290],{"class":289},[272,5649,5650],{"class":293},"~\u002Ftypes\u002Fmetedata",[272,5652,297],{"class":289},[272,5654,5655],{"class":274,"line":345},[272,5656,302],{"emptyLinePlaceholder":169},[272,5658,5659,5661,5664,5666,5669],{"class":274,"line":363},[272,5660,2288],{"class":781},[272,5662,5663],{"class":282}," props ",[272,5665,2294],{"class":289},[272,5667,5668],{"class":354}," defineProps",[272,5670,5671],{"class":289},"\u003C{\n",[272,5673,5674,5677,5679],{"class":274,"line":376},[272,5675,5676],{"class":366},"  url",[272,5678,370],{"class":289},[272,5680,5681],{"class":801}," string\n",[272,5683,5684,5687],{"class":274,"line":390},[272,5685,5686],{"class":289},"}>",[272,5688,4082],{"class":282},[272,5690,5691],{"class":274,"line":409},[272,5692,302],{"emptyLinePlaceholder":169},[272,5694,5695,5697,5699,5702,5704,5706,5708,5710,5712,5715,5717,5719,5722,5725,5727,5729,5731,5734,5736,5739,5741,5744,5746,5748,5751,5753],{"class":274,"line":419},[272,5696,2288],{"class":781},[272,5698,310],{"class":289},[272,5700,5701],{"class":282}," data ",[272,5703,677],{"class":289},[272,5705,3127],{"class":289},[272,5707,4279],{"class":278},[272,5709,5616],{"class":354},[272,5711,4069],{"class":289},[272,5713,5714],{"class":366}," metadata",[272,5716,370],{"class":289},[272,5718,5641],{"class":801},[272,5720,5721],{"class":289}," |",[272,5723,5724],{"class":801}," null",[272,5726,4079],{"class":289},[272,5728,357],{"class":282},[272,5730,2129],{"class":289},[272,5732,5733],{"class":293},"link-card-",[272,5735,2830],{"class":289},[272,5737,5738],{"class":282},"props",[272,5740,430],{"class":289},[272,5742,5743],{"class":282},"url",[272,5745,2842],{"class":289},[272,5747,316],{"class":289},[272,5749,5750],{"class":289}," ()",[272,5752,3089],{"class":781},[272,5754,373],{"class":289},[272,5756,5757,5760],{"class":274,"line":449},[272,5758,5759],{"class":278},"   try",[272,5761,373],{"class":289},[272,5763,5764,5766,5769,5771,5773,5776,5778,5781,5783,5785],{"class":274,"line":466},[272,5765,3121],{"class":781},[272,5767,5768],{"class":282}," response",[272,5770,3127],{"class":289},[272,5772,4279],{"class":278},[272,5774,5775],{"class":282}," $fetch",[272,5777,430],{"class":289},[272,5779,5780],{"class":354},"native",[272,5782,357],{"class":366},[272,5784,5743],{"class":282},[272,5786,406],{"class":289},[272,5788,5789],{"class":274,"line":472},[272,5790,5791],{"class":289},"      {\n",[272,5793,5794,5797,5799,5801,5804,5806],{"class":274,"line":491},[272,5795,5796],{"class":366},"        method",[272,5798,370],{"class":289},[272,5800,290],{"class":289},[272,5802,5803],{"class":293},"get",[272,5805,403],{"class":289},[272,5807,406],{"class":289},[272,5809,5810,5812],{"class":274,"line":511},[272,5811,651],{"class":289},[272,5813,680],{"class":366},[272,5815,5816],{"class":274,"line":529},[272,5817,302],{"emptyLinePlaceholder":169},[272,5819,5820,5822,5825,5827,5829,5831,5833,5835],{"class":274,"line":547},[272,5821,3121],{"class":781},[272,5823,5824],{"class":282}," html",[272,5826,3127],{"class":289},[272,5828,4279],{"class":278},[272,5830,5768],{"class":282},[272,5832,430],{"class":289},[272,5834,726],{"class":354},[272,5836,4082],{"class":366},[272,5838,5839,5841,5843,5845,5847,5849,5851,5854,5856,5859,5861,5863],{"class":274,"line":565},[272,5840,3121],{"class":781},[272,5842,5714],{"class":282},[272,5844,370],{"class":289},[272,5846,5641],{"class":801},[272,5848,3127],{"class":289},[272,5850,310],{"class":289},[272,5852,5853],{"class":282}," url",[272,5855,316],{"class":289},[272,5857,5858],{"class":366}," title",[272,5860,370],{"class":289},[272,5862,5724],{"class":289},[272,5864,1861],{"class":289},[272,5866,5867,5869,5872,5874,5877,5879,5882],{"class":274,"line":592},[272,5868,3121],{"class":781},[272,5870,5871],{"class":282}," loaded",[272,5873,3127],{"class":289},[272,5875,5876],{"class":354}," load",[272,5878,357],{"class":366},[272,5880,5881],{"class":282},"html",[272,5883,680],{"class":366},[272,5885,5886],{"class":274,"line":611},[272,5887,302],{"emptyLinePlaceholder":169},[272,5889,5890,5892,5895,5897,5899,5901,5903,5906,5908],{"class":274,"line":629},[272,5891,3121],{"class":781},[272,5893,5894],{"class":282}," metaTags",[272,5896,3127],{"class":289},[272,5898,5871],{"class":354},[272,5900,357],{"class":366},[272,5902,403],{"class":289},[272,5904,5905],{"class":293},"meta",[272,5907,403],{"class":289},[272,5909,680],{"class":366},[272,5911,5912],{"class":274,"line":648},[272,5913,302],{"emptyLinePlaceholder":169},[272,5915,5916,5919,5921,5923,5926,5929,5931,5933],{"class":274,"line":658},[272,5917,5918],{"class":278},"    for",[272,5920,2493],{"class":366},[272,5922,2288],{"class":781},[272,5924,5925],{"class":282}," meta",[272,5927,5928],{"class":289}," of",[272,5930,5894],{"class":282},[272,5932,2317],{"class":366},[272,5934,360],{"class":289},[272,5936,5937,5940,5943,5945,5947,5949,5952,5954],{"class":274,"line":668},[272,5938,5939],{"class":781},"      const",[272,5941,5942],{"class":282}," property",[272,5944,3127],{"class":289},[272,5946,5925],{"class":282},[272,5948,430],{"class":289},[272,5950,5951],{"class":282},"attribs",[272,5953,430],{"class":289},[272,5955,5956],{"class":282},"property\n",[272,5958,5959],{"class":274,"line":674},[272,5960,302],{"emptyLinePlaceholder":169},[272,5962,5963,5965,5967,5969,5971,5973,5976,5978,5980],{"class":274,"line":1161},[272,5964,3149],{"class":278},[272,5966,2493],{"class":366},[272,5968,5143],{"class":282},[272,5970,3173],{"class":289},[272,5972,290],{"class":289},[272,5974,5975],{"class":293},"og:title",[272,5977,403],{"class":289},[272,5979,2317],{"class":366},[272,5981,360],{"class":289},[272,5983,5984,5987,5989,5992,5994,5996,5998,6000,6002,6004,6007],{"class":274,"line":1169},[272,5985,5986],{"class":282},"        metadata",[272,5988,430],{"class":289},[272,5990,5991],{"class":282},"title",[272,5993,3127],{"class":289},[272,5995,5925],{"class":282},[272,5997,430],{"class":289},[272,5999,5951],{"class":282},[272,6001,430],{"class":289},[272,6003,696],{"class":282},[272,6005,6006],{"class":289}," ||",[272,6008,6009],{"class":289}," null\n",[272,6011,6012],{"class":274,"line":1177},[272,6013,3213],{"class":289},[272,6015,6016],{"class":274,"line":1184},[272,6017,6018],{"class":289},"    }\n",[272,6020,6021],{"class":274,"line":1192},[272,6022,302],{"emptyLinePlaceholder":169},[272,6024,6025,6027,6029,6031],{"class":274,"line":1200},[272,6026,3256],{"class":278},[272,6028,310],{"class":289},[272,6030,5714],{"class":282},[272,6032,1861],{"class":289},[272,6034,6035,6038,6041],{"class":274,"line":1208},[272,6036,6037],{"class":289},"  }",[272,6039,6040],{"class":278}," catch",[272,6042,373],{"class":289},[272,6044,6045,6047,6049,6051,6053,6055],{"class":274,"line":1216},[272,6046,3256],{"class":278},[272,6048,310],{"class":289},[272,6050,5714],{"class":366},[272,6052,370],{"class":289},[272,6054,5724],{"class":289},[272,6056,1861],{"class":289},[272,6058,6059],{"class":274,"line":1221},[272,6060,909],{"class":289},[272,6062,6063,6065],{"class":274,"line":1229},[272,6064,677],{"class":289},[272,6066,680],{"class":282},[272,6068,6069,6071,6073],{"class":274,"line":1237},[272,6070,4113],{"class":289},[272,6072,4021],{"class":366},[272,6074,4038],{"class":289},[272,6076,6077],{"class":274,"line":1245},[272,6078,302],{"emptyLinePlaceholder":169},[272,6080,6081,6083,6085],{"class":274,"line":1253},[272,6082,3081],{"class":289},[272,6084,4128],{"class":366},[272,6086,4038],{"class":289},[272,6088,6089,6091],{"class":274,"line":1261},[272,6090,4135],{"class":289},[272,6092,6093],{"class":366},"a\n",[272,6095,6096,6099,6101,6103,6106],{"class":274,"line":1269},[272,6097,6098],{"class":781},"    v-if",[272,6100,2294],{"class":289},[272,6102,2334],{"class":289},[272,6104,6105],{"class":293},"data",[272,6107,6108],{"class":289},"\"\n",[272,6110,6111,6114,6116,6118,6120],{"class":274,"line":1277},[272,6112,6113],{"class":781},"    :href",[272,6115,2294],{"class":289},[272,6117,2334],{"class":289},[272,6119,5743],{"class":293},[272,6121,6108],{"class":289},[272,6123,6124],{"class":274,"line":1285},[272,6125,6126],{"class":289},"  >\n",[272,6128,6129,6131,6133],{"class":274,"line":1293},[272,6130,4157],{"class":289},[272,6132,4138],{"class":366},[272,6134,4038],{"class":289},[272,6136,6137,6140,6142],{"class":274,"line":1301},[272,6138,6139],{"class":289},"      \u003C",[272,6141,15],{"class":366},[272,6143,4038],{"class":289},[272,6145,6146],{"class":274,"line":1309},[272,6147,6148],{"class":282},"        {{ data.metadata?.title || url }}\n",[272,6150,6151,6154,6156],{"class":274,"line":1317},[272,6152,6153],{"class":289},"      \u003C\u002F",[272,6155,15],{"class":366},[272,6157,4038],{"class":289},[272,6159,6160,6163,6165],{"class":274,"line":1325},[272,6161,6162],{"class":289},"    \u003C\u002F",[272,6164,4138],{"class":366},[272,6166,4038],{"class":289},[272,6168,6169,6171,6173],{"class":274,"line":1333},[272,6170,4175],{"class":289},[272,6172,80],{"class":366},[272,6174,4038],{"class":289},[272,6176,6177,6179,6181],{"class":274,"line":1341},[272,6178,4113],{"class":289},[272,6180,4128],{"class":366},[272,6182,4038],{"class":289},[15,6184,6185],{},"ちなみに、これはローカル開発時だけに起こりうるものになります。SSG アプリケーションであるため、サイトの metadata 取得やレンダリングは事前のビルド時にサーバー内で行われ、本番ではページ遷移時でブラウザからのリクエストが送られることはありません。\nそのためそこまで対応が迫られるレベルの問題ではないですが、毎度リロードをかけて動作確認をするのも手間であり、ページ遷移時や記事の内容更新時に正常に動作して欲しいことから、解決方法を考えました。",[15,6187,6188,6189,6192],{},"最初思いついた案としては、Nuxt.js の ",[203,6190,6191],{},"server"," ディレクトリを利用し、API サーバーを立てることを考えました。指定したサイトから CORS ヘッダーが送られていないことがほとんどなので、サーバー側から metadata を取得しながらも CORS ヘッダーを返すように実装します。最初のアクセス時とページ遷移時の両方で、コンポーネントからは自分で実装した API を叩き、内部で metadata を取得します。このアプローチのメリットは、スクレイピング処理に必要な処理やライブラリを隠蔽でき、クライアントへ転送される JavaScript を少なくできます。",[264,6194,6196],{"className":4009,"code":6195,"filename":5585,"language":4012,"meta":154,"style":154},"\u003Cscript lang=\"ts\" setup>\nconst { data } = await useFetch\u003C{ metadata: SiteMetadata | null }>('\u002Fapi\u002Fmetadata', { query: { url: props.url }})\n\u003C\u002Fscript>\n",[203,6197,6198,6218,6286],{"__ignoreMap":154},[272,6199,6200,6202,6204,6206,6208,6210,6212,6214,6216],{"class":274,"line":275},[272,6201,3081],{"class":289},[272,6203,4021],{"class":366},[272,6205,4024],{"class":781},[272,6207,2294],{"class":289},[272,6209,2334],{"class":289},[272,6211,268],{"class":293},[272,6213,2334],{"class":289},[272,6215,4035],{"class":781},[272,6217,4038],{"class":289},[272,6219,6220,6222,6224,6226,6228,6230,6232,6235,6237,6239,6241,6243,6245,6247,6249,6251,6253,6256,6258,6260,6262,6265,6267,6269,6271,6273,6276,6278,6281,6284],{"class":274,"line":155},[272,6221,2288],{"class":781},[272,6223,310],{"class":289},[272,6225,5701],{"class":282},[272,6227,677],{"class":289},[272,6229,3127],{"class":289},[272,6231,4279],{"class":278},[272,6233,6234],{"class":354}," useFetch",[272,6236,4069],{"class":289},[272,6238,5714],{"class":366},[272,6240,370],{"class":289},[272,6242,5641],{"class":801},[272,6244,5721],{"class":289},[272,6246,5724],{"class":801},[272,6248,4079],{"class":289},[272,6250,357],{"class":282},[272,6252,403],{"class":289},[272,6254,6255],{"class":293},"\u002Fapi\u002Fmetadata",[272,6257,403],{"class":289},[272,6259,316],{"class":289},[272,6261,310],{"class":289},[272,6263,6264],{"class":366}," query",[272,6266,370],{"class":289},[272,6268,310],{"class":289},[272,6270,5853],{"class":366},[272,6272,370],{"class":289},[272,6274,6275],{"class":282}," props",[272,6277,430],{"class":289},[272,6279,6280],{"class":282},"url ",[272,6282,6283],{"class":289},"}}",[272,6285,680],{"class":282},[272,6287,6288,6290,6292],{"class":274,"line":305},[272,6289,4113],{"class":289},[272,6291,4021],{"class":366},[272,6293,4038],{"class":289},[264,6295,6298],{"className":266,"code":6296,"filename":6297,"language":268,"meta":154,"style":154},"import { defineEventHandler, getQuery } from '#imports'\n\nimport { load } from 'cheerio'\nimport { $fetch } from 'ofetch'\n\nimport type { SiteMetadata } from '~\u002Ftypes\u002Fmetedata'\n\nexport default defineEventHandler(async (event) => {\n  const query = getQuery(event)\n\n  try {\n    const response = await $fetch.native(url,\n      {\n        method: 'get',\n      })\n\n    const html = await response.text()\n    const metadata: SiteMetadata = { url, title: null }\n    const loaded = load(html)\n\n    const metaTags = loaded('meta')\n\n    for (const meta of metaTags) {\n      const property = meta.attribs.property\n\n      if (property === 'og:title') {\n        metadata.title = meta.attribs.content || null\n      }\n    }\n\n    return { metadata }\n  } catch {\n    return { metadata: null }\n  }\n})\n","server\u002Fapi\u002Fmetadata.ts",[203,6299,6300,6324,6328,6347,6366,6370,6390,6394,6418,6435,6439,6446,6468,6472,6486,6492,6496,6514,6540,6556,6560,6580,6584,6602,6620,6624,6644,6668,6672,6676,6680,6690,6698,6712,6716],{"__ignoreMap":154},[272,6301,6302,6304,6306,6309,6311,6314,6316,6318,6320,6322],{"class":274,"line":275},[272,6303,279],{"class":278},[272,6305,310],{"class":289},[272,6307,6308],{"class":282}," defineEventHandler",[272,6310,316],{"class":289},[272,6312,6313],{"class":282}," getQuery",[272,6315,327],{"class":289},[272,6317,330],{"class":278},[272,6319,290],{"class":289},[272,6321,4056],{"class":293},[272,6323,297],{"class":289},[272,6325,6326],{"class":274,"line":155},[272,6327,302],{"emptyLinePlaceholder":169},[272,6329,6330,6332,6334,6336,6338,6340,6342,6345],{"class":274,"line":305},[272,6331,279],{"class":278},[272,6333,310],{"class":289},[272,6335,5876],{"class":282},[272,6337,327],{"class":289},[272,6339,330],{"class":278},[272,6341,290],{"class":289},[272,6343,6344],{"class":293},"cheerio",[272,6346,297],{"class":289},[272,6348,6349,6351,6353,6355,6357,6359,6361,6364],{"class":274,"line":340},[272,6350,279],{"class":278},[272,6352,310],{"class":289},[272,6354,5775],{"class":282},[272,6356,327],{"class":289},[272,6358,330],{"class":278},[272,6360,290],{"class":289},[272,6362,6363],{"class":293},"ofetch",[272,6365,297],{"class":289},[272,6367,6368],{"class":274,"line":345},[272,6369,302],{"emptyLinePlaceholder":169},[272,6371,6372,6374,6376,6378,6380,6382,6384,6386,6388],{"class":274,"line":363},[272,6373,279],{"class":278},[272,6375,752],{"class":278},[272,6377,310],{"class":289},[272,6379,5641],{"class":282},[272,6381,327],{"class":289},[272,6383,330],{"class":278},[272,6385,290],{"class":289},[272,6387,5650],{"class":293},[272,6389,297],{"class":289},[272,6391,6392],{"class":274,"line":376},[272,6393,302],{"emptyLinePlaceholder":169},[272,6395,6396,6398,6400,6402,6404,6407,6409,6412,6414,6416],{"class":274,"line":390},[272,6397,348],{"class":278},[272,6399,351],{"class":278},[272,6401,6308],{"class":354},[272,6403,357],{"class":282},[272,6405,6406],{"class":781},"async",[272,6408,2493],{"class":289},[272,6410,6411],{"class":2496},"event",[272,6413,188],{"class":289},[272,6415,3089],{"class":781},[272,6417,373],{"class":289},[272,6419,6420,6423,6425,6427,6429,6431,6433],{"class":274,"line":409},[272,6421,6422],{"class":781},"  const",[272,6424,6264],{"class":282},[272,6426,3127],{"class":289},[272,6428,6313],{"class":354},[272,6430,357],{"class":366},[272,6432,6411],{"class":282},[272,6434,680],{"class":366},[272,6436,6437],{"class":274,"line":419},[272,6438,302],{"emptyLinePlaceholder":169},[272,6440,6441,6444],{"class":274,"line":449},[272,6442,6443],{"class":278},"  try",[272,6445,373],{"class":289},[272,6447,6448,6450,6452,6454,6456,6458,6460,6462,6464,6466],{"class":274,"line":466},[272,6449,3121],{"class":781},[272,6451,5768],{"class":282},[272,6453,3127],{"class":289},[272,6455,4279],{"class":278},[272,6457,5775],{"class":282},[272,6459,430],{"class":289},[272,6461,5780],{"class":354},[272,6463,357],{"class":366},[272,6465,5743],{"class":282},[272,6467,406],{"class":289},[272,6469,6470],{"class":274,"line":472},[272,6471,5791],{"class":289},[272,6473,6474,6476,6478,6480,6482,6484],{"class":274,"line":491},[272,6475,5796],{"class":366},[272,6477,370],{"class":289},[272,6479,290],{"class":289},[272,6481,5803],{"class":293},[272,6483,403],{"class":289},[272,6485,406],{"class":289},[272,6487,6488,6490],{"class":274,"line":511},[272,6489,651],{"class":289},[272,6491,680],{"class":366},[272,6493,6494],{"class":274,"line":529},[272,6495,302],{"emptyLinePlaceholder":169},[272,6497,6498,6500,6502,6504,6506,6508,6510,6512],{"class":274,"line":547},[272,6499,3121],{"class":781},[272,6501,5824],{"class":282},[272,6503,3127],{"class":289},[272,6505,4279],{"class":278},[272,6507,5768],{"class":282},[272,6509,430],{"class":289},[272,6511,726],{"class":354},[272,6513,4082],{"class":366},[272,6515,6516,6518,6520,6522,6524,6526,6528,6530,6532,6534,6536,6538],{"class":274,"line":565},[272,6517,3121],{"class":781},[272,6519,5714],{"class":282},[272,6521,370],{"class":289},[272,6523,5641],{"class":801},[272,6525,3127],{"class":289},[272,6527,310],{"class":289},[272,6529,5853],{"class":282},[272,6531,316],{"class":289},[272,6533,5858],{"class":366},[272,6535,370],{"class":289},[272,6537,5724],{"class":289},[272,6539,1861],{"class":289},[272,6541,6542,6544,6546,6548,6550,6552,6554],{"class":274,"line":592},[272,6543,3121],{"class":781},[272,6545,5871],{"class":282},[272,6547,3127],{"class":289},[272,6549,5876],{"class":354},[272,6551,357],{"class":366},[272,6553,5881],{"class":282},[272,6555,680],{"class":366},[272,6557,6558],{"class":274,"line":611},[272,6559,302],{"emptyLinePlaceholder":169},[272,6561,6562,6564,6566,6568,6570,6572,6574,6576,6578],{"class":274,"line":629},[272,6563,3121],{"class":781},[272,6565,5894],{"class":282},[272,6567,3127],{"class":289},[272,6569,5871],{"class":354},[272,6571,357],{"class":366},[272,6573,403],{"class":289},[272,6575,5905],{"class":293},[272,6577,403],{"class":289},[272,6579,680],{"class":366},[272,6581,6582],{"class":274,"line":648},[272,6583,302],{"emptyLinePlaceholder":169},[272,6585,6586,6588,6590,6592,6594,6596,6598,6600],{"class":274,"line":658},[272,6587,5918],{"class":278},[272,6589,2493],{"class":366},[272,6591,2288],{"class":781},[272,6593,5925],{"class":282},[272,6595,5928],{"class":289},[272,6597,5894],{"class":282},[272,6599,2317],{"class":366},[272,6601,360],{"class":289},[272,6603,6604,6606,6608,6610,6612,6614,6616,6618],{"class":274,"line":668},[272,6605,5939],{"class":781},[272,6607,5942],{"class":282},[272,6609,3127],{"class":289},[272,6611,5925],{"class":282},[272,6613,430],{"class":289},[272,6615,5951],{"class":282},[272,6617,430],{"class":289},[272,6619,5956],{"class":282},[272,6621,6622],{"class":274,"line":674},[272,6623,302],{"emptyLinePlaceholder":169},[272,6625,6626,6628,6630,6632,6634,6636,6638,6640,6642],{"class":274,"line":1161},[272,6627,3149],{"class":278},[272,6629,2493],{"class":366},[272,6631,5143],{"class":282},[272,6633,3173],{"class":289},[272,6635,290],{"class":289},[272,6637,5975],{"class":293},[272,6639,403],{"class":289},[272,6641,2317],{"class":366},[272,6643,360],{"class":289},[272,6645,6646,6648,6650,6652,6654,6656,6658,6660,6662,6664,6666],{"class":274,"line":1169},[272,6647,5986],{"class":282},[272,6649,430],{"class":289},[272,6651,5991],{"class":282},[272,6653,3127],{"class":289},[272,6655,5925],{"class":282},[272,6657,430],{"class":289},[272,6659,5951],{"class":282},[272,6661,430],{"class":289},[272,6663,696],{"class":282},[272,6665,6006],{"class":289},[272,6667,6009],{"class":289},[272,6669,6670],{"class":274,"line":1177},[272,6671,3213],{"class":289},[272,6673,6674],{"class":274,"line":1184},[272,6675,6018],{"class":289},[272,6677,6678],{"class":274,"line":1192},[272,6679,302],{"emptyLinePlaceholder":169},[272,6681,6682,6684,6686,6688],{"class":274,"line":1200},[272,6683,3256],{"class":278},[272,6685,310],{"class":289},[272,6687,5714],{"class":282},[272,6689,1861],{"class":289},[272,6691,6692,6694,6696],{"class":274,"line":1208},[272,6693,6037],{"class":289},[272,6695,6040],{"class":278},[272,6697,373],{"class":289},[272,6699,6700,6702,6704,6706,6708,6710],{"class":274,"line":1216},[272,6701,3256],{"class":278},[272,6703,310],{"class":289},[272,6705,5714],{"class":366},[272,6707,370],{"class":289},[272,6709,5724],{"class":289},[272,6711,1861],{"class":289},[272,6713,6714],{"class":274,"line":1221},[272,6715,909],{"class":289},[272,6717,6718,6720],{"class":274,"line":1229},[272,6719,677],{"class":289},[272,6721,680],{"class":282},[15,6723,6724],{},"しかし、今度は、作りが大きくになるのと、開発途中少しでも飛んでしまう無駄なリクエストが多いことについて懸念として感じました。",[15,6726,6727,6728,6731],{},"そこで、他にも最良な案がないか再度調べたところ、Nuxt Server Components が使えるのではないかと考えました。これで metadata 取得とレンダリングが",[716,6729,6730],{},"サーバー内で完結します。"," 問題となっているページ遷移や記事の内容更新時にリクエストがクライアントで発生させないようにすれば問題解決です。",[264,6733,6736],{"className":4009,"code":6734,"filename":6735,"language":4012,"meta":154,"style":154},"\u003Cscript setup lang=\"ts\">\nimport { useAsyncData } from '#imports'\n\nimport type { SiteMetadata } from '~\u002Ftypes\u002Fmetedata'\n\nconst props = defineProps\u003C{\n  url: string\n}>()\n\nconst { data } = await useAsyncData\u003C{ metadata: SiteMetadata | null }>(`embed-${props.url}`, () => {\n   try {\n    const response = await $fetch.native(url,\n      {\n        method: 'get',\n        headers: { 'user-agent': userAgent },\n      })\n\n    const html = await response.text()\n    const metadata: SiteMetadata = { url, title: null }\n    const loaded = load(html)\n\n    const metaTags = loaded('meta')\n\n    for (const meta of metaTags) {\n      const property = meta.attribs.property\n\n      if (property === 'og:title') {\n        metadata.title = meta.attribs.content || null\n      }\n    }\n\n    return { metadata }\n  } catch {\n    return { metadata: null }\n  }\n})\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Ca\n    v-if=\"data\"\n    :href=\"url\"\n  >\n    \u003Cdiv>\n      \u003Cp>\n        {{ data.metadata?.title || url }}\n      \u003C\u002Fp>\n    \u003C\u002Fdiv>\n  \u003C\u002Fa>\n\u003C\u002Ftemplate>\n","components\u002FLinkCard.server.vue",[203,6737,6738,6758,6776,6780,6800,6804,6816,6824,6830,6834,6889,6895,6917,6921,6935,6959,6965,6969,6987,7013,7029,7033,7053,7057,7075,7093,7097,7117,7141,7145,7149,7153,7163,7171,7185,7189,7195,7203,7207,7215,7221,7233,7245,7249,7257,7265,7269,7277,7285,7293],{"__ignoreMap":154},[272,6739,6740,6742,6744,6746,6748,6750,6752,6754,6756],{"class":274,"line":275},[272,6741,3081],{"class":289},[272,6743,4021],{"class":366},[272,6745,4035],{"class":781},[272,6747,4024],{"class":781},[272,6749,2294],{"class":289},[272,6751,2334],{"class":289},[272,6753,268],{"class":293},[272,6755,2334],{"class":289},[272,6757,4038],{"class":289},[272,6759,6760,6762,6764,6766,6768,6770,6772,6774],{"class":274,"line":155},[272,6761,279],{"class":278},[272,6763,310],{"class":289},[272,6765,5616],{"class":282},[272,6767,327],{"class":289},[272,6769,330],{"class":278},[272,6771,290],{"class":289},[272,6773,4056],{"class":293},[272,6775,297],{"class":289},[272,6777,6778],{"class":274,"line":305},[272,6779,302],{"emptyLinePlaceholder":169},[272,6781,6782,6784,6786,6788,6790,6792,6794,6796,6798],{"class":274,"line":340},[272,6783,279],{"class":278},[272,6785,752],{"class":278},[272,6787,310],{"class":289},[272,6789,5641],{"class":282},[272,6791,327],{"class":289},[272,6793,330],{"class":278},[272,6795,290],{"class":289},[272,6797,5650],{"class":293},[272,6799,297],{"class":289},[272,6801,6802],{"class":274,"line":345},[272,6803,302],{"emptyLinePlaceholder":169},[272,6805,6806,6808,6810,6812,6814],{"class":274,"line":363},[272,6807,2288],{"class":781},[272,6809,5663],{"class":282},[272,6811,2294],{"class":289},[272,6813,5668],{"class":354},[272,6815,5671],{"class":289},[272,6817,6818,6820,6822],{"class":274,"line":376},[272,6819,5676],{"class":366},[272,6821,370],{"class":289},[272,6823,5681],{"class":801},[272,6825,6826,6828],{"class":274,"line":390},[272,6827,5686],{"class":289},[272,6829,4082],{"class":282},[272,6831,6832],{"class":274,"line":409},[272,6833,302],{"emptyLinePlaceholder":169},[272,6835,6836,6838,6840,6842,6844,6846,6848,6850,6852,6854,6856,6858,6860,6862,6864,6866,6868,6871,6873,6875,6877,6879,6881,6883,6885,6887],{"class":274,"line":419},[272,6837,2288],{"class":781},[272,6839,310],{"class":289},[272,6841,5701],{"class":282},[272,6843,677],{"class":289},[272,6845,3127],{"class":289},[272,6847,4279],{"class":278},[272,6849,5616],{"class":354},[272,6851,4069],{"class":289},[272,6853,5714],{"class":366},[272,6855,370],{"class":289},[272,6857,5641],{"class":801},[272,6859,5721],{"class":289},[272,6861,5724],{"class":801},[272,6863,4079],{"class":289},[272,6865,357],{"class":282},[272,6867,2129],{"class":289},[272,6869,6870],{"class":293},"embed-",[272,6872,2830],{"class":289},[272,6874,5738],{"class":282},[272,6876,430],{"class":289},[272,6878,5743],{"class":282},[272,6880,2842],{"class":289},[272,6882,316],{"class":289},[272,6884,5750],{"class":289},[272,6886,3089],{"class":781},[272,6888,373],{"class":289},[272,6890,6891,6893],{"class":274,"line":449},[272,6892,5759],{"class":278},[272,6894,373],{"class":289},[272,6896,6897,6899,6901,6903,6905,6907,6909,6911,6913,6915],{"class":274,"line":466},[272,6898,3121],{"class":781},[272,6900,5768],{"class":282},[272,6902,3127],{"class":289},[272,6904,4279],{"class":278},[272,6906,5775],{"class":282},[272,6908,430],{"class":289},[272,6910,5780],{"class":354},[272,6912,357],{"class":366},[272,6914,5743],{"class":282},[272,6916,406],{"class":289},[272,6918,6919],{"class":274,"line":472},[272,6920,5791],{"class":289},[272,6922,6923,6925,6927,6929,6931,6933],{"class":274,"line":491},[272,6924,5796],{"class":366},[272,6926,370],{"class":289},[272,6928,290],{"class":289},[272,6930,5803],{"class":293},[272,6932,403],{"class":289},[272,6934,406],{"class":289},[272,6936,6937,6940,6942,6944,6946,6949,6951,6953,6956],{"class":274,"line":511},[272,6938,6939],{"class":366},"        headers",[272,6941,370],{"class":289},[272,6943,310],{"class":289},[272,6945,290],{"class":289},[272,6947,6948],{"class":366},"user-agent",[272,6950,403],{"class":289},[272,6952,370],{"class":289},[272,6954,6955],{"class":282}," userAgent",[272,6957,6958],{"class":289}," },\n",[272,6960,6961,6963],{"class":274,"line":529},[272,6962,651],{"class":289},[272,6964,680],{"class":366},[272,6966,6967],{"class":274,"line":547},[272,6968,302],{"emptyLinePlaceholder":169},[272,6970,6971,6973,6975,6977,6979,6981,6983,6985],{"class":274,"line":565},[272,6972,3121],{"class":781},[272,6974,5824],{"class":282},[272,6976,3127],{"class":289},[272,6978,4279],{"class":278},[272,6980,5768],{"class":282},[272,6982,430],{"class":289},[272,6984,726],{"class":354},[272,6986,4082],{"class":366},[272,6988,6989,6991,6993,6995,6997,6999,7001,7003,7005,7007,7009,7011],{"class":274,"line":592},[272,6990,3121],{"class":781},[272,6992,5714],{"class":282},[272,6994,370],{"class":289},[272,6996,5641],{"class":801},[272,6998,3127],{"class":289},[272,7000,310],{"class":289},[272,7002,5853],{"class":282},[272,7004,316],{"class":289},[272,7006,5858],{"class":366},[272,7008,370],{"class":289},[272,7010,5724],{"class":289},[272,7012,1861],{"class":289},[272,7014,7015,7017,7019,7021,7023,7025,7027],{"class":274,"line":611},[272,7016,3121],{"class":781},[272,7018,5871],{"class":282},[272,7020,3127],{"class":289},[272,7022,5876],{"class":354},[272,7024,357],{"class":366},[272,7026,5881],{"class":282},[272,7028,680],{"class":366},[272,7030,7031],{"class":274,"line":629},[272,7032,302],{"emptyLinePlaceholder":169},[272,7034,7035,7037,7039,7041,7043,7045,7047,7049,7051],{"class":274,"line":648},[272,7036,3121],{"class":781},[272,7038,5894],{"class":282},[272,7040,3127],{"class":289},[272,7042,5871],{"class":354},[272,7044,357],{"class":366},[272,7046,403],{"class":289},[272,7048,5905],{"class":293},[272,7050,403],{"class":289},[272,7052,680],{"class":366},[272,7054,7055],{"class":274,"line":658},[272,7056,302],{"emptyLinePlaceholder":169},[272,7058,7059,7061,7063,7065,7067,7069,7071,7073],{"class":274,"line":668},[272,7060,5918],{"class":278},[272,7062,2493],{"class":366},[272,7064,2288],{"class":781},[272,7066,5925],{"class":282},[272,7068,5928],{"class":289},[272,7070,5894],{"class":282},[272,7072,2317],{"class":366},[272,7074,360],{"class":289},[272,7076,7077,7079,7081,7083,7085,7087,7089,7091],{"class":274,"line":674},[272,7078,5939],{"class":781},[272,7080,5942],{"class":282},[272,7082,3127],{"class":289},[272,7084,5925],{"class":282},[272,7086,430],{"class":289},[272,7088,5951],{"class":282},[272,7090,430],{"class":289},[272,7092,5956],{"class":282},[272,7094,7095],{"class":274,"line":1161},[272,7096,302],{"emptyLinePlaceholder":169},[272,7098,7099,7101,7103,7105,7107,7109,7111,7113,7115],{"class":274,"line":1169},[272,7100,3149],{"class":278},[272,7102,2493],{"class":366},[272,7104,5143],{"class":282},[272,7106,3173],{"class":289},[272,7108,290],{"class":289},[272,7110,5975],{"class":293},[272,7112,403],{"class":289},[272,7114,2317],{"class":366},[272,7116,360],{"class":289},[272,7118,7119,7121,7123,7125,7127,7129,7131,7133,7135,7137,7139],{"class":274,"line":1177},[272,7120,5986],{"class":282},[272,7122,430],{"class":289},[272,7124,5991],{"class":282},[272,7126,3127],{"class":289},[272,7128,5925],{"class":282},[272,7130,430],{"class":289},[272,7132,5951],{"class":282},[272,7134,430],{"class":289},[272,7136,696],{"class":282},[272,7138,6006],{"class":289},[272,7140,6009],{"class":289},[272,7142,7143],{"class":274,"line":1184},[272,7144,3213],{"class":289},[272,7146,7147],{"class":274,"line":1192},[272,7148,6018],{"class":289},[272,7150,7151],{"class":274,"line":1200},[272,7152,302],{"emptyLinePlaceholder":169},[272,7154,7155,7157,7159,7161],{"class":274,"line":1208},[272,7156,3256],{"class":278},[272,7158,310],{"class":289},[272,7160,5714],{"class":282},[272,7162,1861],{"class":289},[272,7164,7165,7167,7169],{"class":274,"line":1216},[272,7166,6037],{"class":289},[272,7168,6040],{"class":278},[272,7170,373],{"class":289},[272,7172,7173,7175,7177,7179,7181,7183],{"class":274,"line":1221},[272,7174,3256],{"class":278},[272,7176,310],{"class":289},[272,7178,5714],{"class":366},[272,7180,370],{"class":289},[272,7182,5724],{"class":289},[272,7184,1861],{"class":289},[272,7186,7187],{"class":274,"line":1229},[272,7188,909],{"class":289},[272,7190,7191,7193],{"class":274,"line":1237},[272,7192,677],{"class":289},[272,7194,680],{"class":282},[272,7196,7197,7199,7201],{"class":274,"line":1245},[272,7198,4113],{"class":289},[272,7200,4021],{"class":366},[272,7202,4038],{"class":289},[272,7204,7205],{"class":274,"line":1253},[272,7206,302],{"emptyLinePlaceholder":169},[272,7208,7209,7211,7213],{"class":274,"line":1261},[272,7210,3081],{"class":289},[272,7212,4128],{"class":366},[272,7214,4038],{"class":289},[272,7216,7217,7219],{"class":274,"line":1269},[272,7218,4135],{"class":289},[272,7220,6093],{"class":366},[272,7222,7223,7225,7227,7229,7231],{"class":274,"line":1277},[272,7224,6098],{"class":781},[272,7226,2294],{"class":289},[272,7228,2334],{"class":289},[272,7230,6105],{"class":293},[272,7232,6108],{"class":289},[272,7234,7235,7237,7239,7241,7243],{"class":274,"line":1285},[272,7236,6113],{"class":781},[272,7238,2294],{"class":289},[272,7240,2334],{"class":289},[272,7242,5743],{"class":293},[272,7244,6108],{"class":289},[272,7246,7247],{"class":274,"line":1293},[272,7248,6126],{"class":289},[272,7250,7251,7253,7255],{"class":274,"line":1301},[272,7252,4157],{"class":289},[272,7254,4138],{"class":366},[272,7256,4038],{"class":289},[272,7258,7259,7261,7263],{"class":274,"line":1309},[272,7260,6139],{"class":289},[272,7262,15],{"class":366},[272,7264,4038],{"class":289},[272,7266,7267],{"class":274,"line":1317},[272,7268,6148],{"class":282},[272,7270,7271,7273,7275],{"class":274,"line":1325},[272,7272,6153],{"class":289},[272,7274,15],{"class":366},[272,7276,4038],{"class":289},[272,7278,7279,7281,7283],{"class":274,"line":1333},[272,7280,6162],{"class":289},[272,7282,4138],{"class":366},[272,7284,4038],{"class":289},[272,7286,7287,7289,7291],{"class":274,"line":1341},[272,7288,4175],{"class":289},[272,7290,80],{"class":366},[272,7292,4038],{"class":289},[272,7294,7295,7297,7299],{"class":274,"line":1349},[272,7296,4113],{"class":289},[272,7298,4128],{"class":366},[272,7300,4038],{"class":289},[11,7302,7303],{"id":7303},"実際に動作させてみて",[15,7305,7306],{},"実際に使用してみて、クライアント側でレンダリングが発生しないので、ページ遷移や記事の内容更新で hot reload でリクエストが飛ばなくなりました。",[15,7308,7309,7310,7316],{},"実際に検証の結果を表示します。今回 metadata を取得したいサイトのスクレイピングは ",[80,7311,7314],{"href":7312,"rel":7313,"target":87},"https:\u002F\u002Fgithub.com\u002Fcheeriojs\u002Fcheerio",[84,85,86],[203,7315,6344],{}," というライブラリを使っています。これがブラウザへ転送されていないかを確認します。network で挙動を確認したところ、server components で cheerio が転送されていないことがわかりました。ブラウザへ JavaScript が転送されずに嬉しい限りです。",[7318,7319,7320,7333],"table",{},[7321,7322,7323],"thead",{},[7324,7325,7326,7330],"tr",{},[7327,7328,7329],"th",{},"Client+Server Component",[7327,7331,7332],{},"Server Component",[7334,7335,7336],"tbody",{},[7324,7337,7338,7345],{},[7339,7340,7341],"td",{},[21,7342],{"alt":7343,"src":7344},"Client と Server コンポーネントでのネットワーク","\u002Fcontent\u002Flink-card-by-nuxt-server-component\u002Fnetwork-by-server-client-component.png",[7339,7346,7347],{},[21,7348],{"alt":7349,"src":7350},"Server コンポーネントでのネットワーク","\u002Fcontent\u002Flink-card-by-nuxt-server-component\u002Fnetwork-by-server-component.png",[11,7352,7354],{"id":7353},"nuxt-server-components-で気をつけるべきこと","Nuxt Server Components で気をつけるべきこと",[15,7356,7357],{},"実装していて、詰まったことを共有します。",[245,7359,7361],{"id":7360},"global-コンポーネントであること","global コンポーネントであること",[15,7363,7364,7368,7369,7372],{},[80,7365,7367],{"href":7366},"\u002Fposts\u002Ftech\u002Flink-card-by-nuxt-server-component#nuxt-server-components-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6","上記","のオプションを ON にして、早速実装したリンクコンポーネントに ",[203,7370,7371],{},".server"," をつけ、動作確認をしました。しかし、試しにボタンクリックで内部にある count がインクリメントされるかを確認したところ、期待通りとはいかず、インクリメントされました。",[264,7374,7377],{"className":4009,"code":7375,"filename":7376,"language":4012,"meta":154,"style":154},"\u003Cscript lang=\"ts\" setup>\nimport { ref } from '#imports'\n\nconst count = ref(1)\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003Cbutton @click=\"count++\">{{ count }}\u003C\u002Fbutton>\n\u003C\u002Ftemplate>\n","components\u002FServerComponent.server.vue",[203,7378,7379,7399,7417,7421,7438,7446,7450,7458,7488],{"__ignoreMap":154},[272,7380,7381,7383,7385,7387,7389,7391,7393,7395,7397],{"class":274,"line":275},[272,7382,3081],{"class":289},[272,7384,4021],{"class":366},[272,7386,4024],{"class":781},[272,7388,2294],{"class":289},[272,7390,2334],{"class":289},[272,7392,268],{"class":293},[272,7394,2334],{"class":289},[272,7396,4035],{"class":781},[272,7398,4038],{"class":289},[272,7400,7401,7403,7405,7407,7409,7411,7413,7415],{"class":274,"line":155},[272,7402,279],{"class":278},[272,7404,310],{"class":289},[272,7406,4047],{"class":282},[272,7408,327],{"class":289},[272,7410,330],{"class":278},[272,7412,290],{"class":289},[272,7414,4056],{"class":293},[272,7416,297],{"class":289},[272,7418,7419],{"class":274,"line":305},[272,7420,302],{"emptyLinePlaceholder":169},[272,7422,7423,7425,7428,7430,7432,7434,7436],{"class":274,"line":340},[272,7424,2288],{"class":781},[272,7426,7427],{"class":282}," count ",[272,7429,2294],{"class":289},[272,7431,4047],{"class":354},[272,7433,357],{"class":282},[272,7435,4805],{"class":2297},[272,7437,680],{"class":282},[272,7439,7440,7442,7444],{"class":274,"line":345},[272,7441,4113],{"class":289},[272,7443,4021],{"class":366},[272,7445,4038],{"class":289},[272,7447,7448],{"class":274,"line":363},[272,7449,302],{"emptyLinePlaceholder":169},[272,7451,7452,7454,7456],{"class":274,"line":376},[272,7453,3081],{"class":289},[272,7455,4128],{"class":366},[272,7457,4038],{"class":289},[272,7459,7460,7462,7465,7468,7470,7472,7475,7477,7479,7482,7484,7486],{"class":274,"line":390},[272,7461,4135],{"class":289},[272,7463,7464],{"class":366},"button",[272,7466,7467],{"class":781}," @click",[272,7469,2294],{"class":289},[272,7471,2334],{"class":289},[272,7473,7474],{"class":293},"count++",[272,7476,2334],{"class":289},[272,7478,2311],{"class":289},[272,7480,7481],{"class":282},"{{ count }}",[272,7483,4113],{"class":289},[272,7485,7464],{"class":366},[272,7487,4038],{"class":289},[272,7489,7490,7492,7494],{"class":274,"line":409},[272,7491,4113],{"class":289},[272,7493,4128],{"class":366},[272,7495,4038],{"class":289},[15,7497,7498,7499,7501],{},"結論コンポーネントを global 登録するのが大事です。",[203,7500,6191],{}," の suffix をつけたパスのままで import しても Server Component として機能しません。自分のプロジェクトでは、auto-import や component の global 登録を無効にしているので、気づくのに時間がかかりました。",[264,7503,7506],{"className":4009,"code":7504,"filename":7505,"language":4012,"meta":154,"style":154},"\u003Cscript lang=\"ts\" setup>\nimport ServerComponent from '~\u002Fcomponents\u002FServerComponent.server.vue' \u002F\u002F \u003C- これがだめ\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CServerComponent \u002F>\n\u003C\u002Ftemplate>\n","pages\u002FSamplePage.vue",[203,7507,7508,7528,7547,7555,7559,7567,7577],{"__ignoreMap":154},[272,7509,7510,7512,7514,7516,7518,7520,7522,7524,7526],{"class":274,"line":275},[272,7511,3081],{"class":289},[272,7513,4021],{"class":366},[272,7515,4024],{"class":781},[272,7517,2294],{"class":289},[272,7519,2334],{"class":289},[272,7521,268],{"class":293},[272,7523,2334],{"class":289},[272,7525,4035],{"class":781},[272,7527,4038],{"class":289},[272,7529,7530,7532,7535,7537,7539,7542,7544],{"class":274,"line":155},[272,7531,279],{"class":278},[272,7533,7534],{"class":282}," ServerComponent ",[272,7536,286],{"class":278},[272,7538,290],{"class":289},[272,7540,7541],{"class":293},"~\u002Fcomponents\u002FServerComponent.server.vue",[272,7543,403],{"class":289},[272,7545,7546],{"class":2656}," \u002F\u002F \u003C- これがだめ\n",[272,7548,7549,7551,7553],{"class":274,"line":305},[272,7550,4113],{"class":289},[272,7552,4021],{"class":366},[272,7554,4038],{"class":289},[272,7556,7557],{"class":274,"line":340},[272,7558,302],{"emptyLinePlaceholder":169},[272,7560,7561,7563,7565],{"class":274,"line":345},[272,7562,3081],{"class":289},[272,7564,4128],{"class":366},[272,7566,4038],{"class":289},[272,7568,7569,7571,7574],{"class":274,"line":363},[272,7570,4135],{"class":289},[272,7572,7573],{"class":366},"ServerComponent",[272,7575,7576],{"class":289}," \u002F>\n",[272,7578,7579,7581,7583],{"class":274,"line":376},[272,7580,4113],{"class":289},[272,7582,4128],{"class":366},[272,7584,4038],{"class":289},[15,7586,7587,7588,7590,7591,7594],{},"幸い ",[203,7589,335],{}," ではマークダウンで利用するコンポーネントについては、最初からグローバル登録する ",[203,7592,7593],{},"~\u002Fcomponents\u002Fcontent"," ディレクトリに入れる仕様があります。それにより global 登録する前提条件はクリアしているので、今回実装したリンクカードコンポーネントをマークダウンで使用できます。",[11,7596,7597],{"id":7597},"テスト",[15,7599,7600],{},"ロジックがある程度定義されているので、テストをどう書いたかも共有します。",[15,7602,7603,7604,7607,7608,7611],{},"テストは vitest を使用しています。",[203,7605,7606],{},"@nuxt\u002Ftest-utils"," から提供されている ",[203,7609,7610],{},"mountSuspended"," を使い、リンクカードコンポーネントをレンダリングします。このとき注意すべきなのは、 global import すると、コンポーネントの中の HTML が空となります。(これは調査していきます。)",[264,7613,7616],{"className":266,"code":7614,"filename":7615,"language":268,"meta":154,"style":154},"import { mountSuspended } from '@nuxt\u002Ftest-utils\u002Fruntime'\n\nimport { LinkCard } from '#components'\n\ndescribe('LinkCard', () => {\n  describe('サイトへのリクエストが成功したとき', () => {\n    describe('すべてのプロパティがレスポンスに入ったとき', () => {\n      test('タイトルが表示されること', async () => {\n        const component = await mountSuspended(LinkCard, { props: { link: 'https:\u002F\u002Fexample.com' } })\n        console.log(`text: ${component.text()}`) \u002F\u002F ←　　出力結果は text:　のみ。なぜか空となってしまう。\n      })\n    })\n  })\n})\n","components\u002FLinkCard.nuxt.spec.ts",[203,7617,7618,7638,7642,7662,7666,7688,7710,7732,7757,7803,7837,7843,7849,7855],{"__ignoreMap":154},[272,7619,7620,7622,7624,7627,7629,7631,7633,7636],{"class":274,"line":275},[272,7621,279],{"class":278},[272,7623,310],{"class":289},[272,7625,7626],{"class":282}," mountSuspended",[272,7628,327],{"class":289},[272,7630,330],{"class":278},[272,7632,290],{"class":289},[272,7634,7635],{"class":293},"@nuxt\u002Ftest-utils\u002Fruntime",[272,7637,297],{"class":289},[272,7639,7640],{"class":274,"line":155},[272,7641,302],{"emptyLinePlaceholder":169},[272,7643,7644,7646,7648,7651,7653,7655,7657,7660],{"class":274,"line":305},[272,7645,279],{"class":278},[272,7647,310],{"class":289},[272,7649,7650],{"class":282}," LinkCard",[272,7652,327],{"class":289},[272,7654,330],{"class":278},[272,7656,290],{"class":289},[272,7658,7659],{"class":293},"#components",[272,7661,297],{"class":289},[272,7663,7664],{"class":274,"line":340},[272,7665,302],{"emptyLinePlaceholder":169},[272,7667,7668,7671,7673,7675,7678,7680,7682,7684,7686],{"class":274,"line":345},[272,7669,7670],{"class":354},"describe",[272,7672,357],{"class":282},[272,7674,403],{"class":289},[272,7676,7677],{"class":293},"LinkCard",[272,7679,403],{"class":289},[272,7681,316],{"class":289},[272,7683,5750],{"class":289},[272,7685,3089],{"class":781},[272,7687,373],{"class":289},[272,7689,7690,7693,7695,7697,7700,7702,7704,7706,7708],{"class":274,"line":363},[272,7691,7692],{"class":354},"  describe",[272,7694,357],{"class":366},[272,7696,403],{"class":289},[272,7698,7699],{"class":293},"サイトへのリクエストが成功したとき",[272,7701,403],{"class":289},[272,7703,316],{"class":289},[272,7705,5750],{"class":289},[272,7707,3089],{"class":781},[272,7709,373],{"class":289},[272,7711,7712,7715,7717,7719,7722,7724,7726,7728,7730],{"class":274,"line":376},[272,7713,7714],{"class":354},"    describe",[272,7716,357],{"class":366},[272,7718,403],{"class":289},[272,7720,7721],{"class":293},"すべてのプロパティがレスポンスに入ったとき",[272,7723,403],{"class":289},[272,7725,316],{"class":289},[272,7727,5750],{"class":289},[272,7729,3089],{"class":781},[272,7731,373],{"class":289},[272,7733,7734,7737,7739,7741,7744,7746,7748,7751,7753,7755],{"class":274,"line":390},[272,7735,7736],{"class":354},"      test",[272,7738,357],{"class":366},[272,7740,403],{"class":289},[272,7742,7743],{"class":293},"タイトルが表示されること",[272,7745,403],{"class":289},[272,7747,316],{"class":289},[272,7749,7750],{"class":781}," async",[272,7752,5750],{"class":289},[272,7754,3089],{"class":781},[272,7756,373],{"class":289},[272,7758,7759,7762,7765,7767,7769,7771,7773,7775,7777,7779,7781,7783,7785,7788,7790,7792,7795,7797,7799,7801],{"class":274,"line":409},[272,7760,7761],{"class":781},"        const",[272,7763,7764],{"class":282}," component",[272,7766,3127],{"class":289},[272,7768,4279],{"class":278},[272,7770,7626],{"class":354},[272,7772,357],{"class":366},[272,7774,7677],{"class":282},[272,7776,316],{"class":289},[272,7778,310],{"class":289},[272,7780,6275],{"class":366},[272,7782,370],{"class":289},[272,7784,310],{"class":289},[272,7786,7787],{"class":366}," link",[272,7789,370],{"class":289},[272,7791,290],{"class":289},[272,7793,7794],{"class":293},"https:\u002F\u002Fexample.com",[272,7796,403],{"class":289},[272,7798,327],{"class":289},[272,7800,327],{"class":289},[272,7802,680],{"class":366},[272,7804,7805,7808,7810,7812,7814,7816,7819,7821,7824,7826,7828,7830,7832,7834],{"class":274,"line":419},[272,7806,7807],{"class":282},"        console",[272,7809,430],{"class":289},[272,7811,2329],{"class":354},[272,7813,357],{"class":366},[272,7815,2129],{"class":289},[272,7817,7818],{"class":293},"text: ",[272,7820,2830],{"class":289},[272,7822,7823],{"class":282},"component",[272,7825,430],{"class":289},[272,7827,726],{"class":354},[272,7829,506],{"class":282},[272,7831,2842],{"class":289},[272,7833,2317],{"class":366},[272,7835,7836],{"class":2656},"\u002F\u002F ←　　出力結果は text:　のみ。なぜか空となってしまう。\n",[272,7838,7839,7841],{"class":274,"line":449},[272,7840,651],{"class":289},[272,7842,680],{"class":366},[272,7844,7845,7847],{"class":274,"line":466},[272,7846,661],{"class":289},[272,7848,680],{"class":366},[272,7850,7851,7853],{"class":274,"line":472},[272,7852,6037],{"class":289},[272,7854,680],{"class":366},[272,7856,7857,7859],{"class":274,"line":491},[272,7858,677],{"class":289},[272,7860,680],{"class":282},[15,7862,7863],{},"それにより、Server Component をテストファイルからインポートするときは、パスを指定しましょう。最終的なテストコードはこちらとなります。",[264,7865,7867],{"className":266,"code":7866,"filename":7615,"language":268,"meta":154,"style":154},"import { mountSuspended } from '@nuxt\u002Ftest-utils\u002Fruntime'\n\nimport LinkCard from '~\u002Fcomponents\u002Fcontent\u002FLinkCard.server.vue'\nimport type { SiteMetadata } from '~\u002Ftypes\u002Fmetedata'\nimport { fetchMetadata } from '~\u002Futils\u002Fpost\u002Fmetadata'\n\nvi.mock('~\u002Futils\u002Fpost\u002Fmetadata')\n\nconst metadata: SiteMetadata = {\n  title: 'site metadata title',\n  description: 'description',\n  url: 'https:\u002F\u002Fexample.com',\n  imageUrl: 'https:\u002F\u002Fexample.com\u002Fimg',\n}\n\ndescribe('LinkCard', () => {\n  describe('サイトへのリクエストが成功したとき', () => {\n    describe('すべてのプロパティがレスポンスに入ったとき', () => {\n      beforeEach(() => {\n        vi.mocked(fetchMetadata).mockResolvedValue({ metadata })\n      })\n\n      test('タイトルが表示されること', async () => {\n        const component = await mountSuspended(LinkCard, { props: { link: 'https:\u002F\u002Fexample.com' } })\n        expect(component.text()).toContain('title')\n      })\n    })\n  })\n})\n",[203,7868,7869,7887,7891,7907,7927,7947,7951,7971,7975,7989,8005,8021,8035,8051,8055,8059,8079,8099,8119,8132,8164,8170,8174,8196,8238,8268,8274,8280,8286],{"__ignoreMap":154},[272,7870,7871,7873,7875,7877,7879,7881,7883,7885],{"class":274,"line":275},[272,7872,279],{"class":278},[272,7874,310],{"class":289},[272,7876,7626],{"class":282},[272,7878,327],{"class":289},[272,7880,330],{"class":278},[272,7882,290],{"class":289},[272,7884,7635],{"class":293},[272,7886,297],{"class":289},[272,7888,7889],{"class":274,"line":155},[272,7890,302],{"emptyLinePlaceholder":169},[272,7892,7893,7895,7898,7900,7902,7905],{"class":274,"line":305},[272,7894,279],{"class":278},[272,7896,7897],{"class":282}," LinkCard ",[272,7899,286],{"class":278},[272,7901,290],{"class":289},[272,7903,7904],{"class":293},"~\u002Fcomponents\u002Fcontent\u002FLinkCard.server.vue",[272,7906,297],{"class":289},[272,7908,7909,7911,7913,7915,7917,7919,7921,7923,7925],{"class":274,"line":340},[272,7910,279],{"class":278},[272,7912,752],{"class":278},[272,7914,310],{"class":289},[272,7916,5641],{"class":282},[272,7918,327],{"class":289},[272,7920,330],{"class":278},[272,7922,290],{"class":289},[272,7924,5650],{"class":293},[272,7926,297],{"class":289},[272,7928,7929,7931,7933,7936,7938,7940,7942,7945],{"class":274,"line":345},[272,7930,279],{"class":278},[272,7932,310],{"class":289},[272,7934,7935],{"class":282}," fetchMetadata",[272,7937,327],{"class":289},[272,7939,330],{"class":278},[272,7941,290],{"class":289},[272,7943,7944],{"class":293},"~\u002Futils\u002Fpost\u002Fmetadata",[272,7946,297],{"class":289},[272,7948,7949],{"class":274,"line":363},[272,7950,302],{"emptyLinePlaceholder":169},[272,7952,7953,7956,7958,7961,7963,7965,7967,7969],{"class":274,"line":376},[272,7954,7955],{"class":282},"vi",[272,7957,430],{"class":289},[272,7959,7960],{"class":354},"mock",[272,7962,357],{"class":282},[272,7964,403],{"class":289},[272,7966,7944],{"class":293},[272,7968,403],{"class":289},[272,7970,680],{"class":282},[272,7972,7973],{"class":274,"line":390},[272,7974,302],{"emptyLinePlaceholder":169},[272,7976,7977,7979,7981,7983,7985,7987],{"class":274,"line":409},[272,7978,2288],{"class":781},[272,7980,5714],{"class":282},[272,7982,370],{"class":289},[272,7984,5641],{"class":801},[272,7986,3127],{"class":289},[272,7988,373],{"class":289},[272,7990,7991,7994,7996,7998,8001,8003],{"class":274,"line":419},[272,7992,7993],{"class":366},"  title",[272,7995,370],{"class":289},[272,7997,290],{"class":289},[272,7999,8000],{"class":293},"site metadata title",[272,8002,403],{"class":289},[272,8004,406],{"class":289},[272,8006,8007,8010,8012,8014,8017,8019],{"class":274,"line":449},[272,8008,8009],{"class":366},"  description",[272,8011,370],{"class":289},[272,8013,290],{"class":289},[272,8015,8016],{"class":293},"description",[272,8018,403],{"class":289},[272,8020,406],{"class":289},[272,8022,8023,8025,8027,8029,8031,8033],{"class":274,"line":466},[272,8024,5676],{"class":366},[272,8026,370],{"class":289},[272,8028,290],{"class":289},[272,8030,7794],{"class":293},[272,8032,403],{"class":289},[272,8034,406],{"class":289},[272,8036,8037,8040,8042,8044,8047,8049],{"class":274,"line":472},[272,8038,8039],{"class":366},"  imageUrl",[272,8041,370],{"class":289},[272,8043,290],{"class":289},[272,8045,8046],{"class":293},"https:\u002F\u002Fexample.com\u002Fimg",[272,8048,403],{"class":289},[272,8050,406],{"class":289},[272,8052,8053],{"class":274,"line":491},[272,8054,965],{"class":289},[272,8056,8057],{"class":274,"line":511},[272,8058,302],{"emptyLinePlaceholder":169},[272,8060,8061,8063,8065,8067,8069,8071,8073,8075,8077],{"class":274,"line":529},[272,8062,7670],{"class":354},[272,8064,357],{"class":282},[272,8066,403],{"class":289},[272,8068,7677],{"class":293},[272,8070,403],{"class":289},[272,8072,316],{"class":289},[272,8074,5750],{"class":289},[272,8076,3089],{"class":781},[272,8078,373],{"class":289},[272,8080,8081,8083,8085,8087,8089,8091,8093,8095,8097],{"class":274,"line":547},[272,8082,7692],{"class":354},[272,8084,357],{"class":366},[272,8086,403],{"class":289},[272,8088,7699],{"class":293},[272,8090,403],{"class":289},[272,8092,316],{"class":289},[272,8094,5750],{"class":289},[272,8096,3089],{"class":781},[272,8098,373],{"class":289},[272,8100,8101,8103,8105,8107,8109,8111,8113,8115,8117],{"class":274,"line":565},[272,8102,7714],{"class":354},[272,8104,357],{"class":366},[272,8106,403],{"class":289},[272,8108,7721],{"class":293},[272,8110,403],{"class":289},[272,8112,316],{"class":289},[272,8114,5750],{"class":289},[272,8116,3089],{"class":781},[272,8118,373],{"class":289},[272,8120,8121,8124,8126,8128,8130],{"class":274,"line":592},[272,8122,8123],{"class":354},"      beforeEach",[272,8125,357],{"class":366},[272,8127,506],{"class":289},[272,8129,3089],{"class":781},[272,8131,373],{"class":289},[272,8133,8134,8137,8139,8142,8144,8147,8149,8151,8154,8156,8158,8160,8162],{"class":274,"line":611},[272,8135,8136],{"class":282},"        vi",[272,8138,430],{"class":289},[272,8140,8141],{"class":354},"mocked",[272,8143,357],{"class":366},[272,8145,8146],{"class":282},"fetchMetadata",[272,8148,188],{"class":366},[272,8150,430],{"class":289},[272,8152,8153],{"class":354},"mockResolvedValue",[272,8155,357],{"class":366},[272,8157,4351],{"class":289},[272,8159,5714],{"class":282},[272,8161,327],{"class":289},[272,8163,680],{"class":366},[272,8165,8166,8168],{"class":274,"line":629},[272,8167,651],{"class":289},[272,8169,680],{"class":366},[272,8171,8172],{"class":274,"line":648},[272,8173,302],{"emptyLinePlaceholder":169},[272,8175,8176,8178,8180,8182,8184,8186,8188,8190,8192,8194],{"class":274,"line":658},[272,8177,7736],{"class":354},[272,8179,357],{"class":366},[272,8181,403],{"class":289},[272,8183,7743],{"class":293},[272,8185,403],{"class":289},[272,8187,316],{"class":289},[272,8189,7750],{"class":781},[272,8191,5750],{"class":289},[272,8193,3089],{"class":781},[272,8195,373],{"class":289},[272,8197,8198,8200,8202,8204,8206,8208,8210,8212,8214,8216,8218,8220,8222,8224,8226,8228,8230,8232,8234,8236],{"class":274,"line":668},[272,8199,7761],{"class":781},[272,8201,7764],{"class":282},[272,8203,3127],{"class":289},[272,8205,4279],{"class":278},[272,8207,7626],{"class":354},[272,8209,357],{"class":366},[272,8211,7677],{"class":282},[272,8213,316],{"class":289},[272,8215,310],{"class":289},[272,8217,6275],{"class":366},[272,8219,370],{"class":289},[272,8221,310],{"class":289},[272,8223,7787],{"class":366},[272,8225,370],{"class":289},[272,8227,290],{"class":289},[272,8229,7794],{"class":293},[272,8231,403],{"class":289},[272,8233,327],{"class":289},[272,8235,327],{"class":289},[272,8237,680],{"class":366},[272,8239,8240,8243,8245,8247,8249,8251,8253,8255,8258,8260,8262,8264,8266],{"class":274,"line":674},[272,8241,8242],{"class":354},"        expect",[272,8244,357],{"class":366},[272,8246,7823],{"class":282},[272,8248,430],{"class":289},[272,8250,726],{"class":354},[272,8252,587],{"class":366},[272,8254,430],{"class":289},[272,8256,8257],{"class":354},"toContain",[272,8259,357],{"class":366},[272,8261,403],{"class":289},[272,8263,5991],{"class":293},[272,8265,403],{"class":289},[272,8267,680],{"class":366},[272,8269,8270,8272],{"class":274,"line":1161},[272,8271,651],{"class":289},[272,8273,680],{"class":366},[272,8275,8276,8278],{"class":274,"line":1169},[272,8277,661],{"class":289},[272,8279,680],{"class":366},[272,8281,8282,8284],{"class":274,"line":1177},[272,8283,6037],{"class":289},[272,8285,680],{"class":366},[272,8287,8288,8290],{"class":274,"line":1184},[272,8289,677],{"class":289},[272,8291,680],{"class":282},[11,8293,8294],{"id":8294},"これからの改善点",[15,8296,8297,8298,8300],{},"ここからは少し余談になりますが、",[203,8299,335],{}," を使用していることから妥協したこともお書きします。",[15,8302,8303],{},"本当は Qiita や Zenn.dev などの技術投稿ブログと一緒で、マークダウンの中に 1 つリンクだけを設置する予定でした。",[264,8305,8307],{"className":989,"code":8306,"language":991,"meta":154,"style":154},"--- a\u002Fsrc\u002Fcontent\u002Ftech\u002Flink-card-by-nuxt-server-component.md\n+++ b\u002Fsrc\u002Fcontent\u002Ftech\u002Flink-card-by-nuxt-server-component.md\n@@ -16,10 +16,7 @@ categories: ['Nuxt.js']\n\n-::LinkCard{link='https:\u002F\u002Fnuxt.com\u002F'}\n-::\n+https:\u002F\u002Fnuxt.com\u002F \u003C!-- ← 理想系はこっち -->\n",[203,8308,8309,8316,8323,8335,8339,8346,8353],{"__ignoreMap":154},[272,8310,8311,8313],{"class":274,"line":275},[272,8312,1008],{"class":289},[272,8314,8315],{"class":282}," a\u002Fsrc\u002Fcontent\u002Ftech\u002Flink-card-by-nuxt-server-component.md\n",[272,8317,8318,8320],{"class":274,"line":155},[272,8319,1016],{"class":289},[272,8321,8322],{"class":282}," b\u002Fsrc\u002Fcontent\u002Ftech\u002Flink-card-by-nuxt-server-component.md\n",[272,8324,8325,8327,8330,8332],{"class":274,"line":305},[272,8326,1024],{"class":289},[272,8328,8329],{"class":282}," -16,10 +16,7 ",[272,8331,1024],{"class":289},[272,8333,8334],{"class":282}," categories: ['Nuxt.js']\n",[272,8336,8337],{"class":274,"line":340},[272,8338,302],{"emptyLinePlaceholder":169},[272,8340,8341,8343],{"class":274,"line":345},[272,8342,1051],{"class":289},[272,8344,8345],{"class":366},"::LinkCard{link='https:\u002F\u002Fnuxt.com\u002F'}\n",[272,8347,8348,8350],{"class":274,"line":363},[272,8349,1051],{"class":289},[272,8351,8352],{"class":366},"::\n",[272,8354,8355,8357],{"class":274,"line":376},[272,8356,1080],{"class":289},[272,8358,8359],{"class":293},"https:\u002F\u002Fnuxt.com\u002F \u003C!-- ← 理想系はこっち -->\n",[15,8361,8362,8364],{},[203,8363,335],{}," の仕様で、パースされた DOM をそれぞれのタグコンポーネントに置換し、HTML を生成しますが、このときのタグコンポーネントを自分でカスタマイズできます。しかし、今回カスタマイズするタグは a タグのコンポーネントになります。中身を上記のコードに書き換えたとき、Hydration mismatch が発生してしまいました。それにより、妥協して今回のようなコンポーネントを使うと言う方向になりました。",[15,8366,8367],{},"原因としては、どうやら a タグの中でインライン要素ではなく、ブロック要素を展開することから DOM 構造が変わってしまうのがよくないようです。すでに issue は上がっているようですが、解決に向けて議論が進んでいるわけではないので、妥協してコンポーネントを呼び出す形を取りました。",[57,8369],{"link":8370},"https:\u002F\u002Fgithub.com\u002Fnuxt\u002Fcontent\u002Fissues\u002F1537#issuecomment-1250810387",[11,8372,2194],{"id":2194},[15,8374,8375],{},"リンクカードがあるかないかでブログの見た目がだいぶ変わってくるので、実装できてよかったです。Nuxt Server Components を実運用できただけではなく、Nuxt で API サーバーを立てるなど、一歩深く Nuxt と向き合えたのではないかと感じます。今回リンクカードコンポーネントだけ Server Components を利用しているのですが、そもそものマークダウンレンダラー自体も Server Components 化していく予定です。日々「Ship Less JavaScript」を目指していきます。",[2211,8377,8378],{},"html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .s0_hs, html code.shiki .s0_hs{--shiki-default:#546E7A;--shiki-default-font-style:italic}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}",{"title":154,"searchDepth":155,"depth":155,"links":8380},[8381,8382,8383,8384,8385,8386,8387,8390,8391,8392],{"id":5426,"depth":155,"text":5426},{"id":5436,"depth":155,"text":5436},{"id":5445,"depth":155,"text":5445},{"id":5464,"depth":155,"text":5465},{"id":5570,"depth":155,"text":5570},{"id":7303,"depth":155,"text":7303},{"id":7353,"depth":155,"text":7354,"children":8388},[8389],{"id":7360,"depth":305,"text":7361},{"id":7597,"depth":155,"text":7597},{"id":8294,"depth":155,"text":8294},{"id":2194,"depth":155,"text":2194},[2230],"Nuxt Server Components で Nuxt Content 用のリンクカードコンポーネントを実装するまでをまとめました。",{},"\u002Ftech\u002Flink-card-by-nuxt-server-component","2024-10-29",{"title":5412,"description":8394},"tech\u002Flink-card-by-nuxt-server-component","2024-12-02","jDyvwqDd0T_6269PWLi7HcRXVjX2nGzCLVoCviZe7Gw",{"id":8403,"title":8404,"body":8405,"categories":9207,"description":9210,"draft":166,"extension":167,"meta":9211,"navigation":169,"path":9212,"priority":171,"publishedAt":9213,"secret":166,"seo":9214,"stem":9215,"updatedAt":9216,"__hash__":9217},"posts\u002Ftech\u002Fbuilt-portofolio-by-nuxt-content-ssg.md","offich.me を支える技術",{"type":8,"value":8406,"toc":9185},[8407,8410,8413,8416,8419,8426,8430,8433,8436,8440,8443,8446,8449,8453,8456,8459,8463,8466,8469,8471,8474,8490,8493,8496,8499,8502,8507,8510,8513,8533,8537,8540,8543,8546,8549,8553,8556,8559,8562,8565,8579,8588,8591,8594,8601,8604,8607,8610,8613,8616,8620,8627,8631,8638,8642,8645,8653,8658,8679,8991,8995,9003,9006,9009,9013,9019,9043,9157,9160,9163,9166,9177,9179,9182],[11,8408,8409],{"id":8409},"これ何",[15,8411,8412],{},"Nuxt 3 x Cloudflare Pages x nuxt\u002Fcontent でブログを作りました。",[15,8414,8415],{},"作るまでのいきさつや大変だったことをまとめていきます。",[11,8417,8418],{"id":8418},"モチベーション",[15,8420,8421,8422,8425],{},"まずはブログ作りまでのモチベーションを書きます。",[716,8423,8424],{},"自分を知ってもらう","を大きなテーマにしていて、そこから細分化したものを書きます。",[245,8427,8429],{"id":8428},"_1-アウトプットの場が欲しかった","1. アウトプットの場が欲しかった",[15,8431,8432],{},"普段 web フロント業務を担当して、デザインやアクセシリビリティ、SEO、パフォーマンス、ビルドツールなど、もう一度最初から勉強し直したい気持ちが芽生えてきました。デザイナーさんや PM さんと一緒に仕様を考えたり、フロントエンドチームと一緒に技術的課題の解決を図るにも、インプットの量が絶対的に足りないとここ数年感じました。手元で動かしたりある程度理解しても、せっかくならそれを本番運用するまでのレベルに昇華させないと実務で役に立たないと思っています。",[15,8434,8435],{},"今まで個人開発に力を入れてこなかったので、次へのレベルアップのためにも、何か 0 から作る経験を積みたかったのもあります。\nブログを作るだけなら、多く存在している情報共有サービスやブログ生成サービスを利用すればいいのですが、自分で 0 から作りたいと思りました。",[245,8437,8439],{"id":8438},"_2-アウトプットを-1-つの場所に集めかった","2. アウトプットを 1 つの場所に集めかった",[15,8441,8442],{},"次にアウトプットの場所を 1 つに統合し、自分を知ってもらう相手のハードルをなるべく下げる狙いがありました。",[15,8444,8445],{},"仕事探しでプロフィールになるものを提出するときに、今度はこのブログの URL を渡す予定です。ブログがないと、今までアウトプットで使用したサービスを統一できず、使用したサービスの URL をすべて渡さないといけません。さらにそれぞれのサービスに用途別でアカウントを別々にわけるともう管理が大変です。新しいサービスが普及すると、そちらへのマイグレーションに手間がかかります。",[15,8447,8448],{},"職務経歴書の管理も 1 つにまとめておきかったのもあります。転職活動するたびに職務経歴書と履歴書を更新して〜、そこにいろんなサービスの URL を貼って〜となかなか骨が折れる作業でした。職務経歴書にいろいろなブログのリンクを貼る作業があるが、どうせならこのサイト内の回遊にしたい気持ちがありました。これからの追加開発で、マークダウンに書いた職務経歴書と履歴書を Excel ファイルに出力する npm パッケージを作る予定です。",[245,8450,8452],{"id":8451},"_3-技術以外のトピックでも書きたい","3. 技術以外のトピックでも書きたい",[15,8454,8455],{},"プログはもちろん技術的なトピックを集める場となりますが、プライベートで起こったことをどこかにまとめたい気持ちもありました。2024 年は特にライフステージの変化が多かったので、そこで起こったことについての時系列、大変だったこと、振り返りを行う場所を作りたかったです。あとは過去なぜかそのような意思決定をしたかを記録に残したいのもあります。当時は懸命に下調べして検討したのに数年経った後決断をするまでの過程を正確に思い出せないのももったいないと感じています。",[15,8457,8458],{},"幸いなことにプライベートも充実しており、ギターや YouTube などの趣味、育児、結婚、引っ越しなど、今振り返ると多くのイベントがあったので、それらをまとめる予定です。他にも生活していく上で書きたいことが多くありました。決して、自分が生活する上で他人へ共有するに値するものはないと感じていましたが、意外にもこのような体験をしたと話をすると、参考になったとフィードバックをくれたり心身に話を聞いてくださる人がいます。自分自身も調べもので他人のプログを見て参考になることが多いので、今度は自分の体験が還元されることを願ってまとめていきます。",[245,8460,8462],{"id":8461},"_4-コメントやいいね機能がないところでブログを書きたかった","4. コメントやいいね機能がないところでブログを書きたかった",[15,8464,8465],{},"アウトプットすることがエンジニアとして大事なことだとは頭では分かっていたが、どうも今まで渋っており腰が重いと感じていました。\n理由を深掘りしていくと、アウトプットにおける他人からの評価を気にしている部分が大きかったと気づきました。他人のいいねやシェア数に一喜一憂し変にモチベージョンに影響が出るのと、何かヒットするのかを調査するのに時間がかかり、結局アウトプットできないことが多かったです。",[15,8467,8468],{},"何のためにアウトプットしているのかと考えたら、まずは他人より自分のためと思えば、心理的敷居が下がると感じたので、評価がない場所でアウトプットをしたいと思いました。qiita、zendev、はてなブログ、note はいいねだけではなくシェア数まで表示されるので、今回作成するブログサイトも記事を評価する機能は実装しないです。ただ参考程度に PV やサイト内滞在時間はどれぐらいなのかを知りたいので、改めて計測ツールの勉強も兼ねて、 Google Analytics を入れる予定です。",[245,8470,130],{"id":130},[15,8472,8473],{},"長くなりましたが、以下がモチベーションの 3 行サマリーになります。",[35,8475,8476],{},[38,8477,8478,8479],{},"自分のことを知ってもらえる場所を作りたかった。\n",[35,8480,8481,8484,8487],{},[38,8482,8483],{},"分散するのではなく、1 つにまとまっているのがわかりやすい。",[38,8485,8486],{},"仕事以外の経験・体験をシェアしていきたい。",[38,8488,8489],{},"アウトプットの内容を自分軸で決めていきたい。",[11,8491,8492],{"id":8492},"技術構成",[15,8494,8495],{},"モチベーションをまとめた上で早速作ろうと、次は要件をまとめました。",[245,8497,8498],{"id":8498},"要件",[15,8500,8501],{},"上に記載があるように、作りたかったものとしては「自分を他人に知ってもらう」がテーマでした。",[8503,8504,8506],"h4",{"id":8505},"_1-マークダウンでブログを書きたい","1. マークダウンでブログを書きたい",[15,8508,8509],{},"今までの現場で、ADR やミーティングの議事録、作業メモ、システムの繋ぎ込みなどはすべてマークダウン記法で書いていました。なので、今回のブログもマークダウン記法が可能であることを要件に入れました。",[15,8511,8512],{},"ブログを書く上で下の要素をパースし、表示できるものが欲しかったです。",[35,8514,8515,8518,8521,8524,8527,8530],{},[38,8516,8517],{},"コードブロック",[38,8519,8520],{},"箇条書き",[38,8522,8523],{},"強調",[38,8525,8526],{},"引用",[38,8528,8529],{},"写真",[38,8531,8532],{},"リンクの埋め込み",[8503,8534,8536],{"id":8535},"_2-静的サイトで作りたい","2. 静的サイトで作りたい",[15,8538,8539],{},"結論、SSG (static-site generation)　の静的サイトで進めていこうと決めました。",[15,8541,8542],{},"ブログ内容はリポジトリの中で管理し自分が書き換えるまで内容は変わらなく、ページの内容が動的に変更されるものではないので、ビルド時に内容が決まる SSG モードのアプリケーションで十分と考えました。パフォーマンスや SEO 対策にも貢献できるとも考えています。",[15,8544,8545],{},"他のレンダリングモードの SSR (server-side rendering) は Node.js のサーバーを用意する、 SPA (Single Page Application) はクローラーへの心配があるので、今回はお見送りしました。",[15,8547,8548],{},"あとは SSG アプリケーションの開発経験を積みたかったのもあります。Nuxt.js の SSR と SPA アプリケーションの開発は今までの現場で経験があるのですが、SSG のアプリケーションだけなかったので、改めて知見を貯めたかったです。",[8503,8550,8552],{"id":8551},"_3-自分が慣れしたんだ技術","3. 自分が慣れしたんだ技術",[15,8554,8555],{},"Nuxt.js や Vue.js の今後を watch し続けたいものがあることから、せっかくの個人開発でも技術的にチャレンジをしたい気持ちを抑えつつ、Nuxt.js で作ることに決めました。自分のメイン技術スタックとなる Nuxt.js のこれからのリリース変更を手を動かして学んでいきたいので、総じてアウトプットできる場所を作りたかったです。手段と目的が逆になっているというツッコミもありつつ、触れたことがない技術については、今度の個人開発で試していきたいです。このブログは長年運用していく予定でもあるので、改善のリリースまでのスピードを考えると、慣れしたんだ技術のほうがより叶うと考えました。",[15,8557,8558],{},"他のレンダリング方法で、island architecture や Next.js が提供する Incremental Site Regeneration を検討しました。しかし、今ある知識の範疇を飛び抜けると、キャッチアップだけでリリースを迎えるのが難しいと感じました。個人的にチャレンジしたい気持ちがあるので、次の個人開発でぜひ再度検討したいです。",[245,8560,8561],{"id":8561},"技術選定",[15,8563,8564],{},"要件が決まれば、次は使用する技術についでです。主に使用している技術は下になります。",[35,8566,8567,8570,8573,8576],{},[38,8568,8569],{},"フレームワーク: Nuxt.js",[38,8571,8572],{},"マークダウン関連: @nuxt\u002Fcontent",[38,8574,8575],{},"ホスティング: Cloudflare Pages",[38,8577,8578],{},"UI ライブラリ: Nuxt UI",[15,8580,8581,8582,8584,8585,8587],{},"マークダウンについては、元々知っていた ",[203,8583,335],{}," を採用しました。マークダウンのパースだけではなく、生成したクエリをコンポーネントに渡すと、クエリに合った条件の記事を表示するなど便利なものがあります。パースだけではなくて、こういった取得部分についても、API が提供されているので採用を決めました。このブログを作る上で ",[203,8586,335],{}," の Tips は多くあったので後日まとめていきます。実際運用していて、他人の記事や YouTube、 X(旧 Twitter) のウィジェットを表示できないなど、まだ改修をいれないといけない部分があります。そのような諸々足りない機能についても後日実装していきます。",[57,8589],{"link":8590},"https:\u002F\u002Fcontent.nuxt.com\u002F",[15,8592,8593],{},"ホスティングでは、Cloudflare Pages を使用することにしました。naked domain を使用できるし、GitHub Actions で CI でデプロイが可能など、運用する上でやりたいことができるので採用しました。デザインシステムのドキュメントや remix でのアプリケーションを本番運用している実績もあるので、改めて自分のブログで使用するにあたって不安がなかったのも大きな理由です。",[15,8595,8596,8597,8600],{},"UI については ",[203,8598,8599],{},"@nuxt\u002Fui"," を採用しました。これは 2023 年の VueFes Japan で紹介があり、ぜひ使ってみたいライブラリでした。自分なりのデザインシステムを作るなんてことも面白いかなと一瞬頭をよぎりましたが、一からコンポーネントを作るのも工数が多くかかるので、使うことにしました。",[57,8602],{"link":8603},"https:\u002F\u002Fui.nuxt.com\u002F",[11,8605,8606],{"id":8606},"大変だったこと",[15,8608,8609],{},"開発していて、以下が大変だったことです。上記にあるように、SSG アプリケーションの開発の経験がそこまでなく、少し頭を悩ませました。",[245,8611,8612],{"id":8612},"ページネーション",[15,8614,8615],{},"特にページネーションの部分で悩みました。SPA や SSR アプリケーションを作るときと同じ考えで、ページ数をクエリパラメーターから取得し、動的にページ内部のページ数とコンテンツ一覧を変更できませんでした。SSG ですとページ内部のページ数はビルド時にのみ変更されるので、リクエスト時に変更されるクエリパラメーターを使用してだとうまく動作しません。仮にクエリパラメーターを変更したページのパスで prerender を行っても、パスパラメーターが同じであるため、エラーになってしまいます。そこで、ページのディレクトリ構成を変更し、ページ数をパスパラメーターにしました。",[8503,8617,8619],{"id":8618},"before","Before",[264,8621,8625],{"className":8622,"code":8623,"filename":8624,"language":726,"meta":154},[723],"src\u002Fpages\u002Fposts\u002F\n├── [...slug].vue\n├── categories\n│   └── [category].vue \u002F\u002F posts\u002Fcategories\u002Ftech?page=1\n└── index.vue \u002F\u002F posts?page=1\n","before.txt",[203,8626,8623],{"__ignoreMap":154},[8503,8628,8630],{"id":8629},"after","After",[264,8632,8636],{"className":8633,"code":8634,"filename":8635,"language":726,"meta":154},[723],"src\u002Fpages\u002Fposts\u002F\n├── [...slug].vue\n├── [page].vue \u002F\u002F posts\u002F1\n├── categories\n│   └── [category]\n│       └── [page].vue \u002F\u002F posts\u002Fcategories\u002Ftech\u002F1\n└── index.vue\n","after.txt",[203,8637,8634],{"__ignoreMap":154},[245,8639,8641],{"id":8640},"prerender-のルート選定","prerender のルート選定",[15,8643,8644],{},"繰り返しになりますが、 SSG アプリケーションであるため、事前に prerender するパスを nitro に伝えなければなりません。\n以下が prerender させるときのパスの要件でした。",[35,8646,8647,8650],{},[38,8648,8649],{},"ページネーションを効かせる。記事の総数とそれぞれのカテゴリの記事の総数を求める必要がある。",[38,8651,8652],{},"draft 記事は含めない。",[15,8654,8655,8657],{},[203,8656,335],{}," の仕様で記事に付与されているカテゴリとそもそも記事が draft かどうかを frontmatter に定義できます。これを prerender するパスにするかいなかの同期をとる必要がありました。",[15,8659,8660,8661,8664,8665,8668,8669,8671,8672,3413,8675,8678],{},"取得するはどうしたらいいかを考えたところ、 ",[203,8662,8663],{},"remark-mdc"," というパッケージから ",[203,8666,8667],{},"parseFrontMatter"," という処理を使えたので、それをそのまま真似ました。後日詳しく書く予定ですが、rdc parser がすごく便利と感じました。",[203,8670,335],{}," が ",[203,8673,8674],{},"@nuxt\u002Fmdc",[203,8676,8677],{},"rdc parser"," の順番に依存しています。そこで frontmatter 単体をパースしている処理を見つけ、この方法で frontmatter で定義されているデータを prerender のときに取得できました。prerender するパスを決めるスクリプトにデータを定義する必要がなく、これで二重管理を避けられます。",[264,8680,8683],{"className":266,"code":8681,"filename":8682,"language":268,"meta":154,"style":154},"import { parseFrontMatter } from 'remark-mdc'\nimport { readFileSync } from 'fs'\n\nconst getFrontMatter = (markdownPath: string): { categories: string[], draft: boolean } => {\n  const { data: frontmatter } = parseFrontMatter(readFileSync(markdownPath, 'utf8'))\n  const { categories, draft } = frontmatter\n  return { categories: categories || [], draft }\n}\n\nfor (const markdownFile of markdownFiles) {\n  const frontmatter = getFrontMatter(`${markdownFile.path}\u002F${markdownFile.name}`)\n\n  if (frontmatter.draft) continue \u002F\u002F ドラフト記事なら、 prerender のルートに入れない。\n\n  for (const category of frontmatter.categories) {\n    \u002F\u002F ...category\n  }\n}\n","getContentRoute.ts",[203,8684,8685,8704,8724,8728,8774,8815,8834,8857,8861,8865,8885,8923,8927,8949,8953,8978,8983,8987],{"__ignoreMap":154},[272,8686,8687,8689,8691,8694,8696,8698,8700,8702],{"class":274,"line":275},[272,8688,279],{"class":278},[272,8690,310],{"class":289},[272,8692,8693],{"class":282}," parseFrontMatter",[272,8695,327],{"class":289},[272,8697,330],{"class":278},[272,8699,290],{"class":289},[272,8701,8663],{"class":293},[272,8703,297],{"class":289},[272,8705,8706,8708,8710,8713,8715,8717,8719,8722],{"class":274,"line":155},[272,8707,279],{"class":278},[272,8709,310],{"class":289},[272,8711,8712],{"class":282}," readFileSync",[272,8714,327],{"class":289},[272,8716,330],{"class":278},[272,8718,290],{"class":289},[272,8720,8721],{"class":293},"fs",[272,8723,297],{"class":289},[272,8725,8726],{"class":274,"line":305},[272,8727,302],{"emptyLinePlaceholder":169},[272,8729,8730,8732,8735,8737,8739,8742,8744,8746,8748,8750,8753,8755,8757,8759,8761,8764,8766,8768,8770,8772],{"class":274,"line":340},[272,8731,2288],{"class":781},[272,8733,8734],{"class":282}," getFrontMatter ",[272,8736,2294],{"class":289},[272,8738,2493],{"class":289},[272,8740,8741],{"class":2496},"markdownPath",[272,8743,370],{"class":289},[272,8745,819],{"class":801},[272,8747,3138],{"class":289},[272,8749,310],{"class":289},[272,8751,8752],{"class":366}," categories",[272,8754,370],{"class":289},[272,8756,819],{"class":801},[272,8758,867],{"class":282},[272,8760,316],{"class":289},[272,8762,8763],{"class":366}," draft",[272,8765,370],{"class":289},[272,8767,879],{"class":801},[272,8769,327],{"class":289},[272,8771,3089],{"class":781},[272,8773,373],{"class":289},[272,8775,8776,8778,8780,8783,8785,8788,8790,8792,8794,8796,8799,8801,8803,8805,8807,8810,8812],{"class":274,"line":345},[272,8777,6422],{"class":781},[272,8779,310],{"class":289},[272,8781,8782],{"class":366}," data",[272,8784,370],{"class":289},[272,8786,8787],{"class":282}," frontmatter",[272,8789,327],{"class":289},[272,8791,3127],{"class":289},[272,8793,8693],{"class":354},[272,8795,357],{"class":366},[272,8797,8798],{"class":354},"readFileSync",[272,8800,357],{"class":366},[272,8802,8741],{"class":282},[272,8804,316],{"class":289},[272,8806,290],{"class":289},[272,8808,8809],{"class":293},"utf8",[272,8811,403],{"class":289},[272,8813,8814],{"class":366},"))\n",[272,8816,8817,8819,8821,8823,8825,8827,8829,8831],{"class":274,"line":363},[272,8818,6422],{"class":781},[272,8820,310],{"class":289},[272,8822,8752],{"class":282},[272,8824,316],{"class":289},[272,8826,8763],{"class":282},[272,8828,327],{"class":289},[272,8830,3127],{"class":289},[272,8832,8833],{"class":282}," frontmatter\n",[272,8835,8836,8838,8840,8842,8844,8846,8848,8851,8853,8855],{"class":274,"line":376},[272,8837,3096],{"class":278},[272,8839,310],{"class":289},[272,8841,8752],{"class":366},[272,8843,370],{"class":289},[272,8845,8752],{"class":282},[272,8847,6006],{"class":289},[272,8849,8850],{"class":366}," []",[272,8852,316],{"class":289},[272,8854,8763],{"class":282},[272,8856,1861],{"class":289},[272,8858,8859],{"class":274,"line":390},[272,8860,965],{"class":289},[272,8862,8863],{"class":274,"line":409},[272,8864,302],{"emptyLinePlaceholder":169},[272,8866,8867,8870,8872,8874,8877,8880,8883],{"class":274,"line":419},[272,8868,8869],{"class":278},"for",[272,8871,2493],{"class":282},[272,8873,2288],{"class":781},[272,8875,8876],{"class":282}," markdownFile ",[272,8878,8879],{"class":289},"of",[272,8881,8882],{"class":282}," markdownFiles) ",[272,8884,360],{"class":289},[272,8886,8887,8889,8891,8893,8896,8898,8900,8903,8905,8907,8909,8911,8913,8915,8917,8919,8921],{"class":274,"line":449},[272,8888,6422],{"class":781},[272,8890,8787],{"class":282},[272,8892,3127],{"class":289},[272,8894,8895],{"class":354}," getFrontMatter",[272,8897,357],{"class":366},[272,8899,2814],{"class":289},[272,8901,8902],{"class":282},"markdownFile",[272,8904,430],{"class":289},[272,8906,294],{"class":282},[272,8908,677],{"class":289},[272,8910,5264],{"class":293},[272,8912,2830],{"class":289},[272,8914,8902],{"class":282},[272,8916,430],{"class":289},[272,8918,3598],{"class":282},[272,8920,2842],{"class":289},[272,8922,680],{"class":366},[272,8924,8925],{"class":274,"line":466},[272,8926,302],{"emptyLinePlaceholder":169},[272,8928,8929,8931,8933,8936,8938,8941,8943,8946],{"class":274,"line":472},[272,8930,3562],{"class":278},[272,8932,2493],{"class":366},[272,8934,8935],{"class":282},"frontmatter",[272,8937,430],{"class":289},[272,8939,8940],{"class":282},"draft",[272,8942,2317],{"class":366},[272,8944,8945],{"class":278},"continue",[272,8947,8948],{"class":2656}," \u002F\u002F ドラフト記事なら、 prerender のルートに入れない。\n",[272,8950,8951],{"class":274,"line":491},[272,8952,302],{"emptyLinePlaceholder":169},[272,8954,8955,8958,8960,8962,8965,8967,8969,8971,8974,8976],{"class":274,"line":511},[272,8956,8957],{"class":278},"  for",[272,8959,2493],{"class":366},[272,8961,2288],{"class":781},[272,8963,8964],{"class":282}," category",[272,8966,5928],{"class":289},[272,8968,8787],{"class":282},[272,8970,430],{"class":289},[272,8972,8973],{"class":282},"categories",[272,8975,2317],{"class":366},[272,8977,360],{"class":289},[272,8979,8980],{"class":274,"line":529},[272,8981,8982],{"class":2656},"    \u002F\u002F ...category\n",[272,8984,8985],{"class":274,"line":547},[272,8986,909],{"class":289},[272,8988,8989],{"class":274,"line":565},[272,8990,965],{"class":289},[245,8992,8994],{"id":8993},"nuxt-ui-のカスタマイズ","Nuxt UI のカスタマイズ",[15,8996,8997,8998,3413,9000,9002],{},"vuefes で紹介されたので、工数削減のためと OSS のライブラリが改めてどのようにコンポーネントを作成しているのかのインプットのために、使ってみてました。",[203,8999,335],{},[203,9001,8599],{}," の親和性も高く、使用したいコーディングブロックのコンポーネントも作成できたので、採用して良かったかと思いきや、他のカスタマイズが難しかったです。",[15,9004,9005],{},"それぞれのコンポーネントで、内部のスタイルが TailwindCSS に大きく依存しているので、設定ファイルを変更すると、@nuxt\u002Fui のコンポーネント群のスタイルも大きく変わります。特に自分好みのスペーシングを定義したところ、コンポーネント内部のパーツの大きさを変更するのに、調整に時間がかかりました。",[15,9007,9008],{},"今振り返ると Vue.js 用の headless\u002Fui ライブラリを使えば、カスタマイズが容易だったかと感じます。",[245,9010,9012],{"id":9011},"rehype-plugin-のカスタマイズ","rehype plugin のカスタマイズ",[15,9014,9015,9016,9018],{},"マークダウンを書き、実際に表示される内容の QA をしたところ、外部サイトが別タブで開かない問題がありました。せっかくなら自身のブログサイトに留まってほしいので、",[203,9017,335],{}," の中身をコードリーディングしたところ、rehype plugin というのを見つけました。",[15,9020,9021,9026,9027,9030,9031,9034,9035,8671,9037,9039,9040,9042],{},[80,9022,9025],{"href":9023,"rel":9024,"target":87},"https:\u002F\u002Fgithub.com\u002Frehypejs\u002Frehype",[84,85,86],"rehype"," についての記事も後日書きますが、HTML に変更を加えるのが容易になります。様々なプラグインがあり、今回 a タグに変更を追加するのは ",[203,9028,9029],{},"rehype-external-plugin"," というものでした。そのデフォルトの挙動を見ると、",[203,9032,9033],{},"rel: nofollow"," をつけることがわかります。幸い ",[203,9036,335],{},[203,9038,9029],{}," へのオプションを渡してくれるので、a タグに付与したい属性を ",[203,9041,982],{}," に定します。これで外部サイトを別タブで開くことができました。",[264,9044,9046],{"className":266,"code":9045,"language":268,"meta":154,"style":154},"export default defineNuxtConfig({\n  markdown: {\n    rehypePlugins: [\n      [\n        'rehype-external-links', {\n          target: '_blank',\n          rel: 'nofollow noopener noreferrer',\n        },\n      ],\n    ],\n  },\n})\n",[203,9047,9048,9060,9069,9079,9084,9098,9113,9129,9133,9140,9147,9151],{"__ignoreMap":154},[272,9049,9050,9052,9054,9056,9058],{"class":274,"line":275},[272,9051,348],{"class":278},[272,9053,351],{"class":278},[272,9055,5533],{"class":354},[272,9057,357],{"class":282},[272,9059,360],{"class":289},[272,9061,9062,9065,9067],{"class":274,"line":155},[272,9063,9064],{"class":366},"  markdown",[272,9066,370],{"class":289},[272,9068,373],{"class":289},[272,9070,9071,9074,9076],{"class":274,"line":305},[272,9072,9073],{"class":366},"    rehypePlugins",[272,9075,370],{"class":289},[272,9077,9078],{"class":282}," [\n",[272,9080,9081],{"class":274,"line":340},[272,9082,9083],{"class":282},"      [\n",[272,9085,9086,9089,9092,9094,9096],{"class":274,"line":345},[272,9087,9088],{"class":289},"        '",[272,9090,9091],{"class":293},"rehype-external-links",[272,9093,403],{"class":289},[272,9095,316],{"class":289},[272,9097,373],{"class":289},[272,9099,9100,9103,9105,9107,9109,9111],{"class":274,"line":363},[272,9101,9102],{"class":366},"          target",[272,9104,370],{"class":289},[272,9106,290],{"class":289},[272,9108,87],{"class":293},[272,9110,403],{"class":289},[272,9112,406],{"class":289},[272,9114,9115,9118,9120,9122,9125,9127],{"class":274,"line":376},[272,9116,9117],{"class":366},"          rel",[272,9119,370],{"class":289},[272,9121,290],{"class":289},[272,9123,9124],{"class":293},"nofollow noopener noreferrer",[272,9126,403],{"class":289},[272,9128,406],{"class":289},[272,9130,9131],{"class":274,"line":390},[272,9132,1147],{"class":289},[272,9134,9135,9138],{"class":274,"line":409},[272,9136,9137],{"class":282},"      ]",[272,9139,406],{"class":289},[272,9141,9142,9145],{"class":274,"line":419},[272,9143,9144],{"class":282},"    ]",[272,9146,406],{"class":289},[272,9148,9149],{"class":274,"line":449},[272,9150,671],{"class":289},[272,9152,9153,9155],{"class":274,"line":466},[272,9154,677],{"class":289},[272,9156,680],{"class":282},[11,9158,9159],{"id":9159},"これからやること",[15,9161,9162],{},"無事にブログをリリースをしましたが、やりたいことが多くあります。",[15,9164,9165],{},"特に Google 関連のツールとの繋ぎ込みに力を入れたいです。",[35,9167,9168,9171,9174],{},[38,9169,9170],{},"Google Search Console に sitemap を登録する。",[38,9172,9173],{},"Google Analytics を導入して記事の PV を確認する。",[38,9175,9176],{},"Google Adsense を入れて広告をいれるまでの過程を調査したりパフォーマンスにどれだけ影響がでるのかを知りたい。",[11,9178,2194],{"id":2194},[15,9180,9181],{},"Nuxt 3 と @nuxt\u002Fcontent を使用して、自分のオリジナルのブログを作ってみました。自分のアウトプットを通して、自分を知ってもらう場所ができたことを非常に嬉しく感じます。もちろん開発するまでに詰まったところや学んだところが多くあったので、後日詳細の記事を書いていく予定です。ここまでご精読ありがとうございました。",[2211,9183,9184],{},"html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s0_hs, html code.shiki .s0_hs{--shiki-default:#546E7A;--shiki-default-font-style:italic}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":154,"searchDepth":155,"depth":155,"links":9186},[9187,9188,9195,9199,9205,9206],{"id":8409,"depth":155,"text":8409},{"id":8418,"depth":155,"text":8418,"children":9189},[9190,9191,9192,9193,9194],{"id":8428,"depth":305,"text":8429},{"id":8438,"depth":305,"text":8439},{"id":8451,"depth":305,"text":8452},{"id":8461,"depth":305,"text":8462},{"id":130,"depth":305,"text":130},{"id":8492,"depth":155,"text":8492,"children":9196},[9197,9198],{"id":8498,"depth":305,"text":8498},{"id":8561,"depth":305,"text":8561},{"id":8606,"depth":155,"text":8606,"children":9200},[9201,9202,9203,9204],{"id":8612,"depth":305,"text":8612},{"id":8640,"depth":305,"text":8641},{"id":8993,"depth":305,"text":8994},{"id":9011,"depth":305,"text":9012},{"id":9159,"depth":155,"text":9159},{"id":2194,"depth":155,"text":2194},[2229,2230,9208,9209],"Cloudflare","Tailwindcss","Nuxt 3 x Cloudflare Pages x @nuxt\u002Fcontent で自ブログを作りました",{},"\u002Ftech\u002Fbuilt-portofolio-by-nuxt-content-ssg","2024-09-26",{"title":8404,"description":9210},"tech\u002Fbuilt-portofolio-by-nuxt-content-ssg","2024-10-20","s10H3ySc2Tl6RyMIHfSRG5-DwQMNe1t3o3vFYMx6tMA",{"id":9219,"title":9220,"body":9221,"categories":16381,"description":16382,"draft":166,"extension":167,"meta":16383,"navigation":169,"path":16384,"priority":171,"publishedAt":16385,"secret":166,"seo":16386,"stem":16387,"updatedAt":16385,"__hash__":16388},"posts\u002Ftech\u002Fnuxtjs-animation.md","2020 年に Nuxt.js で実装してきたアニメーションをまとめてみた",{"type":8,"value":9222,"toc":16366},[9223,9231,9234,9236,9239,9242,9272,9275,9281,9284,9287,9318,9321,9325,9337,9346,9348,9353,9356,9362,9368,9398,9404,9429,9432,10511,10518,10587,10589,10595,10598,10604,11385,11391,11456,11458,11462,11468,11474,11481,11507,11552,12587,12590,13672,13676,13689,13692,13695,13700,13703,13709,13715,14874,14877,14881,14887,14900,16340,16342,16348,16351,16360,16363],[15,9224,9225,9230],{},[80,9226,9229],{"href":9227,"rel":9228,"target":87},"https:\u002F\u002Ftech.hey.jp\u002Fentry\u002F2020\u002F12\u002F01\u002F172331",[84,85,86],"hey \u002F STORES advent calendar 2020"," 7 日目の記事です。",[15,9232,9233],{},"2020 年の振り返りとして、この記事では Nuxt.js で実装してきたアニメーションをまとめていきます。",[11,9235,5426],{"id":5426},[15,9237,9238],{},"Nuxt.js での開発で、Vue.js のコミュニティが活発だからか、自然と多くの UI ライブラリやアニメーションライブラリを見ます。しかし、自分はそれらを使わず、ほとんどのケースにおいて自分で実装していく派です。",[15,9240,9241],{},"理由としては、",[35,9243,9244,9247,9250,9253,9261],{},[38,9245,9246],{},"要件を満たすものを探し、実際にプロジェクトに入れてみて、要件を満たせるかの検証に時間がかかる。",[38,9248,9249],{},"ライブラリが提供している UI とデザイナーから要求される UI の調整が難しい。",[38,9251,9252],{},"将来要求される機能追加や変更を叶えられるかがわからない。",[38,9254,9255,9256],{},"tree-shaking が未対応であるライブラリの場合、使わない機能の JavaScript まで import し、結果プロジェクトのバンドルサイズが増えてしまう。\n",[35,9257,9258],{},[38,9259,9260],{},"バージョン管理も長期的な運用コストにもなる。",[38,9262,9263,9264,9267,9268,9271],{},"Vue.js の中にアニメーション実装のための ",[203,9265,9266],{},"\u003Ctransition>"," タグや ",[203,9269,9270],{},"\u003Ctransition-group>"," タグがある。",[15,9273,9274],{},"というのがあります。",[15,9276,9277,9278,9280],{},"2020 年では、UI・UX 向上のため Web サイトのデザインリニューアルを担当していました。多くのアニメーション実装が必要でしたが、上の理由から、適宜要件に合うように自分で実装してきました。多くの学びがあったため、振り返りを兼ねて、それらの一部をまとめます。Vue.js の ",[203,9279,9266],{}," を使ったケースと使わなかったケースがあるので、その観点でグループ化しました。",[11,9282,9283],{"id":9283},"開発環境",[15,9285,9286],{},"開発環境は以下のものになります。",[35,9288,9289,9315],{},[38,9290,9291,9292],{},"Nuxt.js 2.14.7\n",[35,9293,9294,9305],{},[38,9295,9296,9297,9300,9301,9304],{},"今回フロントの実装の記事になり、SSR モードで実装する必要はないので、",[203,9298,9299],{},"ssr","　オプションは ",[203,9302,9303],{},"false"," にして、SPA アプリケーションのモードにする。",[38,9306,9307,9310,9311,9314],{},[203,9308,9309],{},"components"," のオプションは ",[203,9312,9313],{},"true"," にして、 コンポーネントの自動 import が効くようにしました。",[38,9316,9317],{},"TypeScript 3.9.7",[11,9319,9320],{"id":9320},"紹介するアニメーションたち",[245,9322,9324],{"id":9323},"vuejsのtransitionを使って実装したもの","Vue.jsのtransitionを使って実装したもの",[9326,9327,9328,9331,9334],"ol",{},[38,9329,9330],{},"スライドメニュー",[38,9332,9333],{},"ポップアップ",[38,9335,9336],{},"アコーディオン",[15,9338,9339,9340,9342,9343,9345],{},"Vue.js でアニメーションを実装すると言えば、上であげた ",[203,9341,9266],{}," タグを使うことがまず案として上がってきます。自分も多く使ってきたので、実装してきたアニメーションの中で ",[203,9344,9266],{}," タグを使ったケースをあげます。",[245,9347,9330],{"id":9330},[21,9349],{"width":9350,"alt":9351,"src":9352},750,"slide-menu.gif","https:\u002F\u002Fqiita-image-store.s3.ap-northeast-1.amazonaws.com\u002F0\u002F152032\u002Ff272dc0c-32a3-63bf-3533-448af89b4590.gif",[15,9354,9355],{},"まずはスライドメニューです。使い方としては、ヘッダーメニューをスライドで開閉を切り替えるようにし、横からスライドで表示するというのがあります。",[15,9357,9358,9359,9361],{},"実装内容もシンプルで、Vuejs の ",[203,9360,9266],{}," タグのドキュメントの一番最初にあるサンプルを参考にして実装したものです。サンプルは開くときに右から左にスライドし、閉じるときには左から右にスライドします。",[15,9363,9364,9365,9367],{},"開くときは、",[203,9366,9266],{}," タグの中身の dom がレンダリングされるのにフックして、",[35,9369,9370,9384],{},[38,9371,9372,9375,9376,9379,9380,9383],{},[716,9373,9374],{},"background",": 初期値で ",[203,9377,9378],{},"opacity: 0"," で透明から、",[203,9381,9382],{},"transition: opacity 0.15s"," で少しずつ背景を黒に変化する。",[38,9385,9386,9389,9390,9393,9394,9397],{},[716,9387,9388],{},"menu",": 初期値が ",[203,9391,9392],{},"translateX(10%)"," で右に少しずらした位置から、 ",[203,9395,9396],{},"transition: all 0.15s ease"," で少しずつ、移動が終わったであろう位置までスライドしていく。",[15,9399,9400,9401,9403],{},"逆に閉じるときは、",[203,9402,9266],{}," タグの中身の DOM がなくなることにフックして、",[35,9405,9406,9417],{},[38,9407,9408,9375,9410,9412,9413,9416],{},[716,9409,9374],{},[203,9411,9378],{}," を設定し、そのまま透明にする。そのまま DOM が破棄される最中から破棄されたあとは同じ状態を維持するので、",[203,9414,9415],{},"leave-active","クラスは何も書かなくても問題ありません。",[38,9418,9419,9421,9422,9425,9426,9428],{},[716,9420,9388],{},": 初期値を特に何も設定せず、dom が破棄されている最中で",[203,9423,9424],{},"transition: all 0.15s cubic-bezier(1, 0.5, 0.8, 1)"," でスライドしていく。消える頃には右に少しずれた位置へ ",[203,9427,9378],{}," で透明にされているため、ならめかにスライドメニューが消えるという挙動になっている。",[15,9430,9431],{},"スライドメニューの中のメニューと背景をクリックしたときに、スライドメニューを閉じる処理を忘れないようにしましょう。",[264,9433,9436],{"className":4009,"code":9434,"filename":9435,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"ume-slide-menu\">\n    \u003Ctransition name=\"background\">\n      \u003Cdiv v-if=\"isOpened\" class=\"background\" @click=\"close\">\n        \u003Cdiv class=\"close-button\">&times;\u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Ftransition>\n\n    \u003Ctransition name=\"menu\">\n      \u003Cdiv v-if=\"isOpened\" class=\"menu\">\n        \u003Cdiv class=\"menu-item-wrapper\">\n          \u003Cdiv class=\"menu-item\" @click=\"close\">\n            \u003Cspan>page1\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n\n          \u003Cdiv class=\"menu-item\" @click=\"close\">\n            \u003Cspan>page2\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n\n          \u003Cdiv class=\"menu-item\" @click=\"close\">\n            \u003Cspan>page3\u003C\u002Fspan>\n          \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Ftransition>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue from 'vue'\n\nexport default Vue.extend({\n  model: {\n    prop: 'isOpened',\n    event: 'close',\n  },\n\n  props: {\n    isOpened: {\n      type: Boolean,\n      required: true,\n    },\n  },\n\n  methods: {\n    close() {\n      this.$emit('close')\n    },\n  },\n})\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\" scoped>\n.ume-slide-menu {\n  .background-enter,\n  .background-leave-to {\n    opacity: 0;\n  }\n\n  .background-enter-active {\n    transition: opacity 0.15s;\n  }\n\n  .menu-enter,\n  .menu-leave-to {\n    transform: translateX(10%);\n    opacity: 0;\n  }\n\n  .menu-enter-active {\n    transition: all 0.15s ease;\n  }\n\n  .menu-leave-active {\n    transition: all 0.15s cubic-bezier(1, 0.5, 0.8, 1);\n  }\n\n  .background {\n    width: 100%;\n    height: 100%;\n    position: fixed;\n    z-index: 98;\n    top: 0;\n    right: 0;\n    overflow-x: hidden;\n    background-color: rgba(0, 0, 0, 0.6);\n\n    .close-button {\n      position: absolute;\n      top: 0;\n      left: 25px;\n      font-size: 36px;\n      color: #fff;\n    }\n  }\n\n  .menu {\n    height: 100%;\n    width: 64%;\n    max-width: 320px;\n    position: fixed;\n    z-index: 99;\n    top: 0;\n    right: 0;\n    background-color: #f3f3f3;\n    overflow-x: hidden;\n\n    .menu-item-wrapper {\n      background-color: #fff;\n      padding-top: 40px;\n      padding-bottom: 52px;\n    }\n\n    .menu-item {\n      display: block;\n      cursor: pointer;\n      margin: 0 20px;\n      padding: 17px 0;\n      font-size: 16px;\n      font-weight: bold;\n      border-bottom: thin solid #c7c7cc;\n      color: #4a4a4a;\n      text-decoration: none;\n      line-height: 1;\n\n      span {\n        vertical-align: middle;\n      }\n    }\n  }\n}\n\u003C\u002Fstyle>\n","components\u002Fmolecules\u002Fume-slide-menu.vue",[203,9437,9438,9446,9465,9485,9526,9555,9563,9571,9575,9593,9621,9640,9670,9688,9697,9701,9729,9746,9754,9758,9786,9803,9811,9820,9828,9836,9844,9852,9856,9874,9889,9893,9911,9920,9935,9950,9954,9958,9967,9976,9987,9998,10002,10006,10010,10019,10028,10046,10050,10054,10060,10068,10072,10092,10097,10102,10107,10112,10116,10120,10125,10130,10134,10138,10143,10148,10153,10157,10161,10165,10170,10175,10179,10183,10188,10193,10197,10201,10206,10211,10216,10221,10226,10231,10237,10243,10249,10254,10260,10266,10272,10278,10284,10290,10295,10300,10305,10311,10316,10322,10328,10333,10339,10344,10349,10355,10360,10365,10371,10377,10383,10389,10394,10399,10405,10411,10417,10423,10429,10435,10441,10447,10453,10459,10465,10470,10476,10482,10487,10492,10497,10502],{"__ignoreMap":154},[272,9439,9440,9442,9444],{"class":274,"line":275},[272,9441,3081],{"class":289},[272,9443,4128],{"class":366},[272,9445,4038],{"class":289},[272,9447,9448,9450,9452,9454,9456,9458,9461,9463],{"class":274,"line":155},[272,9449,4135],{"class":289},[272,9451,4138],{"class":366},[272,9453,4141],{"class":781},[272,9455,2294],{"class":289},[272,9457,2334],{"class":289},[272,9459,9460],{"class":293},"ume-slide-menu",[272,9462,2334],{"class":289},[272,9464,4038],{"class":289},[272,9466,9467,9469,9472,9475,9477,9479,9481,9483],{"class":274,"line":305},[272,9468,4157],{"class":289},[272,9470,9471],{"class":366},"transition",[272,9473,9474],{"class":781}," name",[272,9476,2294],{"class":289},[272,9478,2334],{"class":289},[272,9480,9374],{"class":293},[272,9482,2334],{"class":289},[272,9484,4038],{"class":289},[272,9486,9487,9489,9491,9494,9496,9498,9501,9503,9505,9507,9509,9511,9513,9515,9517,9519,9522,9524],{"class":274,"line":340},[272,9488,6139],{"class":289},[272,9490,4138],{"class":366},[272,9492,9493],{"class":781}," v-if",[272,9495,2294],{"class":289},[272,9497,2334],{"class":289},[272,9499,9500],{"class":293},"isOpened",[272,9502,2334],{"class":289},[272,9504,4141],{"class":781},[272,9506,2294],{"class":289},[272,9508,2334],{"class":289},[272,9510,9374],{"class":293},[272,9512,2334],{"class":289},[272,9514,7467],{"class":781},[272,9516,2294],{"class":289},[272,9518,2334],{"class":289},[272,9520,9521],{"class":293},"close",[272,9523,2334],{"class":289},[272,9525,4038],{"class":289},[272,9527,9528,9531,9533,9535,9537,9539,9542,9544,9546,9549,9551,9553],{"class":274,"line":345},[272,9529,9530],{"class":289},"        \u003C",[272,9532,4138],{"class":366},[272,9534,4141],{"class":781},[272,9536,2294],{"class":289},[272,9538,2334],{"class":289},[272,9540,9541],{"class":293},"close-button",[272,9543,2334],{"class":289},[272,9545,2311],{"class":289},[272,9547,9548],{"class":282},"&times;",[272,9550,4113],{"class":289},[272,9552,4138],{"class":366},[272,9554,4038],{"class":289},[272,9556,9557,9559,9561],{"class":274,"line":363},[272,9558,6153],{"class":289},[272,9560,4138],{"class":366},[272,9562,4038],{"class":289},[272,9564,9565,9567,9569],{"class":274,"line":376},[272,9566,6162],{"class":289},[272,9568,9471],{"class":366},[272,9570,4038],{"class":289},[272,9572,9573],{"class":274,"line":390},[272,9574,302],{"emptyLinePlaceholder":169},[272,9576,9577,9579,9581,9583,9585,9587,9589,9591],{"class":274,"line":409},[272,9578,4157],{"class":289},[272,9580,9471],{"class":366},[272,9582,9474],{"class":781},[272,9584,2294],{"class":289},[272,9586,2334],{"class":289},[272,9588,9388],{"class":293},[272,9590,2334],{"class":289},[272,9592,4038],{"class":289},[272,9594,9595,9597,9599,9601,9603,9605,9607,9609,9611,9613,9615,9617,9619],{"class":274,"line":419},[272,9596,6139],{"class":289},[272,9598,4138],{"class":366},[272,9600,9493],{"class":781},[272,9602,2294],{"class":289},[272,9604,2334],{"class":289},[272,9606,9500],{"class":293},[272,9608,2334],{"class":289},[272,9610,4141],{"class":781},[272,9612,2294],{"class":289},[272,9614,2334],{"class":289},[272,9616,9388],{"class":293},[272,9618,2334],{"class":289},[272,9620,4038],{"class":289},[272,9622,9623,9625,9627,9629,9631,9633,9636,9638],{"class":274,"line":449},[272,9624,9530],{"class":289},[272,9626,4138],{"class":366},[272,9628,4141],{"class":781},[272,9630,2294],{"class":289},[272,9632,2334],{"class":289},[272,9634,9635],{"class":293},"menu-item-wrapper",[272,9637,2334],{"class":289},[272,9639,4038],{"class":289},[272,9641,9642,9645,9647,9649,9651,9653,9656,9658,9660,9662,9664,9666,9668],{"class":274,"line":466},[272,9643,9644],{"class":289},"          \u003C",[272,9646,4138],{"class":366},[272,9648,4141],{"class":781},[272,9650,2294],{"class":289},[272,9652,2334],{"class":289},[272,9654,9655],{"class":293},"menu-item",[272,9657,2334],{"class":289},[272,9659,7467],{"class":781},[272,9661,2294],{"class":289},[272,9663,2334],{"class":289},[272,9665,9521],{"class":293},[272,9667,2334],{"class":289},[272,9669,4038],{"class":289},[272,9671,9672,9675,9677,9679,9682,9684,9686],{"class":274,"line":472},[272,9673,9674],{"class":289},"            \u003C",[272,9676,272],{"class":366},[272,9678,2311],{"class":289},[272,9680,9681],{"class":282},"page1",[272,9683,4113],{"class":289},[272,9685,272],{"class":366},[272,9687,4038],{"class":289},[272,9689,9690,9693,9695],{"class":274,"line":491},[272,9691,9692],{"class":289},"          \u003C\u002F",[272,9694,4138],{"class":366},[272,9696,4038],{"class":289},[272,9698,9699],{"class":274,"line":511},[272,9700,302],{"emptyLinePlaceholder":169},[272,9702,9703,9705,9707,9709,9711,9713,9715,9717,9719,9721,9723,9725,9727],{"class":274,"line":529},[272,9704,9644],{"class":289},[272,9706,4138],{"class":366},[272,9708,4141],{"class":781},[272,9710,2294],{"class":289},[272,9712,2334],{"class":289},[272,9714,9655],{"class":293},[272,9716,2334],{"class":289},[272,9718,7467],{"class":781},[272,9720,2294],{"class":289},[272,9722,2334],{"class":289},[272,9724,9521],{"class":293},[272,9726,2334],{"class":289},[272,9728,4038],{"class":289},[272,9730,9731,9733,9735,9737,9740,9742,9744],{"class":274,"line":547},[272,9732,9674],{"class":289},[272,9734,272],{"class":366},[272,9736,2311],{"class":289},[272,9738,9739],{"class":282},"page2",[272,9741,4113],{"class":289},[272,9743,272],{"class":366},[272,9745,4038],{"class":289},[272,9747,9748,9750,9752],{"class":274,"line":565},[272,9749,9692],{"class":289},[272,9751,4138],{"class":366},[272,9753,4038],{"class":289},[272,9755,9756],{"class":274,"line":592},[272,9757,302],{"emptyLinePlaceholder":169},[272,9759,9760,9762,9764,9766,9768,9770,9772,9774,9776,9778,9780,9782,9784],{"class":274,"line":611},[272,9761,9644],{"class":289},[272,9763,4138],{"class":366},[272,9765,4141],{"class":781},[272,9767,2294],{"class":289},[272,9769,2334],{"class":289},[272,9771,9655],{"class":293},[272,9773,2334],{"class":289},[272,9775,7467],{"class":781},[272,9777,2294],{"class":289},[272,9779,2334],{"class":289},[272,9781,9521],{"class":293},[272,9783,2334],{"class":289},[272,9785,4038],{"class":289},[272,9787,9788,9790,9792,9794,9797,9799,9801],{"class":274,"line":629},[272,9789,9674],{"class":289},[272,9791,272],{"class":366},[272,9793,2311],{"class":289},[272,9795,9796],{"class":282},"page3",[272,9798,4113],{"class":289},[272,9800,272],{"class":366},[272,9802,4038],{"class":289},[272,9804,9805,9807,9809],{"class":274,"line":648},[272,9806,9692],{"class":289},[272,9808,4138],{"class":366},[272,9810,4038],{"class":289},[272,9812,9813,9816,9818],{"class":274,"line":658},[272,9814,9815],{"class":289},"        \u003C\u002F",[272,9817,4138],{"class":366},[272,9819,4038],{"class":289},[272,9821,9822,9824,9826],{"class":274,"line":668},[272,9823,6153],{"class":289},[272,9825,4138],{"class":366},[272,9827,4038],{"class":289},[272,9829,9830,9832,9834],{"class":274,"line":674},[272,9831,6162],{"class":289},[272,9833,9471],{"class":366},[272,9835,4038],{"class":289},[272,9837,9838,9840,9842],{"class":274,"line":1161},[272,9839,4175],{"class":289},[272,9841,4138],{"class":366},[272,9843,4038],{"class":289},[272,9845,9846,9848,9850],{"class":274,"line":1169},[272,9847,4113],{"class":289},[272,9849,4128],{"class":366},[272,9851,4038],{"class":289},[272,9853,9854],{"class":274,"line":1177},[272,9855,302],{"emptyLinePlaceholder":169},[272,9857,9858,9860,9862,9864,9866,9868,9870,9872],{"class":274,"line":1184},[272,9859,3081],{"class":289},[272,9861,4021],{"class":366},[272,9863,4024],{"class":781},[272,9865,2294],{"class":289},[272,9867,2334],{"class":289},[272,9869,268],{"class":293},[272,9871,2334],{"class":289},[272,9873,4038],{"class":289},[272,9875,9876,9878,9881,9883,9885,9887],{"class":274,"line":1192},[272,9877,279],{"class":278},[272,9879,9880],{"class":282}," Vue ",[272,9882,286],{"class":278},[272,9884,290],{"class":289},[272,9886,4012],{"class":293},[272,9888,297],{"class":289},[272,9890,9891],{"class":274,"line":1200},[272,9892,302],{"emptyLinePlaceholder":169},[272,9894,9895,9897,9899,9902,9904,9907,9909],{"class":274,"line":1208},[272,9896,348],{"class":278},[272,9898,351],{"class":278},[272,9900,9901],{"class":282}," Vue",[272,9903,430],{"class":289},[272,9905,9906],{"class":354},"extend",[272,9908,357],{"class":282},[272,9910,360],{"class":289},[272,9912,9913,9916,9918],{"class":274,"line":1216},[272,9914,9915],{"class":366},"  model",[272,9917,370],{"class":289},[272,9919,373],{"class":289},[272,9921,9922,9925,9927,9929,9931,9933],{"class":274,"line":1221},[272,9923,9924],{"class":366},"    prop",[272,9926,370],{"class":289},[272,9928,290],{"class":289},[272,9930,9500],{"class":293},[272,9932,403],{"class":289},[272,9934,406],{"class":289},[272,9936,9937,9940,9942,9944,9946,9948],{"class":274,"line":1229},[272,9938,9939],{"class":366},"    event",[272,9941,370],{"class":289},[272,9943,290],{"class":289},[272,9945,9521],{"class":293},[272,9947,403],{"class":289},[272,9949,406],{"class":289},[272,9951,9952],{"class":274,"line":1237},[272,9953,671],{"class":289},[272,9955,9956],{"class":274,"line":1245},[272,9957,302],{"emptyLinePlaceholder":169},[272,9959,9960,9963,9965],{"class":274,"line":1253},[272,9961,9962],{"class":366},"  props",[272,9964,370],{"class":289},[272,9966,373],{"class":289},[272,9968,9969,9972,9974],{"class":274,"line":1261},[272,9970,9971],{"class":366},"    isOpened",[272,9973,370],{"class":289},[272,9975,373],{"class":289},[272,9977,9978,9980,9982,9985],{"class":274,"line":1269},[272,9979,393],{"class":366},[272,9981,370],{"class":289},[272,9983,9984],{"class":282}," Boolean",[272,9986,406],{"class":289},[272,9988,9989,9992,9994,9996],{"class":274,"line":1277},[272,9990,9991],{"class":366},"      required",[272,9993,370],{"class":289},[272,9995,3513],{"class":2762},[272,9997,406],{"class":289},[272,9999,10000],{"class":274,"line":1285},[272,10001,1140],{"class":289},[272,10003,10004],{"class":274,"line":1293},[272,10005,671],{"class":289},[272,10007,10008],{"class":274,"line":1301},[272,10009,302],{"emptyLinePlaceholder":169},[272,10011,10012,10015,10017],{"class":274,"line":1309},[272,10013,10014],{"class":366},"  methods",[272,10016,370],{"class":289},[272,10018,373],{"class":289},[272,10020,10021,10024,10026],{"class":274,"line":1317},[272,10022,10023],{"class":366},"    close",[272,10025,506],{"class":289},[272,10027,373],{"class":289},[272,10029,10030,10033,10036,10038,10040,10042,10044],{"class":274,"line":1325},[272,10031,10032],{"class":289},"      this.",[272,10034,10035],{"class":354},"$emit",[272,10037,357],{"class":366},[272,10039,403],{"class":289},[272,10041,9521],{"class":293},[272,10043,403],{"class":289},[272,10045,680],{"class":366},[272,10047,10048],{"class":274,"line":1333},[272,10049,1140],{"class":289},[272,10051,10052],{"class":274,"line":1341},[272,10053,671],{"class":289},[272,10055,10056,10058],{"class":274,"line":1349},[272,10057,677],{"class":289},[272,10059,680],{"class":282},[272,10061,10062,10064,10066],{"class":274,"line":1357},[272,10063,4113],{"class":289},[272,10065,4021],{"class":366},[272,10067,4038],{"class":289},[272,10069,10070],{"class":274,"line":1365},[272,10071,302],{"emptyLinePlaceholder":169},[272,10073,10074,10076,10078,10080,10082,10084,10086,10088,10090],{"class":274,"line":1373},[272,10075,3081],{"class":289},[272,10077,2211],{"class":366},[272,10079,4024],{"class":781},[272,10081,2294],{"class":289},[272,10083,2334],{"class":289},[272,10085,4206],{"class":293},[272,10087,2334],{"class":289},[272,10089,4211],{"class":781},[272,10091,4038],{"class":289},[272,10093,10094],{"class":274,"line":1381},[272,10095,10096],{"class":282},".ume-slide-menu {\n",[272,10098,10099],{"class":274,"line":1389},[272,10100,10101],{"class":282},"  .background-enter,\n",[272,10103,10104],{"class":274,"line":1397},[272,10105,10106],{"class":282},"  .background-leave-to {\n",[272,10108,10109],{"class":274,"line":1404},[272,10110,10111],{"class":282},"    opacity: 0;\n",[272,10113,10114],{"class":274,"line":1412},[272,10115,909],{"class":282},[272,10117,10118],{"class":274,"line":1420},[272,10119,302],{"emptyLinePlaceholder":169},[272,10121,10122],{"class":274,"line":1428},[272,10123,10124],{"class":282},"  .background-enter-active {\n",[272,10126,10127],{"class":274,"line":1436},[272,10128,10129],{"class":282},"    transition: opacity 0.15s;\n",[272,10131,10132],{"class":274,"line":1444},[272,10133,909],{"class":282},[272,10135,10136],{"class":274,"line":1452},[272,10137,302],{"emptyLinePlaceholder":169},[272,10139,10140],{"class":274,"line":1460},[272,10141,10142],{"class":282},"  .menu-enter,\n",[272,10144,10145],{"class":274,"line":1468},[272,10146,10147],{"class":282},"  .menu-leave-to {\n",[272,10149,10150],{"class":274,"line":1476},[272,10151,10152],{"class":282},"    transform: translateX(10%);\n",[272,10154,10155],{"class":274,"line":1484},[272,10156,10111],{"class":282},[272,10158,10159],{"class":274,"line":1492},[272,10160,909],{"class":282},[272,10162,10163],{"class":274,"line":1500},[272,10164,302],{"emptyLinePlaceholder":169},[272,10166,10167],{"class":274,"line":1508},[272,10168,10169],{"class":282},"  .menu-enter-active {\n",[272,10171,10172],{"class":274,"line":1516},[272,10173,10174],{"class":282},"    transition: all 0.15s ease;\n",[272,10176,10177],{"class":274,"line":1524},[272,10178,909],{"class":282},[272,10180,10181],{"class":274,"line":1532},[272,10182,302],{"emptyLinePlaceholder":169},[272,10184,10185],{"class":274,"line":1540},[272,10186,10187],{"class":282},"  .menu-leave-active {\n",[272,10189,10190],{"class":274,"line":1548},[272,10191,10192],{"class":282},"    transition: all 0.15s cubic-bezier(1, 0.5, 0.8, 1);\n",[272,10194,10195],{"class":274,"line":1556},[272,10196,909],{"class":282},[272,10198,10199],{"class":274,"line":1564},[272,10200,302],{"emptyLinePlaceholder":169},[272,10202,10203],{"class":274,"line":1572},[272,10204,10205],{"class":282},"  .background {\n",[272,10207,10208],{"class":274,"line":1580},[272,10209,10210],{"class":282},"    width: 100%;\n",[272,10212,10213],{"class":274,"line":1588},[272,10214,10215],{"class":282},"    height: 100%;\n",[272,10217,10218],{"class":274,"line":1595},[272,10219,10220],{"class":282},"    position: fixed;\n",[272,10222,10223],{"class":274,"line":1602},[272,10224,10225],{"class":282},"    z-index: 98;\n",[272,10227,10228],{"class":274,"line":1608},[272,10229,10230],{"class":282},"    top: 0;\n",[272,10232,10234],{"class":274,"line":10233},84,[272,10235,10236],{"class":282},"    right: 0;\n",[272,10238,10240],{"class":274,"line":10239},85,[272,10241,10242],{"class":282},"    overflow-x: hidden;\n",[272,10244,10246],{"class":274,"line":10245},86,[272,10247,10248],{"class":282},"    background-color: rgba(0, 0, 0, 0.6);\n",[272,10250,10252],{"class":274,"line":10251},87,[272,10253,302],{"emptyLinePlaceholder":169},[272,10255,10257],{"class":274,"line":10256},88,[272,10258,10259],{"class":282},"    .close-button {\n",[272,10261,10263],{"class":274,"line":10262},89,[272,10264,10265],{"class":282},"      position: absolute;\n",[272,10267,10269],{"class":274,"line":10268},90,[272,10270,10271],{"class":282},"      top: 0;\n",[272,10273,10275],{"class":274,"line":10274},91,[272,10276,10277],{"class":282},"      left: 25px;\n",[272,10279,10281],{"class":274,"line":10280},92,[272,10282,10283],{"class":282},"      font-size: 36px;\n",[272,10285,10287],{"class":274,"line":10286},93,[272,10288,10289],{"class":282},"      color: #fff;\n",[272,10291,10293],{"class":274,"line":10292},94,[272,10294,6018],{"class":282},[272,10296,10298],{"class":274,"line":10297},95,[272,10299,909],{"class":282},[272,10301,10303],{"class":274,"line":10302},96,[272,10304,302],{"emptyLinePlaceholder":169},[272,10306,10308],{"class":274,"line":10307},97,[272,10309,10310],{"class":282},"  .menu {\n",[272,10312,10314],{"class":274,"line":10313},98,[272,10315,10215],{"class":282},[272,10317,10319],{"class":274,"line":10318},99,[272,10320,10321],{"class":282},"    width: 64%;\n",[272,10323,10325],{"class":274,"line":10324},100,[272,10326,10327],{"class":282},"    max-width: 320px;\n",[272,10329,10331],{"class":274,"line":10330},101,[272,10332,10220],{"class":282},[272,10334,10336],{"class":274,"line":10335},102,[272,10337,10338],{"class":282},"    z-index: 99;\n",[272,10340,10342],{"class":274,"line":10341},103,[272,10343,10230],{"class":282},[272,10345,10347],{"class":274,"line":10346},104,[272,10348,10236],{"class":282},[272,10350,10352],{"class":274,"line":10351},105,[272,10353,10354],{"class":282},"    background-color: #f3f3f3;\n",[272,10356,10358],{"class":274,"line":10357},106,[272,10359,10242],{"class":282},[272,10361,10363],{"class":274,"line":10362},107,[272,10364,302],{"emptyLinePlaceholder":169},[272,10366,10368],{"class":274,"line":10367},108,[272,10369,10370],{"class":282},"    .menu-item-wrapper {\n",[272,10372,10374],{"class":274,"line":10373},109,[272,10375,10376],{"class":282},"      background-color: #fff;\n",[272,10378,10380],{"class":274,"line":10379},110,[272,10381,10382],{"class":282},"      padding-top: 40px;\n",[272,10384,10386],{"class":274,"line":10385},111,[272,10387,10388],{"class":282},"      padding-bottom: 52px;\n",[272,10390,10392],{"class":274,"line":10391},112,[272,10393,6018],{"class":282},[272,10395,10397],{"class":274,"line":10396},113,[272,10398,302],{"emptyLinePlaceholder":169},[272,10400,10402],{"class":274,"line":10401},114,[272,10403,10404],{"class":282},"    .menu-item {\n",[272,10406,10408],{"class":274,"line":10407},115,[272,10409,10410],{"class":282},"      display: block;\n",[272,10412,10414],{"class":274,"line":10413},116,[272,10415,10416],{"class":282},"      cursor: pointer;\n",[272,10418,10420],{"class":274,"line":10419},117,[272,10421,10422],{"class":282},"      margin: 0 20px;\n",[272,10424,10426],{"class":274,"line":10425},118,[272,10427,10428],{"class":282},"      padding: 17px 0;\n",[272,10430,10432],{"class":274,"line":10431},119,[272,10433,10434],{"class":282},"      font-size: 16px;\n",[272,10436,10438],{"class":274,"line":10437},120,[272,10439,10440],{"class":282},"      font-weight: bold;\n",[272,10442,10444],{"class":274,"line":10443},121,[272,10445,10446],{"class":282},"      border-bottom: thin solid #c7c7cc;\n",[272,10448,10450],{"class":274,"line":10449},122,[272,10451,10452],{"class":282},"      color: #4a4a4a;\n",[272,10454,10456],{"class":274,"line":10455},123,[272,10457,10458],{"class":282},"      text-decoration: none;\n",[272,10460,10462],{"class":274,"line":10461},124,[272,10463,10464],{"class":282},"      line-height: 1;\n",[272,10466,10468],{"class":274,"line":10467},125,[272,10469,302],{"emptyLinePlaceholder":169},[272,10471,10473],{"class":274,"line":10472},126,[272,10474,10475],{"class":282},"      span {\n",[272,10477,10479],{"class":274,"line":10478},127,[272,10480,10481],{"class":282},"        vertical-align: middle;\n",[272,10483,10485],{"class":274,"line":10484},128,[272,10486,3213],{"class":282},[272,10488,10490],{"class":274,"line":10489},129,[272,10491,6018],{"class":282},[272,10493,10495],{"class":274,"line":10494},130,[272,10496,909],{"class":282},[272,10498,10500],{"class":274,"line":10499},131,[272,10501,965],{"class":282},[272,10503,10505,10507,10509],{"class":274,"line":10504},132,[272,10506,4113],{"class":289},[272,10508,2211],{"class":366},[272,10510,4038],{"class":289},[15,10512,10513,10514,10517],{},"ここでの注意点では、",[203,10515,10516],{},"v-if"," などで制御せずに、呼び出しているコンポーネントをマウントしているときには、スライドメニューのコンポーネントもレンダリングされている必要がある。",[264,10519,10522],{"className":4009,"code":10520,"filename":10521,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"index-page\">\n    \u003Cume-slide-menu v-model=\"showSlideMenu\" \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n","pages\u002Findex.vue",[203,10523,10524,10532,10551,10571,10579],{"__ignoreMap":154},[272,10525,10526,10528,10530],{"class":274,"line":275},[272,10527,3081],{"class":289},[272,10529,4128],{"class":366},[272,10531,4038],{"class":289},[272,10533,10534,10536,10538,10540,10542,10544,10547,10549],{"class":274,"line":155},[272,10535,4135],{"class":289},[272,10537,4138],{"class":366},[272,10539,4141],{"class":781},[272,10541,2294],{"class":289},[272,10543,2334],{"class":289},[272,10545,10546],{"class":293},"index-page",[272,10548,2334],{"class":289},[272,10550,4038],{"class":289},[272,10552,10553,10555,10557,10560,10562,10564,10567,10569],{"class":274,"line":305},[272,10554,4157],{"class":289},[272,10556,9460],{"class":366},[272,10558,10559],{"class":781}," v-model",[272,10561,2294],{"class":289},[272,10563,2334],{"class":289},[272,10565,10566],{"class":293},"showSlideMenu",[272,10568,2334],{"class":289},[272,10570,7576],{"class":289},[272,10572,10573,10575,10577],{"class":274,"line":340},[272,10574,4175],{"class":289},[272,10576,4138],{"class":366},[272,10578,4038],{"class":289},[272,10580,10581,10583,10585],{"class":274,"line":345},[272,10582,4113],{"class":289},[272,10584,4128],{"class":366},[272,10586,4038],{"class":289},[245,10588,9333],{"id":9333},[15,10590,10591],{},[21,10592],{"alt":10593,"src":10594},"popup.gif","https:\u002F\u002Fqiita-image-store.s3.ap-northeast-1.amazonaws.com\u002F0\u002F152032\u002F21727a0d-bbe4-00f5-b45b-a49a1a72628b.gif",[15,10596,10597],{},"次は、ポップアップです。ページが表示されたあとにキャンペーンの告知として表示したり、条件によってボタンをクリックをしたにフックして表示します。スライドメニューと同じで、背景をクリックしたときにも、ポップアップを閉じる処理を入れるのを忘れないようにしましょう。",[15,10599,10600,10601,10603],{},"実装も上のスライドメニューとほぼ同じです。Vue.js の ",[203,10602,9266],{}," タグを使って、DOM がレンダリングされるときと破棄されるときまでの挙動を CSS クラスでなめらかにポップアップを表示できます。",[264,10605,10608],{"className":4009,"code":10606,"filename":10607,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"ume-popup\">\n    \u003Ctransition name=\"background\">\n      \u003Cdiv v-if=\"showPopup\" class=\"background\" @click.prevent=\"$emit('change-popup', false)\" \u002F>\n    \u003C\u002Ftransition>\n\n    \u003Ctransition name=\"popup\">\n      \u003Cdiv v-if=\"showPopup\" class=\"popup-wrapper\">\n        \u003Cume-close class=\"icon icon-close\" @click.prevent=\"$emit('change-popup', false)\" \u002F>\n\n        \u003Cdiv class=\"image-wrapper\">\n          \u003Cimg src=\"https:\u002F\u002Fpicsum.photos\u002Fseed\u002Fpicsum\u002F400\u002F600\" \u002F>\n        \u003C\u002Fdiv>\n      \u003C\u002Fdiv>\n    \u003C\u002Ftransition>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue from 'vue'\n\nimport UmeClose from '~\u002Fassets\u002Ffonts\u002Fclose.svg?inline'\n\nexport default Vue.extend({\n  components: {\n    UmeClose,\n  },\n\n  model: {\n    prop: 'showPopup',\n    event: 'change-popup',\n  },\n\n  props: {\n    showPopup: {\n      type: Boolean,\n      required: true,\n    },\n  },\n})\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\" scoped>\n.ume-popup {\n  .background-enter-active {\n    transition: opacity 0.15s;\n  }\n\n  .background-enter,\n  .background-leave-to {\n    opacity: 0;\n  }\n\n  .popup-enter-active {\n    transition: all 0.25s ease;\n  }\n\n  .popup-leave-active {\n    transition: all 0.25s cubic-bezier(1, 0.5, 0.8, 1);\n  }\n\n  .popup-enter,\n  .popup-leave-to {\n    opacity: 0;\n  }\n\n  .background {\n    width: 100%;\n    height: 100%;\n    position: fixed;\n    z-index: 1;\n    top: 0;\n    right: 0;\n    overflow-x: hidden;\n    background-color: rgba(35, 24, 21, 0.35);\n  }\n\n  .popup-wrapper {\n    top: 50%;\n    left: 50%;\n    transform: translate(-50%, -50%);\n    position: fixed;\n    padding: 0.5em 1em;\n    z-index: 2;\n    display: flex;\n    flex-direction: column;\n\n    .icon-close {\n      height: 36px;\n      fill: black;\n      margin: 0 0 10px auto;\n    }\n\n    .image-wrapper {\n      display: block;\n      height: 350px;\n      width: 330px;\n\n      img {\n        height: 100%;\n        width: 100%;\n        border-radius: 10px;\n      }\n    }\n  }\n}\n\u003C\u002Fstyle>\n","components\u002Fmolecules\u002Fume-popup.vue",[203,10609,10610,10618,10637,10655,10696,10704,10708,10727,10756,10786,10790,10809,10829,10837,10845,10853,10861,10869,10873,10891,10905,10909,10925,10929,10945,10954,10961,10965,10969,10977,10991,11006,11010,11014,11022,11031,11041,11051,11055,11059,11065,11073,11077,11097,11102,11106,11110,11114,11118,11122,11126,11130,11134,11138,11143,11148,11152,11156,11161,11166,11170,11174,11179,11184,11188,11192,11196,11200,11204,11208,11212,11217,11221,11225,11229,11234,11238,11242,11247,11252,11257,11262,11266,11271,11276,11281,11286,11290,11295,11300,11305,11310,11314,11318,11323,11327,11332,11337,11341,11346,11351,11356,11361,11365,11369,11373,11377],{"__ignoreMap":154},[272,10611,10612,10614,10616],{"class":274,"line":275},[272,10613,3081],{"class":289},[272,10615,4128],{"class":366},[272,10617,4038],{"class":289},[272,10619,10620,10622,10624,10626,10628,10630,10633,10635],{"class":274,"line":155},[272,10621,4135],{"class":289},[272,10623,4138],{"class":366},[272,10625,4141],{"class":781},[272,10627,2294],{"class":289},[272,10629,2334],{"class":289},[272,10631,10632],{"class":293},"ume-popup",[272,10634,2334],{"class":289},[272,10636,4038],{"class":289},[272,10638,10639,10641,10643,10645,10647,10649,10651,10653],{"class":274,"line":305},[272,10640,4157],{"class":289},[272,10642,9471],{"class":366},[272,10644,9474],{"class":781},[272,10646,2294],{"class":289},[272,10648,2334],{"class":289},[272,10650,9374],{"class":293},[272,10652,2334],{"class":289},[272,10654,4038],{"class":289},[272,10656,10657,10659,10661,10663,10665,10667,10670,10672,10674,10676,10678,10680,10682,10685,10687,10689,10692,10694],{"class":274,"line":340},[272,10658,6139],{"class":289},[272,10660,4138],{"class":366},[272,10662,9493],{"class":781},[272,10664,2294],{"class":289},[272,10666,2334],{"class":289},[272,10668,10669],{"class":293},"showPopup",[272,10671,2334],{"class":289},[272,10673,4141],{"class":781},[272,10675,2294],{"class":289},[272,10677,2334],{"class":289},[272,10679,9374],{"class":293},[272,10681,2334],{"class":289},[272,10683,10684],{"class":781}," @click.prevent",[272,10686,2294],{"class":289},[272,10688,2334],{"class":289},[272,10690,10691],{"class":293},"$emit('change-popup', false)",[272,10693,2334],{"class":289},[272,10695,7576],{"class":289},[272,10697,10698,10700,10702],{"class":274,"line":345},[272,10699,6162],{"class":289},[272,10701,9471],{"class":366},[272,10703,4038],{"class":289},[272,10705,10706],{"class":274,"line":363},[272,10707,302],{"emptyLinePlaceholder":169},[272,10709,10710,10712,10714,10716,10718,10720,10723,10725],{"class":274,"line":376},[272,10711,4157],{"class":289},[272,10713,9471],{"class":366},[272,10715,9474],{"class":781},[272,10717,2294],{"class":289},[272,10719,2334],{"class":289},[272,10721,10722],{"class":293},"popup",[272,10724,2334],{"class":289},[272,10726,4038],{"class":289},[272,10728,10729,10731,10733,10735,10737,10739,10741,10743,10745,10747,10749,10752,10754],{"class":274,"line":390},[272,10730,6139],{"class":289},[272,10732,4138],{"class":366},[272,10734,9493],{"class":781},[272,10736,2294],{"class":289},[272,10738,2334],{"class":289},[272,10740,10669],{"class":293},[272,10742,2334],{"class":289},[272,10744,4141],{"class":781},[272,10746,2294],{"class":289},[272,10748,2334],{"class":289},[272,10750,10751],{"class":293},"popup-wrapper",[272,10753,2334],{"class":289},[272,10755,4038],{"class":289},[272,10757,10758,10760,10763,10765,10767,10769,10772,10774,10776,10778,10780,10782,10784],{"class":274,"line":409},[272,10759,9530],{"class":289},[272,10761,10762],{"class":366},"ume-close",[272,10764,4141],{"class":781},[272,10766,2294],{"class":289},[272,10768,2334],{"class":289},[272,10770,10771],{"class":293},"icon icon-close",[272,10773,2334],{"class":289},[272,10775,10684],{"class":781},[272,10777,2294],{"class":289},[272,10779,2334],{"class":289},[272,10781,10691],{"class":293},[272,10783,2334],{"class":289},[272,10785,7576],{"class":289},[272,10787,10788],{"class":274,"line":419},[272,10789,302],{"emptyLinePlaceholder":169},[272,10791,10792,10794,10796,10798,10800,10802,10805,10807],{"class":274,"line":449},[272,10793,9530],{"class":289},[272,10795,4138],{"class":366},[272,10797,4141],{"class":781},[272,10799,2294],{"class":289},[272,10801,2334],{"class":289},[272,10803,10804],{"class":293},"image-wrapper",[272,10806,2334],{"class":289},[272,10808,4038],{"class":289},[272,10810,10811,10813,10815,10818,10820,10822,10825,10827],{"class":274,"line":466},[272,10812,9644],{"class":289},[272,10814,21],{"class":366},[272,10816,10817],{"class":781}," src",[272,10819,2294],{"class":289},[272,10821,2334],{"class":289},[272,10823,10824],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fseed\u002Fpicsum\u002F400\u002F600",[272,10826,2334],{"class":289},[272,10828,7576],{"class":289},[272,10830,10831,10833,10835],{"class":274,"line":472},[272,10832,9815],{"class":289},[272,10834,4138],{"class":366},[272,10836,4038],{"class":289},[272,10838,10839,10841,10843],{"class":274,"line":491},[272,10840,6153],{"class":289},[272,10842,4138],{"class":366},[272,10844,4038],{"class":289},[272,10846,10847,10849,10851],{"class":274,"line":511},[272,10848,6162],{"class":289},[272,10850,9471],{"class":366},[272,10852,4038],{"class":289},[272,10854,10855,10857,10859],{"class":274,"line":529},[272,10856,4175],{"class":289},[272,10858,4138],{"class":366},[272,10860,4038],{"class":289},[272,10862,10863,10865,10867],{"class":274,"line":547},[272,10864,4113],{"class":289},[272,10866,4128],{"class":366},[272,10868,4038],{"class":289},[272,10870,10871],{"class":274,"line":565},[272,10872,302],{"emptyLinePlaceholder":169},[272,10874,10875,10877,10879,10881,10883,10885,10887,10889],{"class":274,"line":592},[272,10876,3081],{"class":289},[272,10878,4021],{"class":366},[272,10880,4024],{"class":781},[272,10882,2294],{"class":289},[272,10884,2334],{"class":289},[272,10886,268],{"class":293},[272,10888,2334],{"class":289},[272,10890,4038],{"class":289},[272,10892,10893,10895,10897,10899,10901,10903],{"class":274,"line":611},[272,10894,279],{"class":278},[272,10896,9880],{"class":282},[272,10898,286],{"class":278},[272,10900,290],{"class":289},[272,10902,4012],{"class":293},[272,10904,297],{"class":289},[272,10906,10907],{"class":274,"line":629},[272,10908,302],{"emptyLinePlaceholder":169},[272,10910,10911,10913,10916,10918,10920,10923],{"class":274,"line":648},[272,10912,279],{"class":278},[272,10914,10915],{"class":282}," UmeClose ",[272,10917,286],{"class":278},[272,10919,290],{"class":289},[272,10921,10922],{"class":293},"~\u002Fassets\u002Ffonts\u002Fclose.svg?inline",[272,10924,297],{"class":289},[272,10926,10927],{"class":274,"line":658},[272,10928,302],{"emptyLinePlaceholder":169},[272,10930,10931,10933,10935,10937,10939,10941,10943],{"class":274,"line":668},[272,10932,348],{"class":278},[272,10934,351],{"class":278},[272,10936,9901],{"class":282},[272,10938,430],{"class":289},[272,10940,9906],{"class":354},[272,10942,357],{"class":282},[272,10944,360],{"class":289},[272,10946,10947,10950,10952],{"class":274,"line":674},[272,10948,10949],{"class":366},"  components",[272,10951,370],{"class":289},[272,10953,373],{"class":289},[272,10955,10956,10959],{"class":274,"line":1161},[272,10957,10958],{"class":282},"    UmeClose",[272,10960,406],{"class":289},[272,10962,10963],{"class":274,"line":1169},[272,10964,671],{"class":289},[272,10966,10967],{"class":274,"line":1177},[272,10968,302],{"emptyLinePlaceholder":169},[272,10970,10971,10973,10975],{"class":274,"line":1184},[272,10972,9915],{"class":366},[272,10974,370],{"class":289},[272,10976,373],{"class":289},[272,10978,10979,10981,10983,10985,10987,10989],{"class":274,"line":1192},[272,10980,9924],{"class":366},[272,10982,370],{"class":289},[272,10984,290],{"class":289},[272,10986,10669],{"class":293},[272,10988,403],{"class":289},[272,10990,406],{"class":289},[272,10992,10993,10995,10997,10999,11002,11004],{"class":274,"line":1200},[272,10994,9939],{"class":366},[272,10996,370],{"class":289},[272,10998,290],{"class":289},[272,11000,11001],{"class":293},"change-popup",[272,11003,403],{"class":289},[272,11005,406],{"class":289},[272,11007,11008],{"class":274,"line":1208},[272,11009,671],{"class":289},[272,11011,11012],{"class":274,"line":1216},[272,11013,302],{"emptyLinePlaceholder":169},[272,11015,11016,11018,11020],{"class":274,"line":1221},[272,11017,9962],{"class":366},[272,11019,370],{"class":289},[272,11021,373],{"class":289},[272,11023,11024,11027,11029],{"class":274,"line":1229},[272,11025,11026],{"class":366},"    showPopup",[272,11028,370],{"class":289},[272,11030,373],{"class":289},[272,11032,11033,11035,11037,11039],{"class":274,"line":1237},[272,11034,393],{"class":366},[272,11036,370],{"class":289},[272,11038,9984],{"class":282},[272,11040,406],{"class":289},[272,11042,11043,11045,11047,11049],{"class":274,"line":1245},[272,11044,9991],{"class":366},[272,11046,370],{"class":289},[272,11048,3513],{"class":2762},[272,11050,406],{"class":289},[272,11052,11053],{"class":274,"line":1253},[272,11054,1140],{"class":289},[272,11056,11057],{"class":274,"line":1261},[272,11058,671],{"class":289},[272,11060,11061,11063],{"class":274,"line":1269},[272,11062,677],{"class":289},[272,11064,680],{"class":282},[272,11066,11067,11069,11071],{"class":274,"line":1277},[272,11068,4113],{"class":289},[272,11070,4021],{"class":366},[272,11072,4038],{"class":289},[272,11074,11075],{"class":274,"line":1285},[272,11076,302],{"emptyLinePlaceholder":169},[272,11078,11079,11081,11083,11085,11087,11089,11091,11093,11095],{"class":274,"line":1293},[272,11080,3081],{"class":289},[272,11082,2211],{"class":366},[272,11084,4024],{"class":781},[272,11086,2294],{"class":289},[272,11088,2334],{"class":289},[272,11090,4206],{"class":293},[272,11092,2334],{"class":289},[272,11094,4211],{"class":781},[272,11096,4038],{"class":289},[272,11098,11099],{"class":274,"line":1301},[272,11100,11101],{"class":282},".ume-popup {\n",[272,11103,11104],{"class":274,"line":1309},[272,11105,10124],{"class":282},[272,11107,11108],{"class":274,"line":1317},[272,11109,10129],{"class":282},[272,11111,11112],{"class":274,"line":1325},[272,11113,909],{"class":282},[272,11115,11116],{"class":274,"line":1333},[272,11117,302],{"emptyLinePlaceholder":169},[272,11119,11120],{"class":274,"line":1341},[272,11121,10101],{"class":282},[272,11123,11124],{"class":274,"line":1349},[272,11125,10106],{"class":282},[272,11127,11128],{"class":274,"line":1357},[272,11129,10111],{"class":282},[272,11131,11132],{"class":274,"line":1365},[272,11133,909],{"class":282},[272,11135,11136],{"class":274,"line":1373},[272,11137,302],{"emptyLinePlaceholder":169},[272,11139,11140],{"class":274,"line":1381},[272,11141,11142],{"class":282},"  .popup-enter-active {\n",[272,11144,11145],{"class":274,"line":1389},[272,11146,11147],{"class":282},"    transition: all 0.25s ease;\n",[272,11149,11150],{"class":274,"line":1397},[272,11151,909],{"class":282},[272,11153,11154],{"class":274,"line":1404},[272,11155,302],{"emptyLinePlaceholder":169},[272,11157,11158],{"class":274,"line":1412},[272,11159,11160],{"class":282},"  .popup-leave-active {\n",[272,11162,11163],{"class":274,"line":1420},[272,11164,11165],{"class":282},"    transition: all 0.25s cubic-bezier(1, 0.5, 0.8, 1);\n",[272,11167,11168],{"class":274,"line":1428},[272,11169,909],{"class":282},[272,11171,11172],{"class":274,"line":1436},[272,11173,302],{"emptyLinePlaceholder":169},[272,11175,11176],{"class":274,"line":1444},[272,11177,11178],{"class":282},"  .popup-enter,\n",[272,11180,11181],{"class":274,"line":1452},[272,11182,11183],{"class":282},"  .popup-leave-to {\n",[272,11185,11186],{"class":274,"line":1460},[272,11187,10111],{"class":282},[272,11189,11190],{"class":274,"line":1468},[272,11191,909],{"class":282},[272,11193,11194],{"class":274,"line":1476},[272,11195,302],{"emptyLinePlaceholder":169},[272,11197,11198],{"class":274,"line":1484},[272,11199,10205],{"class":282},[272,11201,11202],{"class":274,"line":1492},[272,11203,10210],{"class":282},[272,11205,11206],{"class":274,"line":1500},[272,11207,10215],{"class":282},[272,11209,11210],{"class":274,"line":1508},[272,11211,10220],{"class":282},[272,11213,11214],{"class":274,"line":1516},[272,11215,11216],{"class":282},"    z-index: 1;\n",[272,11218,11219],{"class":274,"line":1524},[272,11220,10230],{"class":282},[272,11222,11223],{"class":274,"line":1532},[272,11224,10236],{"class":282},[272,11226,11227],{"class":274,"line":1540},[272,11228,10242],{"class":282},[272,11230,11231],{"class":274,"line":1548},[272,11232,11233],{"class":282},"    background-color: rgba(35, 24, 21, 0.35);\n",[272,11235,11236],{"class":274,"line":1556},[272,11237,909],{"class":282},[272,11239,11240],{"class":274,"line":1564},[272,11241,302],{"emptyLinePlaceholder":169},[272,11243,11244],{"class":274,"line":1572},[272,11245,11246],{"class":282},"  .popup-wrapper {\n",[272,11248,11249],{"class":274,"line":1580},[272,11250,11251],{"class":282},"    top: 50%;\n",[272,11253,11254],{"class":274,"line":1588},[272,11255,11256],{"class":282},"    left: 50%;\n",[272,11258,11259],{"class":274,"line":1595},[272,11260,11261],{"class":282},"    transform: translate(-50%, -50%);\n",[272,11263,11264],{"class":274,"line":1602},[272,11265,10220],{"class":282},[272,11267,11268],{"class":274,"line":1608},[272,11269,11270],{"class":282},"    padding: 0.5em 1em;\n",[272,11272,11273],{"class":274,"line":10233},[272,11274,11275],{"class":282},"    z-index: 2;\n",[272,11277,11278],{"class":274,"line":10239},[272,11279,11280],{"class":282},"    display: flex;\n",[272,11282,11283],{"class":274,"line":10245},[272,11284,11285],{"class":282},"    flex-direction: column;\n",[272,11287,11288],{"class":274,"line":10251},[272,11289,302],{"emptyLinePlaceholder":169},[272,11291,11292],{"class":274,"line":10256},[272,11293,11294],{"class":282},"    .icon-close {\n",[272,11296,11297],{"class":274,"line":10262},[272,11298,11299],{"class":282},"      height: 36px;\n",[272,11301,11302],{"class":274,"line":10268},[272,11303,11304],{"class":282},"      fill: black;\n",[272,11306,11307],{"class":274,"line":10274},[272,11308,11309],{"class":282},"      margin: 0 0 10px auto;\n",[272,11311,11312],{"class":274,"line":10280},[272,11313,6018],{"class":282},[272,11315,11316],{"class":274,"line":10286},[272,11317,302],{"emptyLinePlaceholder":169},[272,11319,11320],{"class":274,"line":10292},[272,11321,11322],{"class":282},"    .image-wrapper {\n",[272,11324,11325],{"class":274,"line":10297},[272,11326,10410],{"class":282},[272,11328,11329],{"class":274,"line":10302},[272,11330,11331],{"class":282},"      height: 350px;\n",[272,11333,11334],{"class":274,"line":10307},[272,11335,11336],{"class":282},"      width: 330px;\n",[272,11338,11339],{"class":274,"line":10313},[272,11340,302],{"emptyLinePlaceholder":169},[272,11342,11343],{"class":274,"line":10318},[272,11344,11345],{"class":282},"      img {\n",[272,11347,11348],{"class":274,"line":10324},[272,11349,11350],{"class":282},"        height: 100%;\n",[272,11352,11353],{"class":274,"line":10330},[272,11354,11355],{"class":282},"        width: 100%;\n",[272,11357,11358],{"class":274,"line":10335},[272,11359,11360],{"class":282},"        border-radius: 10px;\n",[272,11362,11363],{"class":274,"line":10341},[272,11364,3213],{"class":282},[272,11366,11367],{"class":274,"line":10346},[272,11368,6018],{"class":282},[272,11370,11371],{"class":274,"line":10351},[272,11372,909],{"class":282},[272,11374,11375],{"class":274,"line":10357},[272,11376,965],{"class":282},[272,11378,11379,11381,11383],{"class":274,"line":10362},[272,11380,4113],{"class":289},[272,11382,2211],{"class":366},[272,11384,4038],{"class":289},[15,11386,11387,11388,11390],{},"ここでも、呼び出し側のほうで　",[203,11389,10516],{}," で制御せずに、事前にポップアップのコンポーネントもレンダリングされている必要があります。",[264,11392,11394],{"className":4009,"code":11393,"filename":10521,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"index-page\">\n    \u003Cume-popup v-model=\"showPopup\" \u002F>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n",[203,11395,11396,11404,11422,11440,11448],{"__ignoreMap":154},[272,11397,11398,11400,11402],{"class":274,"line":275},[272,11399,3081],{"class":289},[272,11401,4128],{"class":366},[272,11403,4038],{"class":289},[272,11405,11406,11408,11410,11412,11414,11416,11418,11420],{"class":274,"line":155},[272,11407,4135],{"class":289},[272,11409,4138],{"class":366},[272,11411,4141],{"class":781},[272,11413,2294],{"class":289},[272,11415,2334],{"class":289},[272,11417,10546],{"class":293},[272,11419,2334],{"class":289},[272,11421,4038],{"class":289},[272,11423,11424,11426,11428,11430,11432,11434,11436,11438],{"class":274,"line":305},[272,11425,4157],{"class":289},[272,11427,10632],{"class":366},[272,11429,10559],{"class":781},[272,11431,2294],{"class":289},[272,11433,2334],{"class":289},[272,11435,10669],{"class":293},[272,11437,2334],{"class":289},[272,11439,7576],{"class":289},[272,11441,11442,11444,11446],{"class":274,"line":340},[272,11443,4175],{"class":289},[272,11445,4138],{"class":366},[272,11447,4038],{"class":289},[272,11449,11450,11452,11454],{"class":274,"line":345},[272,11451,4113],{"class":289},[272,11453,4128],{"class":366},[272,11455,4038],{"class":289},[245,11457,9336],{"id":9336},[21,11459],{"width":9350,"alt":11460,"src":11461},"accordion.gif","https:\u002F\u002Fqiita-image-store.s3.ap-northeast-1.amazonaws.com\u002F0\u002F152032\u002F9747d6f3-af65-39e7-2486-85c147167e1e.gif",[15,11463,11464,11465,11467],{},"狭い限定された枠の中で、メニューをクリックしてコンテンツを開閉したいというケースがあり、その対応でアコーディオンを実装しました。これも OSS のライブラリで要求されるデザインや仕様を満たせるかが不安だったので、自分で実装しました。今回も Vue.js の",[203,11466,9266],{},"タグを使っていますが、上 2 つとは少し違います。",[15,11469,11470,11471],{},"どのように違うかというと、今まではトランジション状態を css で任せていましたが、",[716,11472,11473],{},"今回はJavaScriptのほうで制御しています。",[15,11475,11476,11477,11480],{},"コンテンツが開かれたあとのアコーディオンの高さがコンテンツの量に依存し、css のクラスで言うところの",[203,11478,11479],{},"xxx-enter-to","で指定する高さが動的になることから、css で静的に決め打ちできません。今回はサンプルなので、コンテンツは静的に決まっていますが、実際は API のレスポンスに依存するので、高さが動的になっています。",[15,11482,11483,11484,11486,11487,11490,11491,11493,11494,11499,11500,11503,11504,11506],{},"動的な高さをどう与えるかというと、トランジションが終わるとき、つまり",[203,11485,11479],{}," のときに、そのコンテンツのラッパーの ",[203,11488,11489],{},"scrollHeight"," を渡すようにすれば解決できます。 Vue.js の ",[203,11492,9266],{}," タグには、",[80,11495,11498],{"href":11496,"rel":11497,"target":87},"https:\u002F\u002Fjp.vuejs.org\u002Fv2\u002Fguide\u002Ftransitions.html#JavaScript-%E3%83%95%E3%83%83%E3%82%AF",[84,85,86],"JavaScriptフック","があります。ここでは ",[203,11501,11502],{},"@enter"," のフックで、アコーディオンのコンテンツのラッパーの高さを ",[203,11505,11489],{}," と同じにすれば、動的に高さを決めることができます。",[15,11508,11509,11510,11512,11513,11515,11516,11519,11520,11523,11524,11526,11527,1621,11529,11531,11532,11534,11535,11538,11539,11541,11542,11544,11545,3413,11548,11551],{},"ここで注意すべきなのは、アコーディオンを開く前に、一度アコーディオンの高さを ",[203,11511,3374],{}," にしないとアニメーションが動きません。",[203,11514,3374],{}," と決め打ちしないと",[203,11517,11518],{},"height: auto"," が割り振られてしまい、",[203,11521,11522],{},"height: ${height}px"," へのケースでは、",[203,11525,9471],{}," が効かなくなってしまいます。\n逆もしかりで、コンテンツを閉じるときの ",[203,11528,11522],{},[203,11530,11518],{}," へのケースでも、",[203,11533,9471],{}," が効かなくなってしまいます。なので、コンテンツが開かれる前と閉じたあとの ",[203,11536,11537],{},"height"," は ",[203,11540,3374],{}," にしましょう。この ",[203,11543,3374],{},"にするというのも、JavaScript のフックで実現可能です。(下の例で言うと、",[203,11546,11547],{},"@before-enter",[203,11549,11550],{},"@leave","になります。)",[264,11553,11556],{"className":4009,"code":11554,"filename":11555,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"ume-accordion\">\n    \u003Cdiv class=\"header\" @click=\"$emit('expand')\">\n      \u003Cslot name=\"header\" \u002F>\n\n      \u003Cdown-arrow v-if=\"expandable\" class=\"icon\" :class=\"{ rotate: expanded }\" \u002F>\n    \u003C\u002Fdiv>\n\n    \u003Ctransition name=\"accordion\" @before-enter=\"beforeEnter\" @enter=\"enter\" @before-leave=\"beforeLeave\" @leave=\"leave\">\n      \u003Cdiv v-if=\"expanded\" ref=\"content\" class=\"content\">\n        \u003Cslot name=\"content\" \u002F>\n      \u003C\u002Fdiv>\n    \u003C\u002Ftransition>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue from 'vue'\n\nimport DownArrow from '~\u002Fassets\u002Ffonts\u002Fdown-arrow.svg?inline'\n\nexport default Vue.extend({\n  components: {\n    DownArrow,\n  },\n\n  model: {\n    prop: 'expanded',\n    event: 'expand',\n  },\n\n  props: {\n    expanded: {\n      type: Boolean,\n      required: true,\n    },\n\n    expandable: {\n      type: Boolean,\n      required: true,\n    },\n  },\n\n  mounted() {\n    if (this.$refs.content) {\n      (this.$refs.content as HTMLElement).style.height = `${this.$refs.content.clientHeight}px`\n    }\n  },\n\n  methods: {\n    beforeEnter(el: HTMLElement) {\n      el.style.height = '0'\n    },\n\n    enter(el: HTMLElement) {\n      el.style.height = el.scrollHeight + 'px'\n    },\n\n    beforeLeave(el: HTMLElement) {\n      el.style.height = el.scrollHeight + 'px'\n    },\n\n    leave(el: HTMLElement) {\n      el.style.height = '0'\n    },\n  },\n})\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\" scoped>\n.ume-accordion {\n  border-radius: 6px;\n  padding-top: 16px;\n\n  .header {\n    color: #fff;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    line-height: 1;\n    padding-bottom: 16px;\n    border-bottom: solid 1px #d1d1d6;\n\n    .icon {\n      display: block;\n      fill: #c7c7cc;\n      height: 14px;\n      width: 14px;\n      transform: rotate(0deg);\n      transition-duration: 0.3s;\n    }\n\n    .rotate {\n      transform: rotate(180deg);\n      transition-duration: 0.3s;\n    }\n  }\n\n  .content {\n    padding: 0 12px;\n    overflow: hidden;\n    transition: 0.2s ease-out;\n  }\n}\n\u003C\u002Fstyle>\n","components\u002Fatoms\u002Fume-accordion.vue",[203,11557,11558,11566,11585,11615,11634,11638,11681,11689,11693,11760,11799,11817,11825,11833,11841,11849,11853,11871,11885,11889,11905,11909,11925,11933,11940,11944,11948,11956,11970,11985,11989,11993,12001,12010,12020,12030,12034,12038,12047,12057,12067,12071,12075,12079,12088,12109,12163,12167,12171,12175,12183,12201,12222,12226,12230,12247,12277,12281,12285,12302,12330,12334,12338,12355,12375,12379,12383,12389,12397,12401,12421,12426,12431,12436,12440,12445,12450,12454,12459,12464,12469,12474,12479,12483,12488,12492,12497,12502,12507,12512,12517,12521,12525,12530,12535,12539,12543,12547,12551,12556,12561,12566,12571,12575,12579],{"__ignoreMap":154},[272,11559,11560,11562,11564],{"class":274,"line":275},[272,11561,3081],{"class":289},[272,11563,4128],{"class":366},[272,11565,4038],{"class":289},[272,11567,11568,11570,11572,11574,11576,11578,11581,11583],{"class":274,"line":155},[272,11569,4135],{"class":289},[272,11571,4138],{"class":366},[272,11573,4141],{"class":781},[272,11575,2294],{"class":289},[272,11577,2334],{"class":289},[272,11579,11580],{"class":293},"ume-accordion",[272,11582,2334],{"class":289},[272,11584,4038],{"class":289},[272,11586,11587,11589,11591,11593,11595,11597,11600,11602,11604,11606,11608,11611,11613],{"class":274,"line":305},[272,11588,4157],{"class":289},[272,11590,4138],{"class":366},[272,11592,4141],{"class":781},[272,11594,2294],{"class":289},[272,11596,2334],{"class":289},[272,11598,11599],{"class":293},"header",[272,11601,2334],{"class":289},[272,11603,7467],{"class":781},[272,11605,2294],{"class":289},[272,11607,2334],{"class":289},[272,11609,11610],{"class":293},"$emit('expand')",[272,11612,2334],{"class":289},[272,11614,4038],{"class":289},[272,11616,11617,11619,11622,11624,11626,11628,11630,11632],{"class":274,"line":340},[272,11618,6139],{"class":289},[272,11620,11621],{"class":366},"slot",[272,11623,9474],{"class":781},[272,11625,2294],{"class":289},[272,11627,2334],{"class":289},[272,11629,11599],{"class":293},[272,11631,2334],{"class":289},[272,11633,7576],{"class":289},[272,11635,11636],{"class":274,"line":345},[272,11637,302],{"emptyLinePlaceholder":169},[272,11639,11640,11642,11645,11647,11649,11651,11654,11656,11658,11660,11662,11665,11667,11670,11672,11674,11677,11679],{"class":274,"line":363},[272,11641,6139],{"class":289},[272,11643,11644],{"class":366},"down-arrow",[272,11646,9493],{"class":781},[272,11648,2294],{"class":289},[272,11650,2334],{"class":289},[272,11652,11653],{"class":293},"expandable",[272,11655,2334],{"class":289},[272,11657,4141],{"class":781},[272,11659,2294],{"class":289},[272,11661,2334],{"class":289},[272,11663,11664],{"class":293},"icon",[272,11666,2334],{"class":289},[272,11668,11669],{"class":781}," :class",[272,11671,2294],{"class":289},[272,11673,2334],{"class":289},[272,11675,11676],{"class":293},"{ rotate: expanded }",[272,11678,2334],{"class":289},[272,11680,7576],{"class":289},[272,11682,11683,11685,11687],{"class":274,"line":376},[272,11684,6162],{"class":289},[272,11686,4138],{"class":366},[272,11688,4038],{"class":289},[272,11690,11691],{"class":274,"line":390},[272,11692,302],{"emptyLinePlaceholder":169},[272,11694,11695,11697,11699,11701,11703,11705,11708,11710,11713,11715,11717,11720,11722,11725,11727,11729,11732,11734,11737,11739,11741,11744,11746,11749,11751,11753,11756,11758],{"class":274,"line":409},[272,11696,4157],{"class":289},[272,11698,9471],{"class":366},[272,11700,9474],{"class":781},[272,11702,2294],{"class":289},[272,11704,2334],{"class":289},[272,11706,11707],{"class":293},"accordion",[272,11709,2334],{"class":289},[272,11711,11712],{"class":781}," @before-enter",[272,11714,2294],{"class":289},[272,11716,2334],{"class":289},[272,11718,11719],{"class":293},"beforeEnter",[272,11721,2334],{"class":289},[272,11723,11724],{"class":781}," @enter",[272,11726,2294],{"class":289},[272,11728,2334],{"class":289},[272,11730,11731],{"class":293},"enter",[272,11733,2334],{"class":289},[272,11735,11736],{"class":781}," @before-leave",[272,11738,2294],{"class":289},[272,11740,2334],{"class":289},[272,11742,11743],{"class":293},"beforeLeave",[272,11745,2334],{"class":289},[272,11747,11748],{"class":781}," @leave",[272,11750,2294],{"class":289},[272,11752,2334],{"class":289},[272,11754,11755],{"class":293},"leave",[272,11757,2334],{"class":289},[272,11759,4038],{"class":289},[272,11761,11762,11764,11766,11768,11770,11772,11775,11777,11779,11781,11783,11785,11787,11789,11791,11793,11795,11797],{"class":274,"line":419},[272,11763,6139],{"class":289},[272,11765,4138],{"class":366},[272,11767,9493],{"class":781},[272,11769,2294],{"class":289},[272,11771,2334],{"class":289},[272,11773,11774],{"class":293},"expanded",[272,11776,2334],{"class":289},[272,11778,4047],{"class":781},[272,11780,2294],{"class":289},[272,11782,2334],{"class":289},[272,11784,696],{"class":293},[272,11786,2334],{"class":289},[272,11788,4141],{"class":781},[272,11790,2294],{"class":289},[272,11792,2334],{"class":289},[272,11794,696],{"class":293},[272,11796,2334],{"class":289},[272,11798,4038],{"class":289},[272,11800,11801,11803,11805,11807,11809,11811,11813,11815],{"class":274,"line":449},[272,11802,9530],{"class":289},[272,11804,11621],{"class":366},[272,11806,9474],{"class":781},[272,11808,2294],{"class":289},[272,11810,2334],{"class":289},[272,11812,696],{"class":293},[272,11814,2334],{"class":289},[272,11816,7576],{"class":289},[272,11818,11819,11821,11823],{"class":274,"line":466},[272,11820,6153],{"class":289},[272,11822,4138],{"class":366},[272,11824,4038],{"class":289},[272,11826,11827,11829,11831],{"class":274,"line":472},[272,11828,6162],{"class":289},[272,11830,9471],{"class":366},[272,11832,4038],{"class":289},[272,11834,11835,11837,11839],{"class":274,"line":491},[272,11836,4175],{"class":289},[272,11838,4138],{"class":366},[272,11840,4038],{"class":289},[272,11842,11843,11845,11847],{"class":274,"line":511},[272,11844,4113],{"class":289},[272,11846,4128],{"class":366},[272,11848,4038],{"class":289},[272,11850,11851],{"class":274,"line":529},[272,11852,302],{"emptyLinePlaceholder":169},[272,11854,11855,11857,11859,11861,11863,11865,11867,11869],{"class":274,"line":547},[272,11856,3081],{"class":289},[272,11858,4021],{"class":366},[272,11860,4024],{"class":781},[272,11862,2294],{"class":289},[272,11864,2334],{"class":289},[272,11866,268],{"class":293},[272,11868,2334],{"class":289},[272,11870,4038],{"class":289},[272,11872,11873,11875,11877,11879,11881,11883],{"class":274,"line":565},[272,11874,279],{"class":278},[272,11876,9880],{"class":282},[272,11878,286],{"class":278},[272,11880,290],{"class":289},[272,11882,4012],{"class":293},[272,11884,297],{"class":289},[272,11886,11887],{"class":274,"line":592},[272,11888,302],{"emptyLinePlaceholder":169},[272,11890,11891,11893,11896,11898,11900,11903],{"class":274,"line":611},[272,11892,279],{"class":278},[272,11894,11895],{"class":282}," DownArrow ",[272,11897,286],{"class":278},[272,11899,290],{"class":289},[272,11901,11902],{"class":293},"~\u002Fassets\u002Ffonts\u002Fdown-arrow.svg?inline",[272,11904,297],{"class":289},[272,11906,11907],{"class":274,"line":629},[272,11908,302],{"emptyLinePlaceholder":169},[272,11910,11911,11913,11915,11917,11919,11921,11923],{"class":274,"line":648},[272,11912,348],{"class":278},[272,11914,351],{"class":278},[272,11916,9901],{"class":282},[272,11918,430],{"class":289},[272,11920,9906],{"class":354},[272,11922,357],{"class":282},[272,11924,360],{"class":289},[272,11926,11927,11929,11931],{"class":274,"line":658},[272,11928,10949],{"class":366},[272,11930,370],{"class":289},[272,11932,373],{"class":289},[272,11934,11935,11938],{"class":274,"line":668},[272,11936,11937],{"class":282},"    DownArrow",[272,11939,406],{"class":289},[272,11941,11942],{"class":274,"line":674},[272,11943,671],{"class":289},[272,11945,11946],{"class":274,"line":1161},[272,11947,302],{"emptyLinePlaceholder":169},[272,11949,11950,11952,11954],{"class":274,"line":1169},[272,11951,9915],{"class":366},[272,11953,370],{"class":289},[272,11955,373],{"class":289},[272,11957,11958,11960,11962,11964,11966,11968],{"class":274,"line":1177},[272,11959,9924],{"class":366},[272,11961,370],{"class":289},[272,11963,290],{"class":289},[272,11965,11774],{"class":293},[272,11967,403],{"class":289},[272,11969,406],{"class":289},[272,11971,11972,11974,11976,11978,11981,11983],{"class":274,"line":1184},[272,11973,9939],{"class":366},[272,11975,370],{"class":289},[272,11977,290],{"class":289},[272,11979,11980],{"class":293},"expand",[272,11982,403],{"class":289},[272,11984,406],{"class":289},[272,11986,11987],{"class":274,"line":1192},[272,11988,671],{"class":289},[272,11990,11991],{"class":274,"line":1200},[272,11992,302],{"emptyLinePlaceholder":169},[272,11994,11995,11997,11999],{"class":274,"line":1208},[272,11996,9962],{"class":366},[272,11998,370],{"class":289},[272,12000,373],{"class":289},[272,12002,12003,12006,12008],{"class":274,"line":1216},[272,12004,12005],{"class":366},"    expanded",[272,12007,370],{"class":289},[272,12009,373],{"class":289},[272,12011,12012,12014,12016,12018],{"class":274,"line":1221},[272,12013,393],{"class":366},[272,12015,370],{"class":289},[272,12017,9984],{"class":282},[272,12019,406],{"class":289},[272,12021,12022,12024,12026,12028],{"class":274,"line":1229},[272,12023,9991],{"class":366},[272,12025,370],{"class":289},[272,12027,3513],{"class":2762},[272,12029,406],{"class":289},[272,12031,12032],{"class":274,"line":1237},[272,12033,1140],{"class":289},[272,12035,12036],{"class":274,"line":1245},[272,12037,302],{"emptyLinePlaceholder":169},[272,12039,12040,12043,12045],{"class":274,"line":1253},[272,12041,12042],{"class":366},"    expandable",[272,12044,370],{"class":289},[272,12046,373],{"class":289},[272,12048,12049,12051,12053,12055],{"class":274,"line":1261},[272,12050,393],{"class":366},[272,12052,370],{"class":289},[272,12054,9984],{"class":282},[272,12056,406],{"class":289},[272,12058,12059,12061,12063,12065],{"class":274,"line":1269},[272,12060,9991],{"class":366},[272,12062,370],{"class":289},[272,12064,3513],{"class":2762},[272,12066,406],{"class":289},[272,12068,12069],{"class":274,"line":1277},[272,12070,1140],{"class":289},[272,12072,12073],{"class":274,"line":1285},[272,12074,671],{"class":289},[272,12076,12077],{"class":274,"line":1293},[272,12078,302],{"emptyLinePlaceholder":169},[272,12080,12081,12084,12086],{"class":274,"line":1301},[272,12082,12083],{"class":366},"  mounted",[272,12085,506],{"class":289},[272,12087,373],{"class":289},[272,12089,12090,12093,12095,12098,12101,12103,12105,12107],{"class":274,"line":1309},[272,12091,12092],{"class":278},"    if",[272,12094,2493],{"class":366},[272,12096,12097],{"class":289},"this.",[272,12099,12100],{"class":282},"$refs",[272,12102,430],{"class":289},[272,12104,696],{"class":282},[272,12106,2317],{"class":366},[272,12108,360],{"class":289},[272,12110,12111,12114,12116,12118,12120,12122,12124,12127,12129,12131,12133,12135,12137,12139,12142,12144,12146,12148,12150,12152,12155,12157,12160],{"class":274,"line":1317},[272,12112,12113],{"class":366},"      (",[272,12115,12097],{"class":289},[272,12117,12100],{"class":282},[272,12119,430],{"class":289},[272,12121,696],{"class":282},[272,12123,3432],{"class":278},[272,12125,12126],{"class":801}," HTMLElement",[272,12128,188],{"class":366},[272,12130,430],{"class":289},[272,12132,2211],{"class":282},[272,12134,430],{"class":289},[272,12136,11537],{"class":282},[272,12138,3127],{"class":289},[272,12140,12141],{"class":289}," `${",[272,12143,12097],{"class":289},[272,12145,12100],{"class":282},[272,12147,430],{"class":289},[272,12149,696],{"class":282},[272,12151,430],{"class":289},[272,12153,12154],{"class":282},"clientHeight",[272,12156,677],{"class":289},[272,12158,12159],{"class":293},"px",[272,12161,12162],{"class":289},"`\n",[272,12164,12165],{"class":274,"line":1325},[272,12166,6018],{"class":289},[272,12168,12169],{"class":274,"line":1333},[272,12170,671],{"class":289},[272,12172,12173],{"class":274,"line":1341},[272,12174,302],{"emptyLinePlaceholder":169},[272,12176,12177,12179,12181],{"class":274,"line":1349},[272,12178,10014],{"class":366},[272,12180,370],{"class":289},[272,12182,373],{"class":289},[272,12184,12185,12188,12190,12193,12195,12197,12199],{"class":274,"line":1357},[272,12186,12187],{"class":366},"    beforeEnter",[272,12189,357],{"class":289},[272,12191,12192],{"class":2496},"el",[272,12194,370],{"class":289},[272,12196,12126],{"class":801},[272,12198,188],{"class":289},[272,12200,373],{"class":289},[272,12202,12203,12206,12208,12210,12212,12214,12216,12218,12220],{"class":274,"line":1365},[272,12204,12205],{"class":282},"      el",[272,12207,430],{"class":289},[272,12209,2211],{"class":282},[272,12211,430],{"class":289},[272,12213,11537],{"class":282},[272,12215,3127],{"class":289},[272,12217,290],{"class":289},[272,12219,3374],{"class":293},[272,12221,297],{"class":289},[272,12223,12224],{"class":274,"line":1373},[272,12225,1140],{"class":289},[272,12227,12228],{"class":274,"line":1381},[272,12229,302],{"emptyLinePlaceholder":169},[272,12231,12232,12235,12237,12239,12241,12243,12245],{"class":274,"line":1389},[272,12233,12234],{"class":366},"    enter",[272,12236,357],{"class":289},[272,12238,12192],{"class":2496},[272,12240,370],{"class":289},[272,12242,12126],{"class":801},[272,12244,188],{"class":289},[272,12246,373],{"class":289},[272,12248,12249,12251,12253,12255,12257,12259,12261,12264,12266,12268,12271,12273,12275],{"class":274,"line":1397},[272,12250,12205],{"class":282},[272,12252,430],{"class":289},[272,12254,2211],{"class":282},[272,12256,430],{"class":289},[272,12258,11537],{"class":282},[272,12260,3127],{"class":289},[272,12262,12263],{"class":282}," el",[272,12265,430],{"class":289},[272,12267,11489],{"class":282},[272,12269,12270],{"class":289}," +",[272,12272,290],{"class":289},[272,12274,12159],{"class":293},[272,12276,297],{"class":289},[272,12278,12279],{"class":274,"line":1404},[272,12280,1140],{"class":289},[272,12282,12283],{"class":274,"line":1412},[272,12284,302],{"emptyLinePlaceholder":169},[272,12286,12287,12290,12292,12294,12296,12298,12300],{"class":274,"line":1420},[272,12288,12289],{"class":366},"    beforeLeave",[272,12291,357],{"class":289},[272,12293,12192],{"class":2496},[272,12295,370],{"class":289},[272,12297,12126],{"class":801},[272,12299,188],{"class":289},[272,12301,373],{"class":289},[272,12303,12304,12306,12308,12310,12312,12314,12316,12318,12320,12322,12324,12326,12328],{"class":274,"line":1428},[272,12305,12205],{"class":282},[272,12307,430],{"class":289},[272,12309,2211],{"class":282},[272,12311,430],{"class":289},[272,12313,11537],{"class":282},[272,12315,3127],{"class":289},[272,12317,12263],{"class":282},[272,12319,430],{"class":289},[272,12321,11489],{"class":282},[272,12323,12270],{"class":289},[272,12325,290],{"class":289},[272,12327,12159],{"class":293},[272,12329,297],{"class":289},[272,12331,12332],{"class":274,"line":1436},[272,12333,1140],{"class":289},[272,12335,12336],{"class":274,"line":1444},[272,12337,302],{"emptyLinePlaceholder":169},[272,12339,12340,12343,12345,12347,12349,12351,12353],{"class":274,"line":1452},[272,12341,12342],{"class":366},"    leave",[272,12344,357],{"class":289},[272,12346,12192],{"class":2496},[272,12348,370],{"class":289},[272,12350,12126],{"class":801},[272,12352,188],{"class":289},[272,12354,373],{"class":289},[272,12356,12357,12359,12361,12363,12365,12367,12369,12371,12373],{"class":274,"line":1460},[272,12358,12205],{"class":282},[272,12360,430],{"class":289},[272,12362,2211],{"class":282},[272,12364,430],{"class":289},[272,12366,11537],{"class":282},[272,12368,3127],{"class":289},[272,12370,290],{"class":289},[272,12372,3374],{"class":293},[272,12374,297],{"class":289},[272,12376,12377],{"class":274,"line":1468},[272,12378,1140],{"class":289},[272,12380,12381],{"class":274,"line":1476},[272,12382,671],{"class":289},[272,12384,12385,12387],{"class":274,"line":1484},[272,12386,677],{"class":289},[272,12388,680],{"class":282},[272,12390,12391,12393,12395],{"class":274,"line":1492},[272,12392,4113],{"class":289},[272,12394,4021],{"class":366},[272,12396,4038],{"class":289},[272,12398,12399],{"class":274,"line":1500},[272,12400,302],{"emptyLinePlaceholder":169},[272,12402,12403,12405,12407,12409,12411,12413,12415,12417,12419],{"class":274,"line":1508},[272,12404,3081],{"class":289},[272,12406,2211],{"class":366},[272,12408,4024],{"class":781},[272,12410,2294],{"class":289},[272,12412,2334],{"class":289},[272,12414,4206],{"class":293},[272,12416,2334],{"class":289},[272,12418,4211],{"class":781},[272,12420,4038],{"class":289},[272,12422,12423],{"class":274,"line":1516},[272,12424,12425],{"class":282},".ume-accordion {\n",[272,12427,12428],{"class":274,"line":1524},[272,12429,12430],{"class":282},"  border-radius: 6px;\n",[272,12432,12433],{"class":274,"line":1532},[272,12434,12435],{"class":282},"  padding-top: 16px;\n",[272,12437,12438],{"class":274,"line":1540},[272,12439,302],{"emptyLinePlaceholder":169},[272,12441,12442],{"class":274,"line":1548},[272,12443,12444],{"class":282},"  .header {\n",[272,12446,12447],{"class":274,"line":1556},[272,12448,12449],{"class":282},"    color: #fff;\n",[272,12451,12452],{"class":274,"line":1564},[272,12453,11280],{"class":282},[272,12455,12456],{"class":274,"line":1572},[272,12457,12458],{"class":282},"    align-items: center;\n",[272,12460,12461],{"class":274,"line":1580},[272,12462,12463],{"class":282},"    justify-content: space-between;\n",[272,12465,12466],{"class":274,"line":1588},[272,12467,12468],{"class":282},"    line-height: 1;\n",[272,12470,12471],{"class":274,"line":1595},[272,12472,12473],{"class":282},"    padding-bottom: 16px;\n",[272,12475,12476],{"class":274,"line":1602},[272,12477,12478],{"class":282},"    border-bottom: solid 1px #d1d1d6;\n",[272,12480,12481],{"class":274,"line":1608},[272,12482,302],{"emptyLinePlaceholder":169},[272,12484,12485],{"class":274,"line":10233},[272,12486,12487],{"class":282},"    .icon {\n",[272,12489,12490],{"class":274,"line":10239},[272,12491,10410],{"class":282},[272,12493,12494],{"class":274,"line":10245},[272,12495,12496],{"class":282},"      fill: #c7c7cc;\n",[272,12498,12499],{"class":274,"line":10251},[272,12500,12501],{"class":282},"      height: 14px;\n",[272,12503,12504],{"class":274,"line":10256},[272,12505,12506],{"class":282},"      width: 14px;\n",[272,12508,12509],{"class":274,"line":10262},[272,12510,12511],{"class":282},"      transform: rotate(0deg);\n",[272,12513,12514],{"class":274,"line":10268},[272,12515,12516],{"class":282},"      transition-duration: 0.3s;\n",[272,12518,12519],{"class":274,"line":10274},[272,12520,6018],{"class":282},[272,12522,12523],{"class":274,"line":10280},[272,12524,302],{"emptyLinePlaceholder":169},[272,12526,12527],{"class":274,"line":10286},[272,12528,12529],{"class":282},"    .rotate {\n",[272,12531,12532],{"class":274,"line":10292},[272,12533,12534],{"class":282},"      transform: rotate(180deg);\n",[272,12536,12537],{"class":274,"line":10297},[272,12538,12516],{"class":282},[272,12540,12541],{"class":274,"line":10302},[272,12542,6018],{"class":282},[272,12544,12545],{"class":274,"line":10307},[272,12546,909],{"class":282},[272,12548,12549],{"class":274,"line":10313},[272,12550,302],{"emptyLinePlaceholder":169},[272,12552,12553],{"class":274,"line":10318},[272,12554,12555],{"class":282},"  .content {\n",[272,12557,12558],{"class":274,"line":10324},[272,12559,12560],{"class":282},"    padding: 0 12px;\n",[272,12562,12563],{"class":274,"line":10330},[272,12564,12565],{"class":282},"    overflow: hidden;\n",[272,12567,12568],{"class":274,"line":10335},[272,12569,12570],{"class":282},"    transition: 0.2s ease-out;\n",[272,12572,12573],{"class":274,"line":10341},[272,12574,909],{"class":282},[272,12576,12577],{"class":274,"line":10346},[272,12578,965],{"class":282},[272,12580,12581,12583,12585],{"class":274,"line":10351},[272,12582,4113],{"class":289},[272,12584,2211],{"class":366},[272,12586,4038],{"class":289},[15,12588,12589],{},"呼び出し側はこのように書いています。",[264,12591,12594],{"className":4009,"code":12592,"filename":12593,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cume-accordion\n    v-for=\"(group, index) in groups\"\n    :key=\"group.id\"\n    :expanded=\"accordionExpanded[index]\"\n    :expandable=\"group.children.length > 0\"\n    class=\"accordion\"\n    @click-header-arrow=\"toggleExpandAccordion($event, index)\"\n  >\n    \u003Ctemplate v-slot:header>\n      \u003Cp>{{ group.name }}\u003C\u002Fp>\n    \u003C\u002Ftemplate>\n\n    \u003Ctemplate v-slot:content>\n      \u003Cul v-if=\"group.children.length > 0\">\n        \u003Cli v-for=\"groupChild in group.children\" :key=\"`${group.id}-${groupChild.id}`\">\n          \u003Cdiv class=\"child-img\">\n            \u003Cimg :src=\"groupChild.src\" \u002F>\n          \u003C\u002Fdiv>\n        \u003C\u002Fli>\n      \u003C\u002Ful>\n    \u003C\u002Ftemplate>\n  \u003C\u002Fume-accordion>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue from 'vue'\n\nimport { ImageGroup } from '~\u002Ftypes\u002Fimage'\n\ntype Data = {\n  groups: ImageGroup[]\n  accordionExpanded: boolean[]\n}\n\nexport default Vue.extend({\n  data(): Data {\n    const groups = [\n      {\n        id: 1,\n        name: 'scenes',\n        children: [\n          { id: 1015, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F1015\u002F200\u002F300' },\n          { id: 1016, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F1016\u002F200\u002F300' },\n          { id: 1018, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F1018\u002F200\u002F300' },\n          { id: 1019, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F1019\u002F200\u002F300' },\n          { id: 102, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F102\u002F200\u002F300' },\n        ],\n      },\n      {\n        id: 2,\n        name: 'scenes',\n        children: [\n          { id: 244, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F244\u002F200\u002F300' },\n          { id: 237, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F237\u002F200\u002F300' },\n          { id: 200, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F200\u002F200\u002F300' },\n          { id: 219, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F219\u002F200\u002F300' },\n          { id: 169, src: 'https:\u002F\u002Fpicsum.photos\u002Fid\u002F169\u002F200\u002F300' },\n        ],\n      },\n    ]\n\n    return {\n      groups,\n      accordionExpanded: [true, ...groups.slice(1, groups.length).map(() => false)],\n    }\n  },\n\n  computed: {\n    accordionClass() {\n      return (opened: boolean) => {\n        return opened ? 'opened' : ''\n      }\n    },\n  },\n\n  methods: {\n    toggleExpandAccordion(expanded: boolean, ingredientCategoryIndex: number) {\n      this.accordionExpanded = this.accordionExpanded.map((_) => false)\n      this.accordionExpanded[ingredientCategoryIndex] = expanded\n    },\n  },\n})\n\u003C\u002Fscript>\n","pages\u002Faccordion.vue",[203,12595,12596,12604,12611,12625,12639,12653,12667,12680,12694,12698,12713,12730,12738,12742,12756,12774,12806,12825,12845,12853,12861,12869,12877,12885,12893,12897,12915,12929,12933,12953,12957,12968,12980,12991,12995,12999,13015,13027,13038,13042,13054,13070,13079,13107,13133,13159,13185,13211,13218,13222,13226,13237,13251,13259,13285,13311,13337,13363,13389,13395,13399,13404,13408,13414,13421,13479,13483,13487,13491,13500,13509,13528,13548,13552,13556,13560,13564,13572,13598,13631,13650,13654,13658,13664],{"__ignoreMap":154},[272,12597,12598,12600,12602],{"class":274,"line":275},[272,12599,3081],{"class":289},[272,12601,4128],{"class":366},[272,12603,4038],{"class":289},[272,12605,12606,12608],{"class":274,"line":155},[272,12607,4135],{"class":289},[272,12609,12610],{"class":366},"ume-accordion\n",[272,12612,12613,12616,12618,12620,12623],{"class":274,"line":305},[272,12614,12615],{"class":781},"    v-for",[272,12617,2294],{"class":289},[272,12619,2334],{"class":289},[272,12621,12622],{"class":293},"(group, index) in groups",[272,12624,6108],{"class":289},[272,12626,12627,12630,12632,12634,12637],{"class":274,"line":340},[272,12628,12629],{"class":781},"    :key",[272,12631,2294],{"class":289},[272,12633,2334],{"class":289},[272,12635,12636],{"class":293},"group.id",[272,12638,6108],{"class":289},[272,12640,12641,12644,12646,12648,12651],{"class":274,"line":345},[272,12642,12643],{"class":781},"    :expanded",[272,12645,2294],{"class":289},[272,12647,2334],{"class":289},[272,12649,12650],{"class":293},"accordionExpanded[index]",[272,12652,6108],{"class":289},[272,12654,12655,12658,12660,12662,12665],{"class":274,"line":363},[272,12656,12657],{"class":781},"    :expandable",[272,12659,2294],{"class":289},[272,12661,2334],{"class":289},[272,12663,12664],{"class":293},"group.children.length > 0",[272,12666,6108],{"class":289},[272,12668,12669,12672,12674,12676,12678],{"class":274,"line":376},[272,12670,12671],{"class":781},"    class",[272,12673,2294],{"class":289},[272,12675,2334],{"class":289},[272,12677,11707],{"class":293},[272,12679,6108],{"class":289},[272,12681,12682,12685,12687,12689,12692],{"class":274,"line":390},[272,12683,12684],{"class":781},"    @click-header-arrow",[272,12686,2294],{"class":289},[272,12688,2334],{"class":289},[272,12690,12691],{"class":293},"toggleExpandAccordion($event, index)",[272,12693,6108],{"class":289},[272,12695,12696],{"class":274,"line":409},[272,12697,6126],{"class":289},[272,12699,12700,12702,12704,12707,12709,12711],{"class":274,"line":419},[272,12701,4157],{"class":289},[272,12703,4128],{"class":366},[272,12705,12706],{"class":781}," v-slot",[272,12708,370],{"class":289},[272,12710,11599],{"class":781},[272,12712,4038],{"class":289},[272,12714,12715,12717,12719,12721,12724,12726,12728],{"class":274,"line":449},[272,12716,6139],{"class":289},[272,12718,15],{"class":366},[272,12720,2311],{"class":289},[272,12722,12723],{"class":282},"{{ group.name }}",[272,12725,4113],{"class":289},[272,12727,15],{"class":366},[272,12729,4038],{"class":289},[272,12731,12732,12734,12736],{"class":274,"line":466},[272,12733,6162],{"class":289},[272,12735,4128],{"class":366},[272,12737,4038],{"class":289},[272,12739,12740],{"class":274,"line":472},[272,12741,302],{"emptyLinePlaceholder":169},[272,12743,12744,12746,12748,12750,12752,12754],{"class":274,"line":491},[272,12745,4157],{"class":289},[272,12747,4128],{"class":366},[272,12749,12706],{"class":781},[272,12751,370],{"class":289},[272,12753,696],{"class":781},[272,12755,4038],{"class":289},[272,12757,12758,12760,12762,12764,12766,12768,12770,12772],{"class":274,"line":511},[272,12759,6139],{"class":289},[272,12761,35],{"class":366},[272,12763,9493],{"class":781},[272,12765,2294],{"class":289},[272,12767,2334],{"class":289},[272,12769,12664],{"class":293},[272,12771,2334],{"class":289},[272,12773,4038],{"class":289},[272,12775,12776,12778,12780,12783,12785,12787,12790,12792,12795,12797,12799,12802,12804],{"class":274,"line":529},[272,12777,9530],{"class":289},[272,12779,38],{"class":366},[272,12781,12782],{"class":781}," v-for",[272,12784,2294],{"class":289},[272,12786,2334],{"class":289},[272,12788,12789],{"class":293},"groupChild in group.children",[272,12791,2334],{"class":289},[272,12793,12794],{"class":781}," :key",[272,12796,2294],{"class":289},[272,12798,2334],{"class":289},[272,12800,12801],{"class":293},"`${group.id}-${groupChild.id}`",[272,12803,2334],{"class":289},[272,12805,4038],{"class":289},[272,12807,12808,12810,12812,12814,12816,12818,12821,12823],{"class":274,"line":547},[272,12809,9644],{"class":289},[272,12811,4138],{"class":366},[272,12813,4141],{"class":781},[272,12815,2294],{"class":289},[272,12817,2334],{"class":289},[272,12819,12820],{"class":293},"child-img",[272,12822,2334],{"class":289},[272,12824,4038],{"class":289},[272,12826,12827,12829,12831,12834,12836,12838,12841,12843],{"class":274,"line":565},[272,12828,9674],{"class":289},[272,12830,21],{"class":366},[272,12832,12833],{"class":781}," :src",[272,12835,2294],{"class":289},[272,12837,2334],{"class":289},[272,12839,12840],{"class":293},"groupChild.src",[272,12842,2334],{"class":289},[272,12844,7576],{"class":289},[272,12846,12847,12849,12851],{"class":274,"line":592},[272,12848,9692],{"class":289},[272,12850,4138],{"class":366},[272,12852,4038],{"class":289},[272,12854,12855,12857,12859],{"class":274,"line":611},[272,12856,9815],{"class":289},[272,12858,38],{"class":366},[272,12860,4038],{"class":289},[272,12862,12863,12865,12867],{"class":274,"line":629},[272,12864,6153],{"class":289},[272,12866,35],{"class":366},[272,12868,4038],{"class":289},[272,12870,12871,12873,12875],{"class":274,"line":648},[272,12872,6162],{"class":289},[272,12874,4128],{"class":366},[272,12876,4038],{"class":289},[272,12878,12879,12881,12883],{"class":274,"line":658},[272,12880,4175],{"class":289},[272,12882,11580],{"class":366},[272,12884,4038],{"class":289},[272,12886,12887,12889,12891],{"class":274,"line":668},[272,12888,4113],{"class":289},[272,12890,4128],{"class":366},[272,12892,4038],{"class":289},[272,12894,12895],{"class":274,"line":674},[272,12896,302],{"emptyLinePlaceholder":169},[272,12898,12899,12901,12903,12905,12907,12909,12911,12913],{"class":274,"line":1161},[272,12900,3081],{"class":289},[272,12902,4021],{"class":366},[272,12904,4024],{"class":781},[272,12906,2294],{"class":289},[272,12908,2334],{"class":289},[272,12910,268],{"class":293},[272,12912,2334],{"class":289},[272,12914,4038],{"class":289},[272,12916,12917,12919,12921,12923,12925,12927],{"class":274,"line":1169},[272,12918,279],{"class":278},[272,12920,9880],{"class":282},[272,12922,286],{"class":278},[272,12924,290],{"class":289},[272,12926,4012],{"class":293},[272,12928,297],{"class":289},[272,12930,12931],{"class":274,"line":1177},[272,12932,302],{"emptyLinePlaceholder":169},[272,12934,12935,12937,12939,12942,12944,12946,12948,12951],{"class":274,"line":1184},[272,12936,279],{"class":278},[272,12938,310],{"class":289},[272,12940,12941],{"class":282}," ImageGroup",[272,12943,327],{"class":289},[272,12945,330],{"class":278},[272,12947,290],{"class":289},[272,12949,12950],{"class":293},"~\u002Ftypes\u002Fimage",[272,12952,297],{"class":289},[272,12954,12955],{"class":274,"line":1192},[272,12956,302],{"emptyLinePlaceholder":169},[272,12958,12959,12961,12964,12966],{"class":274,"line":1200},[272,12960,2543],{"class":781},[272,12962,12963],{"class":801}," Data",[272,12965,3127],{"class":289},[272,12967,373],{"class":289},[272,12969,12970,12973,12975,12977],{"class":274,"line":1208},[272,12971,12972],{"class":366},"  groups",[272,12974,370],{"class":289},[272,12976,12941],{"class":801},[272,12978,12979],{"class":282},"[]\n",[272,12981,12982,12985,12987,12989],{"class":274,"line":1216},[272,12983,12984],{"class":366},"  accordionExpanded",[272,12986,370],{"class":289},[272,12988,879],{"class":801},[272,12990,12979],{"class":282},[272,12992,12993],{"class":274,"line":1221},[272,12994,965],{"class":289},[272,12996,12997],{"class":274,"line":1229},[272,12998,302],{"emptyLinePlaceholder":169},[272,13000,13001,13003,13005,13007,13009,13011,13013],{"class":274,"line":1237},[272,13002,348],{"class":278},[272,13004,351],{"class":278},[272,13006,9901],{"class":282},[272,13008,430],{"class":289},[272,13010,9906],{"class":354},[272,13012,357],{"class":282},[272,13014,360],{"class":289},[272,13016,13017,13020,13023,13025],{"class":274,"line":1245},[272,13018,13019],{"class":366},"  data",[272,13021,13022],{"class":289},"():",[272,13024,12963],{"class":801},[272,13026,373],{"class":289},[272,13028,13029,13031,13034,13036],{"class":274,"line":1253},[272,13030,3121],{"class":781},[272,13032,13033],{"class":282}," groups",[272,13035,3127],{"class":289},[272,13037,9078],{"class":366},[272,13039,13040],{"class":274,"line":1261},[272,13041,5791],{"class":289},[272,13043,13044,13047,13049,13052],{"class":274,"line":1269},[272,13045,13046],{"class":366},"        id",[272,13048,370],{"class":289},[272,13050,13051],{"class":2297}," 1",[272,13053,406],{"class":289},[272,13055,13056,13059,13061,13063,13066,13068],{"class":274,"line":1277},[272,13057,13058],{"class":366},"        name",[272,13060,370],{"class":289},[272,13062,290],{"class":289},[272,13064,13065],{"class":293},"scenes",[272,13067,403],{"class":289},[272,13069,406],{"class":289},[272,13071,13072,13075,13077],{"class":274,"line":1285},[272,13073,13074],{"class":366},"        children",[272,13076,370],{"class":289},[272,13078,9078],{"class":366},[272,13080,13081,13084,13087,13089,13092,13094,13096,13098,13100,13103,13105],{"class":274,"line":1293},[272,13082,13083],{"class":289},"          {",[272,13085,13086],{"class":366}," id",[272,13088,370],{"class":289},[272,13090,13091],{"class":2297}," 1015",[272,13093,316],{"class":289},[272,13095,10817],{"class":366},[272,13097,370],{"class":289},[272,13099,290],{"class":289},[272,13101,13102],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F1015\u002F200\u002F300",[272,13104,403],{"class":289},[272,13106,6958],{"class":289},[272,13108,13109,13111,13113,13115,13118,13120,13122,13124,13126,13129,13131],{"class":274,"line":1301},[272,13110,13083],{"class":289},[272,13112,13086],{"class":366},[272,13114,370],{"class":289},[272,13116,13117],{"class":2297}," 1016",[272,13119,316],{"class":289},[272,13121,10817],{"class":366},[272,13123,370],{"class":289},[272,13125,290],{"class":289},[272,13127,13128],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F1016\u002F200\u002F300",[272,13130,403],{"class":289},[272,13132,6958],{"class":289},[272,13134,13135,13137,13139,13141,13144,13146,13148,13150,13152,13155,13157],{"class":274,"line":1309},[272,13136,13083],{"class":289},[272,13138,13086],{"class":366},[272,13140,370],{"class":289},[272,13142,13143],{"class":2297}," 1018",[272,13145,316],{"class":289},[272,13147,10817],{"class":366},[272,13149,370],{"class":289},[272,13151,290],{"class":289},[272,13153,13154],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F1018\u002F200\u002F300",[272,13156,403],{"class":289},[272,13158,6958],{"class":289},[272,13160,13161,13163,13165,13167,13170,13172,13174,13176,13178,13181,13183],{"class":274,"line":1317},[272,13162,13083],{"class":289},[272,13164,13086],{"class":366},[272,13166,370],{"class":289},[272,13168,13169],{"class":2297}," 1019",[272,13171,316],{"class":289},[272,13173,10817],{"class":366},[272,13175,370],{"class":289},[272,13177,290],{"class":289},[272,13179,13180],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F1019\u002F200\u002F300",[272,13182,403],{"class":289},[272,13184,6958],{"class":289},[272,13186,13187,13189,13191,13193,13196,13198,13200,13202,13204,13207,13209],{"class":274,"line":1325},[272,13188,13083],{"class":289},[272,13190,13086],{"class":366},[272,13192,370],{"class":289},[272,13194,13195],{"class":2297}," 102",[272,13197,316],{"class":289},[272,13199,10817],{"class":366},[272,13201,370],{"class":289},[272,13203,290],{"class":289},[272,13205,13206],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F102\u002F200\u002F300",[272,13208,403],{"class":289},[272,13210,6958],{"class":289},[272,13212,13213,13216],{"class":274,"line":1333},[272,13214,13215],{"class":366},"        ]",[272,13217,406],{"class":289},[272,13219,13220],{"class":274,"line":1341},[272,13221,469],{"class":289},[272,13223,13224],{"class":274,"line":1349},[272,13225,5791],{"class":289},[272,13227,13228,13230,13232,13235],{"class":274,"line":1357},[272,13229,13046],{"class":366},[272,13231,370],{"class":289},[272,13233,13234],{"class":2297}," 2",[272,13236,406],{"class":289},[272,13238,13239,13241,13243,13245,13247,13249],{"class":274,"line":1365},[272,13240,13058],{"class":366},[272,13242,370],{"class":289},[272,13244,290],{"class":289},[272,13246,13065],{"class":293},[272,13248,403],{"class":289},[272,13250,406],{"class":289},[272,13252,13253,13255,13257],{"class":274,"line":1373},[272,13254,13074],{"class":366},[272,13256,370],{"class":289},[272,13258,9078],{"class":366},[272,13260,13261,13263,13265,13267,13270,13272,13274,13276,13278,13281,13283],{"class":274,"line":1381},[272,13262,13083],{"class":289},[272,13264,13086],{"class":366},[272,13266,370],{"class":289},[272,13268,13269],{"class":2297}," 244",[272,13271,316],{"class":289},[272,13273,10817],{"class":366},[272,13275,370],{"class":289},[272,13277,290],{"class":289},[272,13279,13280],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F244\u002F200\u002F300",[272,13282,403],{"class":289},[272,13284,6958],{"class":289},[272,13286,13287,13289,13291,13293,13296,13298,13300,13302,13304,13307,13309],{"class":274,"line":1389},[272,13288,13083],{"class":289},[272,13290,13086],{"class":366},[272,13292,370],{"class":289},[272,13294,13295],{"class":2297}," 237",[272,13297,316],{"class":289},[272,13299,10817],{"class":366},[272,13301,370],{"class":289},[272,13303,290],{"class":289},[272,13305,13306],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F237\u002F200\u002F300",[272,13308,403],{"class":289},[272,13310,6958],{"class":289},[272,13312,13313,13315,13317,13319,13322,13324,13326,13328,13330,13333,13335],{"class":274,"line":1397},[272,13314,13083],{"class":289},[272,13316,13086],{"class":366},[272,13318,370],{"class":289},[272,13320,13321],{"class":2297}," 200",[272,13323,316],{"class":289},[272,13325,10817],{"class":366},[272,13327,370],{"class":289},[272,13329,290],{"class":289},[272,13331,13332],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F200\u002F200\u002F300",[272,13334,403],{"class":289},[272,13336,6958],{"class":289},[272,13338,13339,13341,13343,13345,13348,13350,13352,13354,13356,13359,13361],{"class":274,"line":1404},[272,13340,13083],{"class":289},[272,13342,13086],{"class":366},[272,13344,370],{"class":289},[272,13346,13347],{"class":2297}," 219",[272,13349,316],{"class":289},[272,13351,10817],{"class":366},[272,13353,370],{"class":289},[272,13355,290],{"class":289},[272,13357,13358],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F219\u002F200\u002F300",[272,13360,403],{"class":289},[272,13362,6958],{"class":289},[272,13364,13365,13367,13369,13371,13374,13376,13378,13380,13382,13385,13387],{"class":274,"line":1412},[272,13366,13083],{"class":289},[272,13368,13086],{"class":366},[272,13370,370],{"class":289},[272,13372,13373],{"class":2297}," 169",[272,13375,316],{"class":289},[272,13377,10817],{"class":366},[272,13379,370],{"class":289},[272,13381,290],{"class":289},[272,13383,13384],{"class":293},"https:\u002F\u002Fpicsum.photos\u002Fid\u002F169\u002F200\u002F300",[272,13386,403],{"class":289},[272,13388,6958],{"class":289},[272,13390,13391,13393],{"class":274,"line":1420},[272,13392,13215],{"class":366},[272,13394,406],{"class":289},[272,13396,13397],{"class":274,"line":1428},[272,13398,469],{"class":289},[272,13400,13401],{"class":274,"line":1436},[272,13402,13403],{"class":366},"    ]\n",[272,13405,13406],{"class":274,"line":1444},[272,13407,302],{"emptyLinePlaceholder":169},[272,13409,13410,13412],{"class":274,"line":1452},[272,13411,3256],{"class":278},[272,13413,373],{"class":289},[272,13415,13416,13419],{"class":274,"line":1460},[272,13417,13418],{"class":282},"      groups",[272,13420,406],{"class":289},[272,13422,13423,13426,13428,13430,13432,13434,13437,13440,13442,13445,13447,13449,13451,13453,13455,13458,13460,13462,13465,13467,13469,13471,13474,13477],{"class":274,"line":1468},[272,13424,13425],{"class":366},"      accordionExpanded",[272,13427,370],{"class":289},[272,13429,3313],{"class":366},[272,13431,9313],{"class":2762},[272,13433,316],{"class":289},[272,13435,13436],{"class":289}," ...",[272,13438,13439],{"class":282},"groups",[272,13441,430],{"class":289},[272,13443,13444],{"class":354},"slice",[272,13446,357],{"class":366},[272,13448,4805],{"class":2297},[272,13450,316],{"class":289},[272,13452,13033],{"class":282},[272,13454,430],{"class":289},[272,13456,13457],{"class":282},"length",[272,13459,188],{"class":366},[272,13461,430],{"class":289},[272,13463,13464],{"class":354},"map",[272,13466,357],{"class":366},[272,13468,506],{"class":289},[272,13470,3089],{"class":781},[272,13472,13473],{"class":2762}," false",[272,13475,13476],{"class":366},")]",[272,13478,406],{"class":289},[272,13480,13481],{"class":274,"line":1476},[272,13482,6018],{"class":289},[272,13484,13485],{"class":274,"line":1484},[272,13486,671],{"class":289},[272,13488,13489],{"class":274,"line":1492},[272,13490,302],{"emptyLinePlaceholder":169},[272,13492,13493,13496,13498],{"class":274,"line":1500},[272,13494,13495],{"class":366},"  computed",[272,13497,370],{"class":289},[272,13499,373],{"class":289},[272,13501,13502,13505,13507],{"class":274,"line":1508},[272,13503,13504],{"class":366},"    accordionClass",[272,13506,506],{"class":289},[272,13508,373],{"class":289},[272,13510,13511,13513,13515,13518,13520,13522,13524,13526],{"class":274,"line":1516},[272,13512,3222],{"class":278},[272,13514,2493],{"class":289},[272,13516,13517],{"class":2496},"opened",[272,13519,370],{"class":289},[272,13521,879],{"class":801},[272,13523,188],{"class":289},[272,13525,3089],{"class":781},[272,13527,373],{"class":289},[272,13529,13530,13532,13535,13537,13539,13541,13543,13545],{"class":274,"line":1524},[272,13531,3188],{"class":278},[272,13533,13534],{"class":282}," opened",[272,13536,2536],{"class":289},[272,13538,290],{"class":289},[272,13540,13517],{"class":293},[272,13542,403],{"class":289},[272,13544,2546],{"class":289},[272,13546,13547],{"class":289}," ''\n",[272,13549,13550],{"class":274,"line":1532},[272,13551,3213],{"class":289},[272,13553,13554],{"class":274,"line":1540},[272,13555,1140],{"class":289},[272,13557,13558],{"class":274,"line":1548},[272,13559,671],{"class":289},[272,13561,13562],{"class":274,"line":1556},[272,13563,302],{"emptyLinePlaceholder":169},[272,13565,13566,13568,13570],{"class":274,"line":1564},[272,13567,10014],{"class":366},[272,13569,370],{"class":289},[272,13571,373],{"class":289},[272,13573,13574,13577,13579,13581,13583,13585,13587,13590,13592,13594,13596],{"class":274,"line":1572},[272,13575,13576],{"class":366},"    toggleExpandAccordion",[272,13578,357],{"class":289},[272,13580,11774],{"class":2496},[272,13582,370],{"class":289},[272,13584,879],{"class":801},[272,13586,316],{"class":289},[272,13588,13589],{"class":2496}," ingredientCategoryIndex",[272,13591,370],{"class":289},[272,13593,902],{"class":801},[272,13595,188],{"class":289},[272,13597,373],{"class":289},[272,13599,13600,13602,13605,13607,13610,13612,13614,13616,13618,13620,13623,13625,13627,13629],{"class":274,"line":1580},[272,13601,10032],{"class":289},[272,13603,13604],{"class":282},"accordionExpanded",[272,13606,3127],{"class":289},[272,13608,13609],{"class":289}," this.",[272,13611,13604],{"class":282},[272,13613,430],{"class":289},[272,13615,13464],{"class":354},[272,13617,357],{"class":366},[272,13619,357],{"class":289},[272,13621,13622],{"class":2496},"_",[272,13624,188],{"class":289},[272,13626,3089],{"class":781},[272,13628,13473],{"class":2762},[272,13630,680],{"class":366},[272,13632,13633,13635,13637,13639,13642,13645,13647],{"class":274,"line":1588},[272,13634,10032],{"class":289},[272,13636,13604],{"class":282},[272,13638,5247],{"class":366},[272,13640,13641],{"class":282},"ingredientCategoryIndex",[272,13643,13644],{"class":366},"] ",[272,13646,2294],{"class":289},[272,13648,13649],{"class":282}," expanded\n",[272,13651,13652],{"class":274,"line":1595},[272,13653,1140],{"class":289},[272,13655,13656],{"class":274,"line":1602},[272,13657,671],{"class":289},[272,13659,13660,13662],{"class":274,"line":1608},[272,13661,677],{"class":289},[272,13663,680],{"class":282},[272,13665,13666,13668,13670],{"class":274,"line":10233},[272,13667,4113],{"class":289},[272,13669,4021],{"class":366},[272,13671,4038],{"class":289},[11,13673,13675],{"id":13674},"vuejs-の-transition-を使わないで実装したもの","Vue.js の transition を使わないで実装したもの",[15,13677,13678,13679,13681,13682,13684,13685,13688],{},"上では ",[203,13680,9266],{}," タグを使ったケースを使わなかったものも紹介します。\nこれは個人的見解ですが、",[203,13683,9266],{}," タグは",[716,13686,13687],{},"DOMの表示\u002F非表示の切り替え時のアニメーションには有効ですが、要素の位置や高さを変更するアニメーション","は向いていないのかなと思っています。",[15,13690,13691],{},"下の 2 つのケースだと、要素の表示と非表示はせず、単純に要素の高さを変えるだけだったり、X 軸の位置の変更だけで要件を満たせることができました。どのように実装したかをまとめていきます。",[245,13693,13694],{"id":13694},"モーダル",[21,13696],{"width":13697,"alt":13698,"src":13699},400,"expandable-modal.gif","https:\u002F\u002Fqiita-image-store.s3.ap-northeast-1.amazonaws.com\u002F0\u002F152032\u002F354aab9a-a055-670c-56a4-80a85aa2e2a2.gif",[15,13701,13702],{},"UI・UX リニューアルに伴い、類似サービスとの差別化を目指して、下から長さを伸ばすことができ、かつ z-index が効かして画面から浮かび上がっているモーダルを用意しようとなりました。上はサンプルですが、実際にはサービス上にある大量のコンテンツから欲しいものだけを絞り込みできるボタンが複数並べられており、それらをクリックすることで、欲しいものを絞り込みできるものとなっています。",[15,13704,13705,13706,13708],{},"アニメーションが入っている部分としては、モーダルの高さ変更のときの",[203,13707,9471],{},"です。モーダルの上の帯の部分をクリックすることで、指定した高さまでモーダルの高さを広げることができます。逆に、広がったモーダルをデフォルトの高さまで縮めることができます。",[15,13710,13711,13712,13714],{},"今回では、要素の高さを調節するだけで要件を満たせるので、上記で書いた通り要素の表示\u002F非表示をするわけではないため、Vue.js の ",[203,13713,9266],{},"タグを使いませんでした。",[264,13716,13719],{"className":4009,"code":13717,"filename":13718,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv ref=\"modal\" class=\"ume-expandable-bottom-modal\">\n    \u003Cdiv class=\"modal-content-title\" @click=\"toggleExpand\">\n      \u003Cp>タイトル\u003C\u002Fp>\n\n      \u003Cup-arrow v-if=\"!expanded\" class=\"icon icon-arrow-up\" \u002F>\n      \u003Cdown-arrow v-else class=\"icon icon-arrow-down\" \u002F>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv class=\"content\">\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue, { PropType } from 'vue'\n\nimport { ImageGroup } from '~\u002Ftypes\u002Fimage'\n\nimport UpArrow from '~\u002Fassets\u002Ffonts\u002Fup-arrow.svg?inline'\nimport DownArrow from '~\u002Fassets\u002Ffonts\u002Fdown-arrow.svg?inline'\n\ntype Data = {\n  defaultHeight: number\n  transitionSeconds: number\n}\n\nexport default Vue.extend({\n  components: {\n    UpArrow,\n    DownArrow,\n  },\n\n  model: {\n    prop: 'expanded',\n    event: 'toggleExpand',\n  },\n\n  props: {\n    expanded: {\n      type: Boolean,\n      required: true,\n    },\n\n    groups: {\n      type: Array as PropType\u003CImageGroup[]>,\n      required: true,\n    },\n  },\n\n  data(): Data {\n    return {\n      defaultHeight: 48,\n      transitionSeconds: 0.5,\n    }\n  },\n\n  watch: {\n    expanded(newValue) {\n      if (newValue) {\n        return\n      }\n\n      (this.$refs.modal as HTMLElement).style.height = `${this.defaultHeight}px`\n    },\n\n    transitionSeconds(newValue) {\n      (this.$refs.modal as HTMLElement).style.transition = `${newValue}s ease-out`\n    },\n  },\n\n  mounted() {\n    (this.$refs.modal as HTMLElement).style.transition = `${this.transitionSeconds}s ease-out`\n  },\n\n  methods: {\n    expandUpTo(height: number) {\n      (this.$refs.modal as HTMLElement).style.height = `${height}px`\n    },\n\n    toggleExpand() {\n      this.$emit('toggleExpand', !this.expanded)\n    },\n  },\n})\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\" scoped>\n.ume-expandable-bottom-modal {\n  width: 100vw;\n  height: 48px;\n  position: fixed;\n  top: auto;\n  right: 0;\n  left: 0;\n  bottom: 0;\n  background: white;\n  cursor: pointer;\n  box-shadow: 0 -9px 10px 0 rgba(0, 0, 0, 0.1);\n  border-radius: 8px 8px 0 0;\n  z-index: 97;\n\n  .modal-content-title {\n    position: relative;\n    height: 48px;\n    background: 'red';\n    display: flex;\n    justify-content: center;\n    align-items: center;\n    border-radius: 8px 8px 0 0;\n\n    .category-title {\n      margin: 6px auto;\n      width: 80%;\n      text-align: center;\n      font-size: 14px;\n      font-weight: bold;\n      color: #000;\n      line-height: 1;\n    }\n\n    .icon {\n      display: block;\n      text-align: left;\n      fill: #000;\n      position: absolute;\n      right: 20px;\n      height: 14px;\n    }\n  }\n}\n\u003C\u002Fstyle>\n","components\u002Fmolecules\u002Fume-expandable-bottom-modal.vue",[203,13720,13721,13729,13759,13789,13806,13810,13841,13863,13871,13875,13893,13901,13909,13917,13921,13939,13962,13966,13984,13988,14004,14018,14022,14032,14042,14051,14055,14059,14075,14083,14090,14096,14100,14104,14112,14126,14140,14144,14148,14156,14164,14174,14184,14188,14192,14201,14225,14235,14239,14243,14247,14257,14263,14275,14287,14291,14295,14299,14308,14321,14333,14338,14342,14346,14387,14391,14395,14408,14447,14451,14455,14459,14467,14509,14513,14517,14525,14542,14580,14584,14588,14597,14620,14624,14628,14634,14642,14646,14666,14671,14676,14681,14686,14691,14696,14701,14706,14711,14716,14721,14726,14731,14735,14740,14745,14750,14755,14759,14764,14768,14773,14777,14782,14787,14792,14797,14802,14806,14811,14815,14819,14823,14827,14831,14836,14841,14845,14850,14854,14858,14862,14866],{"__ignoreMap":154},[272,13722,13723,13725,13727],{"class":274,"line":275},[272,13724,3081],{"class":289},[272,13726,4128],{"class":366},[272,13728,4038],{"class":289},[272,13730,13731,13733,13735,13737,13739,13741,13744,13746,13748,13750,13752,13755,13757],{"class":274,"line":155},[272,13732,4135],{"class":289},[272,13734,4138],{"class":366},[272,13736,4047],{"class":781},[272,13738,2294],{"class":289},[272,13740,2334],{"class":289},[272,13742,13743],{"class":293},"modal",[272,13745,2334],{"class":289},[272,13747,4141],{"class":781},[272,13749,2294],{"class":289},[272,13751,2334],{"class":289},[272,13753,13754],{"class":293},"ume-expandable-bottom-modal",[272,13756,2334],{"class":289},[272,13758,4038],{"class":289},[272,13760,13761,13763,13765,13767,13769,13771,13774,13776,13778,13780,13782,13785,13787],{"class":274,"line":305},[272,13762,4157],{"class":289},[272,13764,4138],{"class":366},[272,13766,4141],{"class":781},[272,13768,2294],{"class":289},[272,13770,2334],{"class":289},[272,13772,13773],{"class":293},"modal-content-title",[272,13775,2334],{"class":289},[272,13777,7467],{"class":781},[272,13779,2294],{"class":289},[272,13781,2334],{"class":289},[272,13783,13784],{"class":293},"toggleExpand",[272,13786,2334],{"class":289},[272,13788,4038],{"class":289},[272,13790,13791,13793,13795,13797,13800,13802,13804],{"class":274,"line":340},[272,13792,6139],{"class":289},[272,13794,15],{"class":366},[272,13796,2311],{"class":289},[272,13798,13799],{"class":282},"タイトル",[272,13801,4113],{"class":289},[272,13803,15],{"class":366},[272,13805,4038],{"class":289},[272,13807,13808],{"class":274,"line":345},[272,13809,302],{"emptyLinePlaceholder":169},[272,13811,13812,13814,13817,13819,13821,13823,13826,13828,13830,13832,13834,13837,13839],{"class":274,"line":363},[272,13813,6139],{"class":289},[272,13815,13816],{"class":366},"up-arrow",[272,13818,9493],{"class":781},[272,13820,2294],{"class":289},[272,13822,2334],{"class":289},[272,13824,13825],{"class":293},"!expanded",[272,13827,2334],{"class":289},[272,13829,4141],{"class":781},[272,13831,2294],{"class":289},[272,13833,2334],{"class":289},[272,13835,13836],{"class":293},"icon icon-arrow-up",[272,13838,2334],{"class":289},[272,13840,7576],{"class":289},[272,13842,13843,13845,13847,13850,13852,13854,13856,13859,13861],{"class":274,"line":376},[272,13844,6139],{"class":289},[272,13846,11644],{"class":366},[272,13848,13849],{"class":781}," v-else",[272,13851,4141],{"class":781},[272,13853,2294],{"class":289},[272,13855,2334],{"class":289},[272,13857,13858],{"class":293},"icon icon-arrow-down",[272,13860,2334],{"class":289},[272,13862,7576],{"class":289},[272,13864,13865,13867,13869],{"class":274,"line":390},[272,13866,6162],{"class":289},[272,13868,4138],{"class":366},[272,13870,4038],{"class":289},[272,13872,13873],{"class":274,"line":409},[272,13874,302],{"emptyLinePlaceholder":169},[272,13876,13877,13879,13881,13883,13885,13887,13889,13891],{"class":274,"line":419},[272,13878,4157],{"class":289},[272,13880,4138],{"class":366},[272,13882,4141],{"class":781},[272,13884,2294],{"class":289},[272,13886,2334],{"class":289},[272,13888,696],{"class":293},[272,13890,2334],{"class":289},[272,13892,4038],{"class":289},[272,13894,13895,13897,13899],{"class":274,"line":449},[272,13896,6162],{"class":289},[272,13898,4138],{"class":366},[272,13900,4038],{"class":289},[272,13902,13903,13905,13907],{"class":274,"line":466},[272,13904,4175],{"class":289},[272,13906,4138],{"class":366},[272,13908,4038],{"class":289},[272,13910,13911,13913,13915],{"class":274,"line":472},[272,13912,4113],{"class":289},[272,13914,4128],{"class":366},[272,13916,4038],{"class":289},[272,13918,13919],{"class":274,"line":491},[272,13920,302],{"emptyLinePlaceholder":169},[272,13922,13923,13925,13927,13929,13931,13933,13935,13937],{"class":274,"line":511},[272,13924,3081],{"class":289},[272,13926,4021],{"class":366},[272,13928,4024],{"class":781},[272,13930,2294],{"class":289},[272,13932,2334],{"class":289},[272,13934,268],{"class":293},[272,13936,2334],{"class":289},[272,13938,4038],{"class":289},[272,13940,13941,13943,13945,13947,13949,13952,13954,13956,13958,13960],{"class":274,"line":529},[272,13942,279],{"class":278},[272,13944,9901],{"class":282},[272,13946,316],{"class":289},[272,13948,310],{"class":289},[272,13950,13951],{"class":282}," PropType",[272,13953,327],{"class":289},[272,13955,330],{"class":278},[272,13957,290],{"class":289},[272,13959,4012],{"class":293},[272,13961,297],{"class":289},[272,13963,13964],{"class":274,"line":547},[272,13965,302],{"emptyLinePlaceholder":169},[272,13967,13968,13970,13972,13974,13976,13978,13980,13982],{"class":274,"line":565},[272,13969,279],{"class":278},[272,13971,310],{"class":289},[272,13973,12941],{"class":282},[272,13975,327],{"class":289},[272,13977,330],{"class":278},[272,13979,290],{"class":289},[272,13981,12950],{"class":293},[272,13983,297],{"class":289},[272,13985,13986],{"class":274,"line":592},[272,13987,302],{"emptyLinePlaceholder":169},[272,13989,13990,13992,13995,13997,13999,14002],{"class":274,"line":611},[272,13991,279],{"class":278},[272,13993,13994],{"class":282}," UpArrow ",[272,13996,286],{"class":278},[272,13998,290],{"class":289},[272,14000,14001],{"class":293},"~\u002Fassets\u002Ffonts\u002Fup-arrow.svg?inline",[272,14003,297],{"class":289},[272,14005,14006,14008,14010,14012,14014,14016],{"class":274,"line":629},[272,14007,279],{"class":278},[272,14009,11895],{"class":282},[272,14011,286],{"class":278},[272,14013,290],{"class":289},[272,14015,11902],{"class":293},[272,14017,297],{"class":289},[272,14019,14020],{"class":274,"line":648},[272,14021,302],{"emptyLinePlaceholder":169},[272,14023,14024,14026,14028,14030],{"class":274,"line":658},[272,14025,2543],{"class":781},[272,14027,12963],{"class":801},[272,14029,3127],{"class":289},[272,14031,373],{"class":289},[272,14033,14034,14037,14039],{"class":274,"line":668},[272,14035,14036],{"class":366},"  defaultHeight",[272,14038,370],{"class":289},[272,14040,14041],{"class":801}," number\n",[272,14043,14044,14047,14049],{"class":274,"line":674},[272,14045,14046],{"class":366},"  transitionSeconds",[272,14048,370],{"class":289},[272,14050,14041],{"class":801},[272,14052,14053],{"class":274,"line":1161},[272,14054,965],{"class":289},[272,14056,14057],{"class":274,"line":1169},[272,14058,302],{"emptyLinePlaceholder":169},[272,14060,14061,14063,14065,14067,14069,14071,14073],{"class":274,"line":1177},[272,14062,348],{"class":278},[272,14064,351],{"class":278},[272,14066,9901],{"class":282},[272,14068,430],{"class":289},[272,14070,9906],{"class":354},[272,14072,357],{"class":282},[272,14074,360],{"class":289},[272,14076,14077,14079,14081],{"class":274,"line":1184},[272,14078,10949],{"class":366},[272,14080,370],{"class":289},[272,14082,373],{"class":289},[272,14084,14085,14088],{"class":274,"line":1192},[272,14086,14087],{"class":282},"    UpArrow",[272,14089,406],{"class":289},[272,14091,14092,14094],{"class":274,"line":1200},[272,14093,11937],{"class":282},[272,14095,406],{"class":289},[272,14097,14098],{"class":274,"line":1208},[272,14099,671],{"class":289},[272,14101,14102],{"class":274,"line":1216},[272,14103,302],{"emptyLinePlaceholder":169},[272,14105,14106,14108,14110],{"class":274,"line":1221},[272,14107,9915],{"class":366},[272,14109,370],{"class":289},[272,14111,373],{"class":289},[272,14113,14114,14116,14118,14120,14122,14124],{"class":274,"line":1229},[272,14115,9924],{"class":366},[272,14117,370],{"class":289},[272,14119,290],{"class":289},[272,14121,11774],{"class":293},[272,14123,403],{"class":289},[272,14125,406],{"class":289},[272,14127,14128,14130,14132,14134,14136,14138],{"class":274,"line":1237},[272,14129,9939],{"class":366},[272,14131,370],{"class":289},[272,14133,290],{"class":289},[272,14135,13784],{"class":293},[272,14137,403],{"class":289},[272,14139,406],{"class":289},[272,14141,14142],{"class":274,"line":1245},[272,14143,671],{"class":289},[272,14145,14146],{"class":274,"line":1253},[272,14147,302],{"emptyLinePlaceholder":169},[272,14149,14150,14152,14154],{"class":274,"line":1261},[272,14151,9962],{"class":366},[272,14153,370],{"class":289},[272,14155,373],{"class":289},[272,14157,14158,14160,14162],{"class":274,"line":1269},[272,14159,12005],{"class":366},[272,14161,370],{"class":289},[272,14163,373],{"class":289},[272,14165,14166,14168,14170,14172],{"class":274,"line":1277},[272,14167,393],{"class":366},[272,14169,370],{"class":289},[272,14171,9984],{"class":282},[272,14173,406],{"class":289},[272,14175,14176,14178,14180,14182],{"class":274,"line":1285},[272,14177,9991],{"class":366},[272,14179,370],{"class":289},[272,14181,3513],{"class":2762},[272,14183,406],{"class":289},[272,14185,14186],{"class":274,"line":1293},[272,14187,1140],{"class":289},[272,14189,14190],{"class":274,"line":1301},[272,14191,302],{"emptyLinePlaceholder":169},[272,14193,14194,14197,14199],{"class":274,"line":1309},[272,14195,14196],{"class":366},"    groups",[272,14198,370],{"class":289},[272,14200,373],{"class":289},[272,14202,14203,14205,14207,14210,14213,14215,14217,14220,14222],{"class":274,"line":1317},[272,14204,393],{"class":366},[272,14206,370],{"class":289},[272,14208,14209],{"class":282}," Array ",[272,14211,14212],{"class":278},"as",[272,14214,13951],{"class":801},[272,14216,3081],{"class":289},[272,14218,14219],{"class":801},"ImageGroup",[272,14221,867],{"class":282},[272,14223,14224],{"class":289},">,\n",[272,14226,14227,14229,14231,14233],{"class":274,"line":1325},[272,14228,9991],{"class":366},[272,14230,370],{"class":289},[272,14232,3513],{"class":2762},[272,14234,406],{"class":289},[272,14236,14237],{"class":274,"line":1333},[272,14238,1140],{"class":289},[272,14240,14241],{"class":274,"line":1341},[272,14242,671],{"class":289},[272,14244,14245],{"class":274,"line":1349},[272,14246,302],{"emptyLinePlaceholder":169},[272,14248,14249,14251,14253,14255],{"class":274,"line":1357},[272,14250,13019],{"class":366},[272,14252,13022],{"class":289},[272,14254,12963],{"class":801},[272,14256,373],{"class":289},[272,14258,14259,14261],{"class":274,"line":1365},[272,14260,3256],{"class":278},[272,14262,373],{"class":289},[272,14264,14265,14268,14270,14273],{"class":274,"line":1373},[272,14266,14267],{"class":366},"      defaultHeight",[272,14269,370],{"class":289},[272,14271,14272],{"class":2297}," 48",[272,14274,406],{"class":289},[272,14276,14277,14280,14282,14285],{"class":274,"line":1381},[272,14278,14279],{"class":366},"      transitionSeconds",[272,14281,370],{"class":289},[272,14283,14284],{"class":2297}," 0.5",[272,14286,406],{"class":289},[272,14288,14289],{"class":274,"line":1389},[272,14290,6018],{"class":289},[272,14292,14293],{"class":274,"line":1397},[272,14294,671],{"class":289},[272,14296,14297],{"class":274,"line":1404},[272,14298,302],{"emptyLinePlaceholder":169},[272,14300,14301,14304,14306],{"class":274,"line":1412},[272,14302,14303],{"class":366},"  watch",[272,14305,370],{"class":289},[272,14307,373],{"class":289},[272,14309,14310,14312,14314,14317,14319],{"class":274,"line":1420},[272,14311,12005],{"class":366},[272,14313,357],{"class":289},[272,14315,14316],{"class":2496},"newValue",[272,14318,188],{"class":289},[272,14320,373],{"class":289},[272,14322,14323,14325,14327,14329,14331],{"class":274,"line":1428},[272,14324,3149],{"class":278},[272,14326,2493],{"class":366},[272,14328,14316],{"class":282},[272,14330,2317],{"class":366},[272,14332,360],{"class":289},[272,14334,14335],{"class":274,"line":1436},[272,14336,14337],{"class":278},"        return\n",[272,14339,14340],{"class":274,"line":1444},[272,14341,3213],{"class":289},[272,14343,14344],{"class":274,"line":1452},[272,14345,302],{"emptyLinePlaceholder":169},[272,14347,14348,14350,14352,14354,14356,14358,14360,14362,14364,14366,14368,14370,14372,14374,14376,14378,14381,14383,14385],{"class":274,"line":1460},[272,14349,12113],{"class":366},[272,14351,12097],{"class":289},[272,14353,12100],{"class":282},[272,14355,430],{"class":289},[272,14357,13743],{"class":282},[272,14359,3432],{"class":278},[272,14361,12126],{"class":801},[272,14363,188],{"class":366},[272,14365,430],{"class":289},[272,14367,2211],{"class":282},[272,14369,430],{"class":289},[272,14371,11537],{"class":282},[272,14373,3127],{"class":289},[272,14375,12141],{"class":289},[272,14377,12097],{"class":289},[272,14379,14380],{"class":282},"defaultHeight",[272,14382,677],{"class":289},[272,14384,12159],{"class":293},[272,14386,12162],{"class":289},[272,14388,14389],{"class":274,"line":1468},[272,14390,1140],{"class":289},[272,14392,14393],{"class":274,"line":1476},[272,14394,302],{"emptyLinePlaceholder":169},[272,14396,14397,14400,14402,14404,14406],{"class":274,"line":1484},[272,14398,14399],{"class":366},"    transitionSeconds",[272,14401,357],{"class":289},[272,14403,14316],{"class":2496},[272,14405,188],{"class":289},[272,14407,373],{"class":289},[272,14409,14410,14412,14414,14416,14418,14420,14422,14424,14426,14428,14430,14432,14434,14436,14438,14440,14442,14445],{"class":274,"line":1492},[272,14411,12113],{"class":366},[272,14413,12097],{"class":289},[272,14415,12100],{"class":282},[272,14417,430],{"class":289},[272,14419,13743],{"class":282},[272,14421,3432],{"class":278},[272,14423,12126],{"class":801},[272,14425,188],{"class":366},[272,14427,430],{"class":289},[272,14429,2211],{"class":282},[272,14431,430],{"class":289},[272,14433,9471],{"class":282},[272,14435,3127],{"class":289},[272,14437,12141],{"class":289},[272,14439,14316],{"class":282},[272,14441,677],{"class":289},[272,14443,14444],{"class":293},"s ease-out",[272,14446,12162],{"class":289},[272,14448,14449],{"class":274,"line":1500},[272,14450,1140],{"class":289},[272,14452,14453],{"class":274,"line":1508},[272,14454,671],{"class":289},[272,14456,14457],{"class":274,"line":1516},[272,14458,302],{"emptyLinePlaceholder":169},[272,14460,14461,14463,14465],{"class":274,"line":1524},[272,14462,12083],{"class":366},[272,14464,506],{"class":289},[272,14466,373],{"class":289},[272,14468,14469,14472,14474,14476,14478,14480,14482,14484,14486,14488,14490,14492,14494,14496,14498,14500,14503,14505,14507],{"class":274,"line":1532},[272,14470,14471],{"class":366},"    (",[272,14473,12097],{"class":289},[272,14475,12100],{"class":282},[272,14477,430],{"class":289},[272,14479,13743],{"class":282},[272,14481,3432],{"class":278},[272,14483,12126],{"class":801},[272,14485,188],{"class":366},[272,14487,430],{"class":289},[272,14489,2211],{"class":282},[272,14491,430],{"class":289},[272,14493,9471],{"class":282},[272,14495,3127],{"class":289},[272,14497,12141],{"class":289},[272,14499,12097],{"class":289},[272,14501,14502],{"class":282},"transitionSeconds",[272,14504,677],{"class":289},[272,14506,14444],{"class":293},[272,14508,12162],{"class":289},[272,14510,14511],{"class":274,"line":1540},[272,14512,671],{"class":289},[272,14514,14515],{"class":274,"line":1548},[272,14516,302],{"emptyLinePlaceholder":169},[272,14518,14519,14521,14523],{"class":274,"line":1556},[272,14520,10014],{"class":366},[272,14522,370],{"class":289},[272,14524,373],{"class":289},[272,14526,14527,14530,14532,14534,14536,14538,14540],{"class":274,"line":1564},[272,14528,14529],{"class":366},"    expandUpTo",[272,14531,357],{"class":289},[272,14533,11537],{"class":2496},[272,14535,370],{"class":289},[272,14537,902],{"class":801},[272,14539,188],{"class":289},[272,14541,373],{"class":289},[272,14543,14544,14546,14548,14550,14552,14554,14556,14558,14560,14562,14564,14566,14568,14570,14572,14574,14576,14578],{"class":274,"line":1572},[272,14545,12113],{"class":366},[272,14547,12097],{"class":289},[272,14549,12100],{"class":282},[272,14551,430],{"class":289},[272,14553,13743],{"class":282},[272,14555,3432],{"class":278},[272,14557,12126],{"class":801},[272,14559,188],{"class":366},[272,14561,430],{"class":289},[272,14563,2211],{"class":282},[272,14565,430],{"class":289},[272,14567,11537],{"class":282},[272,14569,3127],{"class":289},[272,14571,12141],{"class":289},[272,14573,11537],{"class":282},[272,14575,677],{"class":289},[272,14577,12159],{"class":293},[272,14579,12162],{"class":289},[272,14581,14582],{"class":274,"line":1580},[272,14583,1140],{"class":289},[272,14585,14586],{"class":274,"line":1588},[272,14587,302],{"emptyLinePlaceholder":169},[272,14589,14590,14593,14595],{"class":274,"line":1595},[272,14591,14592],{"class":366},"    toggleExpand",[272,14594,506],{"class":289},[272,14596,373],{"class":289},[272,14598,14599,14601,14603,14605,14607,14609,14611,14613,14616,14618],{"class":274,"line":1602},[272,14600,10032],{"class":289},[272,14602,10035],{"class":354},[272,14604,357],{"class":366},[272,14606,403],{"class":289},[272,14608,13784],{"class":293},[272,14610,403],{"class":289},[272,14612,316],{"class":289},[272,14614,14615],{"class":289}," !this.",[272,14617,11774],{"class":282},[272,14619,680],{"class":366},[272,14621,14622],{"class":274,"line":1608},[272,14623,1140],{"class":289},[272,14625,14626],{"class":274,"line":10233},[272,14627,671],{"class":289},[272,14629,14630,14632],{"class":274,"line":10239},[272,14631,677],{"class":289},[272,14633,680],{"class":282},[272,14635,14636,14638,14640],{"class":274,"line":10245},[272,14637,4113],{"class":289},[272,14639,4021],{"class":366},[272,14641,4038],{"class":289},[272,14643,14644],{"class":274,"line":10251},[272,14645,302],{"emptyLinePlaceholder":169},[272,14647,14648,14650,14652,14654,14656,14658,14660,14662,14664],{"class":274,"line":10256},[272,14649,3081],{"class":289},[272,14651,2211],{"class":366},[272,14653,4024],{"class":781},[272,14655,2294],{"class":289},[272,14657,2334],{"class":289},[272,14659,4206],{"class":293},[272,14661,2334],{"class":289},[272,14663,4211],{"class":781},[272,14665,4038],{"class":289},[272,14667,14668],{"class":274,"line":10262},[272,14669,14670],{"class":282},".ume-expandable-bottom-modal {\n",[272,14672,14673],{"class":274,"line":10268},[272,14674,14675],{"class":282},"  width: 100vw;\n",[272,14677,14678],{"class":274,"line":10274},[272,14679,14680],{"class":282},"  height: 48px;\n",[272,14682,14683],{"class":274,"line":10280},[272,14684,14685],{"class":282},"  position: fixed;\n",[272,14687,14688],{"class":274,"line":10286},[272,14689,14690],{"class":282},"  top: auto;\n",[272,14692,14693],{"class":274,"line":10292},[272,14694,14695],{"class":282},"  right: 0;\n",[272,14697,14698],{"class":274,"line":10297},[272,14699,14700],{"class":282},"  left: 0;\n",[272,14702,14703],{"class":274,"line":10302},[272,14704,14705],{"class":282},"  bottom: 0;\n",[272,14707,14708],{"class":274,"line":10307},[272,14709,14710],{"class":282},"  background: white;\n",[272,14712,14713],{"class":274,"line":10313},[272,14714,14715],{"class":282},"  cursor: pointer;\n",[272,14717,14718],{"class":274,"line":10318},[272,14719,14720],{"class":282},"  box-shadow: 0 -9px 10px 0 rgba(0, 0, 0, 0.1);\n",[272,14722,14723],{"class":274,"line":10324},[272,14724,14725],{"class":282},"  border-radius: 8px 8px 0 0;\n",[272,14727,14728],{"class":274,"line":10330},[272,14729,14730],{"class":282},"  z-index: 97;\n",[272,14732,14733],{"class":274,"line":10335},[272,14734,302],{"emptyLinePlaceholder":169},[272,14736,14737],{"class":274,"line":10341},[272,14738,14739],{"class":282},"  .modal-content-title {\n",[272,14741,14742],{"class":274,"line":10346},[272,14743,14744],{"class":282},"    position: relative;\n",[272,14746,14747],{"class":274,"line":10351},[272,14748,14749],{"class":282},"    height: 48px;\n",[272,14751,14752],{"class":274,"line":10357},[272,14753,14754],{"class":282},"    background: 'red';\n",[272,14756,14757],{"class":274,"line":10362},[272,14758,11280],{"class":282},[272,14760,14761],{"class":274,"line":10367},[272,14762,14763],{"class":282},"    justify-content: center;\n",[272,14765,14766],{"class":274,"line":10373},[272,14767,12458],{"class":282},[272,14769,14770],{"class":274,"line":10379},[272,14771,14772],{"class":282},"    border-radius: 8px 8px 0 0;\n",[272,14774,14775],{"class":274,"line":10385},[272,14776,302],{"emptyLinePlaceholder":169},[272,14778,14779],{"class":274,"line":10391},[272,14780,14781],{"class":282},"    .category-title {\n",[272,14783,14784],{"class":274,"line":10396},[272,14785,14786],{"class":282},"      margin: 6px auto;\n",[272,14788,14789],{"class":274,"line":10401},[272,14790,14791],{"class":282},"      width: 80%;\n",[272,14793,14794],{"class":274,"line":10407},[272,14795,14796],{"class":282},"      text-align: center;\n",[272,14798,14799],{"class":274,"line":10413},[272,14800,14801],{"class":282},"      font-size: 14px;\n",[272,14803,14804],{"class":274,"line":10419},[272,14805,10440],{"class":282},[272,14807,14808],{"class":274,"line":10425},[272,14809,14810],{"class":282},"      color: #000;\n",[272,14812,14813],{"class":274,"line":10431},[272,14814,10464],{"class":282},[272,14816,14817],{"class":274,"line":10437},[272,14818,6018],{"class":282},[272,14820,14821],{"class":274,"line":10443},[272,14822,302],{"emptyLinePlaceholder":169},[272,14824,14825],{"class":274,"line":10449},[272,14826,12487],{"class":282},[272,14828,14829],{"class":274,"line":10455},[272,14830,10410],{"class":282},[272,14832,14833],{"class":274,"line":10461},[272,14834,14835],{"class":282},"      text-align: left;\n",[272,14837,14838],{"class":274,"line":10467},[272,14839,14840],{"class":282},"      fill: #000;\n",[272,14842,14843],{"class":274,"line":10472},[272,14844,10265],{"class":282},[272,14846,14847],{"class":274,"line":10478},[272,14848,14849],{"class":282},"      right: 20px;\n",[272,14851,14852],{"class":274,"line":10484},[272,14853,12501],{"class":282},[272,14855,14856],{"class":274,"line":10489},[272,14857,6018],{"class":282},[272,14859,14860],{"class":274,"line":10494},[272,14861,909],{"class":282},[272,14863,14864],{"class":274,"line":10499},[272,14865,965],{"class":282},[272,14867,14868,14870,14872],{"class":274,"line":10504},[272,14869,4113],{"class":289},[272,14871,2211],{"class":366},[272,14873,4038],{"class":289},[245,14875,14876],{"id":14876},"ギャラリー",[21,14878],{"width":9350,"alt":14879,"src":14880},"gallery.gif","https:\u002F\u002Fqiita-image-store.s3.ap-northeast-1.amazonaws.com\u002F0\u002F152032\u002Fb9d7cc27-fa82-51da-a458-4352a9d07329.gif",[15,14882,14883,14884,14886],{},"もう 1 つ Vue.js の",[203,14885,9266],{},"タグを使わずに実装したアニメーションとして、写真を複数枚並べて、それをスライドさせるギャラリーがあります。使われるシーンとしては、トップページの上部で複数のバナー画像の表示だったり、ランキング表示や 1 つの商品を紹介する写真を複数する表示するときなどに利用されるケースが多いです。",[15,14888,14889,14890,14892,14893,14896,14897,14899],{},"上で書いたように、これも ",[203,14891,9266],{},"タグを使わずに実装しています。矢印クリックで、要素のリストのラッパーの",[203,14894,14895],{},"translateY","を要素の長さ分、加算したり減算することで、リストの位置をずらす仕組みになっています。リストをラップしている DOM は、指定した長さで固定されているので、実際に目に見えるリストのコンテンツを表示するという考えです。スライドの速度はリストの css に",[203,14898,9471],{},"を書くことで調整できます。",[264,14901,14904],{"className":4009,"code":14902,"filename":14903,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cdiv class=\"ume-gallery\">\n    \u003Cdiv @click=\"previous\">\n      \u003Cleft-arrow :class=\"`icon icon-arrow-left ${previousclickableClass}`\" \u002F>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv ref=\"slide-list-wrapper\" class=\"slide-list-wrapper\">\n      \u003Col ref=\"slide-list\" class=\"slide-list\">\n        \u003Cli v-for=\"(slideListElement, index) in slideListElements\" :key=\"index\">\n          \u003Cslot name=\"slide-list-element\" :slide-list-element=\"slideListElement\" \u002F>\n        \u003C\u002Fli>\n      \u003C\u002Fol>\n    \u003C\u002Fdiv>\n\n    \u003Cdiv @click=\"following\">\n      \u003Cright-arrow :class=\"`icon icon-arrow-right ${followingClickableClass}`\" \u002F>\n    \u003C\u002Fdiv>\n  \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript lang=\"ts\">\nimport Vue, { PropType } from 'vue'\n\nimport { Image } from '~\u002Ftypes\u002Fimage'\n\nimport RightArrow from '~\u002Fassets\u002Ffonts\u002Fright-arrow.svg?inline'\nimport LeftArrow from '~\u002Fassets\u002Ffonts\u002Fleft-arrow.svg?inline'\n\nconst firstDisplayNum = 4\n\ntype Data = {\n  transformX: number\n  offset: number\n  largestDisplayedNum: number\n}\n\nexport default Vue.extend({\n  components: {\n    RightArrow,\n    LeftArrow,\n  },\n\n  props: {\n    slideListElements: {\n      type: Array as PropType\u003CImage[]>,\n      required: true,\n    },\n\n    width: {\n      type: Number,\n      required: true,\n    },\n  },\n\n  data(): Data {\n    return {\n      transformX: 0,\n      offset: 24,\n      largestDisplayedNum: firstDisplayNum,\n    }\n  },\n\n  computed: {\n    previousclickableClass(): string {\n      return this.canSlidePrevious ? 'clickable' : 'non-clickable'\n    },\n\n    followingClickableClass(): string {\n      return this.canSlideFollowing ? 'clickable' : 'non-clickable'\n    },\n\n    canSlidePrevious(): boolean {\n      return this.largestDisplayedNum > firstDisplayNum\n    },\n\n    canSlideFollowing(): boolean {\n      return this.largestDisplayedNum \u003C this.slideListElements.length\n    },\n\n    slideElementStyle(): { 'min-width': string } {\n      return { 'min-width': `${this.width}px` }\n    },\n  },\n\n  mounted() {\n    (this.$refs['slide-list-wrapper'] as HTMLElement).style.width = `${(this.width + this.offset) * firstDisplayNum}px`\n  },\n\n  methods: {\n    previous(): void {\n      if (!this.canSlidePrevious) {\n        return\n      }\n\n      this.transformX += this.width + this.offset\n      (this.$refs.slide as HTMLElement).style.transform = `translate(${this.transformX}px, 0)`\n      this.largestDisplayedNum--\n    },\n\n    following(): void {\n      if (!this.canSlideFollowing) {\n        return\n      }\n\n      this.transformX -= this.width + this.offset\n      (this.$refs.slide as HTMLElement).style.transform = `translate(${this.transformX}px, 0)`\n      this.largestDisplayedNum++\n    },\n  },\n})\n\u003C\u002Fscript>\n\n\u003Cstyle lang=\"scss\" scoped>\n.ume-gallery {\n  display: flex;\n  justify-content: center;\n  align-items: center;\n\n  @media only screen and (max-width: 940px) {\n    margin: 0;\n  }\n\n  .icon {\n    height: 24px;\n    width: 28px;\n  }\n\n  .clickable {\n    fill: #c7c7cc;\n  }\n\n  .non-clickable {\n    fill: #d1d1d6;\n  }\n\n  .slide-list-wrapper {\n    overflow: hidden;\n    margin: 0 auto;\n\n    .slide-list {\n      transition: 0.5s;\n      display: flex;\n    }\n  }\n}\n\u003C\u002Fstyle>\n","component\u002Fmolecules\u002Fume-gallery.vue",[203,14905,14906,14914,14933,14952,14972,14980,14984,15013,15042,15072,15103,15111,15119,15127,15131,15150,15170,15178,15186,15194,15198,15216,15238,15242,15261,15265,15281,15297,15301,15313,15317,15327,15336,15345,15354,15358,15362,15378,15386,15393,15400,15404,15408,15416,15425,15446,15456,15460,15464,15473,15484,15494,15498,15502,15506,15516,15522,15534,15546,15558,15562,15566,15570,15578,15589,15616,15620,15624,15635,15660,15664,15668,15679,15694,15698,15702,15713,15734,15738,15742,15766,15795,15799,15803,15807,15815,15876,15880,15884,15892,15903,15918,15922,15926,15930,15951,16000,16009,16013,16017,16028,16042,16046,16050,16054,16073,16117,16126,16130,16134,16140,16148,16152,16172,16177,16182,16187,16192,16196,16201,16206,16210,16214,16219,16224,16229,16233,16237,16242,16247,16251,16255,16260,16266,16271,16276,16282,16287,16293,16298,16304,16310,16316,16321,16326,16331],{"__ignoreMap":154},[272,14907,14908,14910,14912],{"class":274,"line":275},[272,14909,3081],{"class":289},[272,14911,4128],{"class":366},[272,14913,4038],{"class":289},[272,14915,14916,14918,14920,14922,14924,14926,14929,14931],{"class":274,"line":155},[272,14917,4135],{"class":289},[272,14919,4138],{"class":366},[272,14921,4141],{"class":781},[272,14923,2294],{"class":289},[272,14925,2334],{"class":289},[272,14927,14928],{"class":293},"ume-gallery",[272,14930,2334],{"class":289},[272,14932,4038],{"class":289},[272,14934,14935,14937,14939,14941,14943,14945,14948,14950],{"class":274,"line":305},[272,14936,4157],{"class":289},[272,14938,4138],{"class":366},[272,14940,7467],{"class":781},[272,14942,2294],{"class":289},[272,14944,2334],{"class":289},[272,14946,14947],{"class":293},"previous",[272,14949,2334],{"class":289},[272,14951,4038],{"class":289},[272,14953,14954,14956,14959,14961,14963,14965,14968,14970],{"class":274,"line":340},[272,14955,6139],{"class":289},[272,14957,14958],{"class":366},"left-arrow",[272,14960,11669],{"class":781},[272,14962,2294],{"class":289},[272,14964,2334],{"class":289},[272,14966,14967],{"class":293},"`icon icon-arrow-left ${previousclickableClass}`",[272,14969,2334],{"class":289},[272,14971,7576],{"class":289},[272,14973,14974,14976,14978],{"class":274,"line":345},[272,14975,6162],{"class":289},[272,14977,4138],{"class":366},[272,14979,4038],{"class":289},[272,14981,14982],{"class":274,"line":363},[272,14983,302],{"emptyLinePlaceholder":169},[272,14985,14986,14988,14990,14992,14994,14996,14999,15001,15003,15005,15007,15009,15011],{"class":274,"line":376},[272,14987,4157],{"class":289},[272,14989,4138],{"class":366},[272,14991,4047],{"class":781},[272,14993,2294],{"class":289},[272,14995,2334],{"class":289},[272,14997,14998],{"class":293},"slide-list-wrapper",[272,15000,2334],{"class":289},[272,15002,4141],{"class":781},[272,15004,2294],{"class":289},[272,15006,2334],{"class":289},[272,15008,14998],{"class":293},[272,15010,2334],{"class":289},[272,15012,4038],{"class":289},[272,15014,15015,15017,15019,15021,15023,15025,15028,15030,15032,15034,15036,15038,15040],{"class":274,"line":390},[272,15016,6139],{"class":289},[272,15018,9326],{"class":366},[272,15020,4047],{"class":781},[272,15022,2294],{"class":289},[272,15024,2334],{"class":289},[272,15026,15027],{"class":293},"slide-list",[272,15029,2334],{"class":289},[272,15031,4141],{"class":781},[272,15033,2294],{"class":289},[272,15035,2334],{"class":289},[272,15037,15027],{"class":293},[272,15039,2334],{"class":289},[272,15041,4038],{"class":289},[272,15043,15044,15046,15048,15050,15052,15054,15057,15059,15061,15063,15065,15068,15070],{"class":274,"line":409},[272,15045,9530],{"class":289},[272,15047,38],{"class":366},[272,15049,12782],{"class":781},[272,15051,2294],{"class":289},[272,15053,2334],{"class":289},[272,15055,15056],{"class":293},"(slideListElement, index) in slideListElements",[272,15058,2334],{"class":289},[272,15060,12794],{"class":781},[272,15062,2294],{"class":289},[272,15064,2334],{"class":289},[272,15066,15067],{"class":293},"index",[272,15069,2334],{"class":289},[272,15071,4038],{"class":289},[272,15073,15074,15076,15078,15080,15082,15084,15087,15089,15092,15094,15096,15099,15101],{"class":274,"line":419},[272,15075,9644],{"class":289},[272,15077,11621],{"class":366},[272,15079,9474],{"class":781},[272,15081,2294],{"class":289},[272,15083,2334],{"class":289},[272,15085,15086],{"class":293},"slide-list-element",[272,15088,2334],{"class":289},[272,15090,15091],{"class":781}," :slide-list-element",[272,15093,2294],{"class":289},[272,15095,2334],{"class":289},[272,15097,15098],{"class":293},"slideListElement",[272,15100,2334],{"class":289},[272,15102,7576],{"class":289},[272,15104,15105,15107,15109],{"class":274,"line":449},[272,15106,9815],{"class":289},[272,15108,38],{"class":366},[272,15110,4038],{"class":289},[272,15112,15113,15115,15117],{"class":274,"line":466},[272,15114,6153],{"class":289},[272,15116,9326],{"class":366},[272,15118,4038],{"class":289},[272,15120,15121,15123,15125],{"class":274,"line":472},[272,15122,6162],{"class":289},[272,15124,4138],{"class":366},[272,15126,4038],{"class":289},[272,15128,15129],{"class":274,"line":491},[272,15130,302],{"emptyLinePlaceholder":169},[272,15132,15133,15135,15137,15139,15141,15143,15146,15148],{"class":274,"line":511},[272,15134,4157],{"class":289},[272,15136,4138],{"class":366},[272,15138,7467],{"class":781},[272,15140,2294],{"class":289},[272,15142,2334],{"class":289},[272,15144,15145],{"class":293},"following",[272,15147,2334],{"class":289},[272,15149,4038],{"class":289},[272,15151,15152,15154,15157,15159,15161,15163,15166,15168],{"class":274,"line":529},[272,15153,6139],{"class":289},[272,15155,15156],{"class":366},"right-arrow",[272,15158,11669],{"class":781},[272,15160,2294],{"class":289},[272,15162,2334],{"class":289},[272,15164,15165],{"class":293},"`icon icon-arrow-right ${followingClickableClass}`",[272,15167,2334],{"class":289},[272,15169,7576],{"class":289},[272,15171,15172,15174,15176],{"class":274,"line":547},[272,15173,6162],{"class":289},[272,15175,4138],{"class":366},[272,15177,4038],{"class":289},[272,15179,15180,15182,15184],{"class":274,"line":565},[272,15181,4175],{"class":289},[272,15183,4138],{"class":366},[272,15185,4038],{"class":289},[272,15187,15188,15190,15192],{"class":274,"line":592},[272,15189,4113],{"class":289},[272,15191,4128],{"class":366},[272,15193,4038],{"class":289},[272,15195,15196],{"class":274,"line":611},[272,15197,302],{"emptyLinePlaceholder":169},[272,15199,15200,15202,15204,15206,15208,15210,15212,15214],{"class":274,"line":629},[272,15201,3081],{"class":289},[272,15203,4021],{"class":366},[272,15205,4024],{"class":781},[272,15207,2294],{"class":289},[272,15209,2334],{"class":289},[272,15211,268],{"class":293},[272,15213,2334],{"class":289},[272,15215,4038],{"class":289},[272,15217,15218,15220,15222,15224,15226,15228,15230,15232,15234,15236],{"class":274,"line":648},[272,15219,279],{"class":278},[272,15221,9901],{"class":282},[272,15223,316],{"class":289},[272,15225,310],{"class":289},[272,15227,13951],{"class":282},[272,15229,327],{"class":289},[272,15231,330],{"class":278},[272,15233,290],{"class":289},[272,15235,4012],{"class":293},[272,15237,297],{"class":289},[272,15239,15240],{"class":274,"line":658},[272,15241,302],{"emptyLinePlaceholder":169},[272,15243,15244,15246,15248,15251,15253,15255,15257,15259],{"class":274,"line":668},[272,15245,279],{"class":278},[272,15247,310],{"class":289},[272,15249,15250],{"class":282}," Image",[272,15252,327],{"class":289},[272,15254,330],{"class":278},[272,15256,290],{"class":289},[272,15258,12950],{"class":293},[272,15260,297],{"class":289},[272,15262,15263],{"class":274,"line":674},[272,15264,302],{"emptyLinePlaceholder":169},[272,15266,15267,15269,15272,15274,15276,15279],{"class":274,"line":1161},[272,15268,279],{"class":278},[272,15270,15271],{"class":282}," RightArrow ",[272,15273,286],{"class":278},[272,15275,290],{"class":289},[272,15277,15278],{"class":293},"~\u002Fassets\u002Ffonts\u002Fright-arrow.svg?inline",[272,15280,297],{"class":289},[272,15282,15283,15285,15288,15290,15292,15295],{"class":274,"line":1169},[272,15284,279],{"class":278},[272,15286,15287],{"class":282}," LeftArrow ",[272,15289,286],{"class":278},[272,15291,290],{"class":289},[272,15293,15294],{"class":293},"~\u002Fassets\u002Ffonts\u002Fleft-arrow.svg?inline",[272,15296,297],{"class":289},[272,15298,15299],{"class":274,"line":1177},[272,15300,302],{"emptyLinePlaceholder":169},[272,15302,15303,15305,15308,15310],{"class":274,"line":1184},[272,15304,2288],{"class":781},[272,15306,15307],{"class":282}," firstDisplayNum ",[272,15309,2294],{"class":289},[272,15311,15312],{"class":2297}," 4\n",[272,15314,15315],{"class":274,"line":1192},[272,15316,302],{"emptyLinePlaceholder":169},[272,15318,15319,15321,15323,15325],{"class":274,"line":1200},[272,15320,2543],{"class":781},[272,15322,12963],{"class":801},[272,15324,3127],{"class":289},[272,15326,373],{"class":289},[272,15328,15329,15332,15334],{"class":274,"line":1208},[272,15330,15331],{"class":366},"  transformX",[272,15333,370],{"class":289},[272,15335,14041],{"class":801},[272,15337,15338,15341,15343],{"class":274,"line":1216},[272,15339,15340],{"class":366},"  offset",[272,15342,370],{"class":289},[272,15344,14041],{"class":801},[272,15346,15347,15350,15352],{"class":274,"line":1221},[272,15348,15349],{"class":366},"  largestDisplayedNum",[272,15351,370],{"class":289},[272,15353,14041],{"class":801},[272,15355,15356],{"class":274,"line":1229},[272,15357,965],{"class":289},[272,15359,15360],{"class":274,"line":1237},[272,15361,302],{"emptyLinePlaceholder":169},[272,15363,15364,15366,15368,15370,15372,15374,15376],{"class":274,"line":1245},[272,15365,348],{"class":278},[272,15367,351],{"class":278},[272,15369,9901],{"class":282},[272,15371,430],{"class":289},[272,15373,9906],{"class":354},[272,15375,357],{"class":282},[272,15377,360],{"class":289},[272,15379,15380,15382,15384],{"class":274,"line":1253},[272,15381,10949],{"class":366},[272,15383,370],{"class":289},[272,15385,373],{"class":289},[272,15387,15388,15391],{"class":274,"line":1261},[272,15389,15390],{"class":282},"    RightArrow",[272,15392,406],{"class":289},[272,15394,15395,15398],{"class":274,"line":1269},[272,15396,15397],{"class":282},"    LeftArrow",[272,15399,406],{"class":289},[272,15401,15402],{"class":274,"line":1277},[272,15403,671],{"class":289},[272,15405,15406],{"class":274,"line":1285},[272,15407,302],{"emptyLinePlaceholder":169},[272,15409,15410,15412,15414],{"class":274,"line":1293},[272,15411,9962],{"class":366},[272,15413,370],{"class":289},[272,15415,373],{"class":289},[272,15417,15418,15421,15423],{"class":274,"line":1301},[272,15419,15420],{"class":366},"    slideListElements",[272,15422,370],{"class":289},[272,15424,373],{"class":289},[272,15426,15427,15429,15431,15433,15435,15437,15439,15442,15444],{"class":274,"line":1309},[272,15428,393],{"class":366},[272,15430,370],{"class":289},[272,15432,14209],{"class":282},[272,15434,14212],{"class":278},[272,15436,13951],{"class":801},[272,15438,3081],{"class":289},[272,15440,15441],{"class":801},"Image",[272,15443,867],{"class":282},[272,15445,14224],{"class":289},[272,15447,15448,15450,15452,15454],{"class":274,"line":1317},[272,15449,9991],{"class":366},[272,15451,370],{"class":289},[272,15453,3513],{"class":2762},[272,15455,406],{"class":289},[272,15457,15458],{"class":274,"line":1325},[272,15459,1140],{"class":289},[272,15461,15462],{"class":274,"line":1333},[272,15463,302],{"emptyLinePlaceholder":169},[272,15465,15466,15469,15471],{"class":274,"line":1341},[272,15467,15468],{"class":366},"    width",[272,15470,370],{"class":289},[272,15472,373],{"class":289},[272,15474,15475,15477,15479,15482],{"class":274,"line":1349},[272,15476,393],{"class":366},[272,15478,370],{"class":289},[272,15480,15481],{"class":282}," Number",[272,15483,406],{"class":289},[272,15485,15486,15488,15490,15492],{"class":274,"line":1357},[272,15487,9991],{"class":366},[272,15489,370],{"class":289},[272,15491,3513],{"class":2762},[272,15493,406],{"class":289},[272,15495,15496],{"class":274,"line":1365},[272,15497,1140],{"class":289},[272,15499,15500],{"class":274,"line":1373},[272,15501,671],{"class":289},[272,15503,15504],{"class":274,"line":1381},[272,15505,302],{"emptyLinePlaceholder":169},[272,15507,15508,15510,15512,15514],{"class":274,"line":1389},[272,15509,13019],{"class":366},[272,15511,13022],{"class":289},[272,15513,12963],{"class":801},[272,15515,373],{"class":289},[272,15517,15518,15520],{"class":274,"line":1397},[272,15519,3256],{"class":278},[272,15521,373],{"class":289},[272,15523,15524,15527,15529,15532],{"class":274,"line":1404},[272,15525,15526],{"class":366},"      transformX",[272,15528,370],{"class":289},[272,15530,15531],{"class":2297}," 0",[272,15533,406],{"class":289},[272,15535,15536,15539,15541,15544],{"class":274,"line":1412},[272,15537,15538],{"class":366},"      offset",[272,15540,370],{"class":289},[272,15542,15543],{"class":2297}," 24",[272,15545,406],{"class":289},[272,15547,15548,15551,15553,15556],{"class":274,"line":1420},[272,15549,15550],{"class":366},"      largestDisplayedNum",[272,15552,370],{"class":289},[272,15554,15555],{"class":282}," firstDisplayNum",[272,15557,406],{"class":289},[272,15559,15560],{"class":274,"line":1428},[272,15561,6018],{"class":289},[272,15563,15564],{"class":274,"line":1436},[272,15565,671],{"class":289},[272,15567,15568],{"class":274,"line":1444},[272,15569,302],{"emptyLinePlaceholder":169},[272,15571,15572,15574,15576],{"class":274,"line":1452},[272,15573,13495],{"class":366},[272,15575,370],{"class":289},[272,15577,373],{"class":289},[272,15579,15580,15583,15585,15587],{"class":274,"line":1460},[272,15581,15582],{"class":366},"    previousclickableClass",[272,15584,13022],{"class":289},[272,15586,819],{"class":801},[272,15588,373],{"class":289},[272,15590,15591,15593,15595,15598,15600,15602,15605,15607,15609,15611,15614],{"class":274,"line":1468},[272,15592,3222],{"class":278},[272,15594,13609],{"class":289},[272,15596,15597],{"class":282},"canSlidePrevious",[272,15599,2536],{"class":289},[272,15601,290],{"class":289},[272,15603,15604],{"class":293},"clickable",[272,15606,403],{"class":289},[272,15608,2546],{"class":289},[272,15610,290],{"class":289},[272,15612,15613],{"class":293},"non-clickable",[272,15615,297],{"class":289},[272,15617,15618],{"class":274,"line":1476},[272,15619,1140],{"class":289},[272,15621,15622],{"class":274,"line":1484},[272,15623,302],{"emptyLinePlaceholder":169},[272,15625,15626,15629,15631,15633],{"class":274,"line":1492},[272,15627,15628],{"class":366},"    followingClickableClass",[272,15630,13022],{"class":289},[272,15632,819],{"class":801},[272,15634,373],{"class":289},[272,15636,15637,15639,15641,15644,15646,15648,15650,15652,15654,15656,15658],{"class":274,"line":1500},[272,15638,3222],{"class":278},[272,15640,13609],{"class":289},[272,15642,15643],{"class":282},"canSlideFollowing",[272,15645,2536],{"class":289},[272,15647,290],{"class":289},[272,15649,15604],{"class":293},[272,15651,403],{"class":289},[272,15653,2546],{"class":289},[272,15655,290],{"class":289},[272,15657,15613],{"class":293},[272,15659,297],{"class":289},[272,15661,15662],{"class":274,"line":1508},[272,15663,1140],{"class":289},[272,15665,15666],{"class":274,"line":1516},[272,15667,302],{"emptyLinePlaceholder":169},[272,15669,15670,15673,15675,15677],{"class":274,"line":1524},[272,15671,15672],{"class":366},"    canSlidePrevious",[272,15674,13022],{"class":289},[272,15676,879],{"class":801},[272,15678,373],{"class":289},[272,15680,15681,15683,15685,15688,15691],{"class":274,"line":1532},[272,15682,3222],{"class":278},[272,15684,13609],{"class":289},[272,15686,15687],{"class":282},"largestDisplayedNum",[272,15689,15690],{"class":289}," >",[272,15692,15693],{"class":282}," firstDisplayNum\n",[272,15695,15696],{"class":274,"line":1540},[272,15697,1140],{"class":289},[272,15699,15700],{"class":274,"line":1548},[272,15701,302],{"emptyLinePlaceholder":169},[272,15703,15704,15707,15709,15711],{"class":274,"line":1556},[272,15705,15706],{"class":366},"    canSlideFollowing",[272,15708,13022],{"class":289},[272,15710,879],{"class":801},[272,15712,373],{"class":289},[272,15714,15715,15717,15719,15721,15724,15726,15729,15731],{"class":274,"line":1564},[272,15716,3222],{"class":278},[272,15718,13609],{"class":289},[272,15720,15687],{"class":282},[272,15722,15723],{"class":289}," \u003C",[272,15725,13609],{"class":289},[272,15727,15728],{"class":282},"slideListElements",[272,15730,430],{"class":289},[272,15732,15733],{"class":282},"length\n",[272,15735,15736],{"class":274,"line":1572},[272,15737,1140],{"class":289},[272,15739,15740],{"class":274,"line":1580},[272,15741,302],{"emptyLinePlaceholder":169},[272,15743,15744,15747,15749,15751,15753,15756,15758,15760,15762,15764],{"class":274,"line":1588},[272,15745,15746],{"class":366},"    slideElementStyle",[272,15748,13022],{"class":289},[272,15750,310],{"class":289},[272,15752,290],{"class":289},[272,15754,15755],{"class":293},"min-width",[272,15757,403],{"class":289},[272,15759,370],{"class":289},[272,15761,819],{"class":801},[272,15763,327],{"class":289},[272,15765,373],{"class":289},[272,15767,15768,15770,15772,15774,15776,15778,15780,15782,15784,15787,15789,15791,15793],{"class":274,"line":1595},[272,15769,3222],{"class":278},[272,15771,310],{"class":289},[272,15773,290],{"class":289},[272,15775,15755],{"class":366},[272,15777,403],{"class":289},[272,15779,370],{"class":289},[272,15781,12141],{"class":289},[272,15783,12097],{"class":289},[272,15785,15786],{"class":282},"width",[272,15788,677],{"class":289},[272,15790,12159],{"class":293},[272,15792,2129],{"class":289},[272,15794,1861],{"class":289},[272,15796,15797],{"class":274,"line":1602},[272,15798,1140],{"class":289},[272,15800,15801],{"class":274,"line":1608},[272,15802,671],{"class":289},[272,15804,15805],{"class":274,"line":10233},[272,15806,302],{"emptyLinePlaceholder":169},[272,15808,15809,15811,15813],{"class":274,"line":10239},[272,15810,12083],{"class":366},[272,15812,506],{"class":289},[272,15814,373],{"class":289},[272,15816,15817,15819,15821,15823,15825,15827,15829,15831,15833,15835,15837,15839,15841,15843,15845,15847,15849,15851,15853,15855,15858,15860,15862,15865,15868,15870,15872,15874],{"class":274,"line":10245},[272,15818,14471],{"class":366},[272,15820,12097],{"class":289},[272,15822,12100],{"class":282},[272,15824,5247],{"class":366},[272,15826,403],{"class":289},[272,15828,14998],{"class":293},[272,15830,403],{"class":289},[272,15832,13644],{"class":366},[272,15834,14212],{"class":278},[272,15836,12126],{"class":801},[272,15838,188],{"class":366},[272,15840,430],{"class":289},[272,15842,2211],{"class":282},[272,15844,430],{"class":289},[272,15846,15786],{"class":282},[272,15848,3127],{"class":289},[272,15850,12141],{"class":289},[272,15852,357],{"class":282},[272,15854,12097],{"class":289},[272,15856,15857],{"class":282},"width ",[272,15859,1080],{"class":289},[272,15861,13609],{"class":289},[272,15863,15864],{"class":282},"offset) ",[272,15866,15867],{"class":289},"*",[272,15869,15555],{"class":282},[272,15871,677],{"class":289},[272,15873,12159],{"class":293},[272,15875,12162],{"class":289},[272,15877,15878],{"class":274,"line":10251},[272,15879,671],{"class":289},[272,15881,15882],{"class":274,"line":10256},[272,15883,302],{"emptyLinePlaceholder":169},[272,15885,15886,15888,15890],{"class":274,"line":10262},[272,15887,10014],{"class":366},[272,15889,370],{"class":289},[272,15891,373],{"class":289},[272,15893,15894,15897,15899,15901],{"class":274,"line":10268},[272,15895,15896],{"class":366},"    previous",[272,15898,13022],{"class":289},[272,15900,3553],{"class":801},[272,15902,373],{"class":289},[272,15904,15905,15907,15909,15912,15914,15916],{"class":274,"line":10274},[272,15906,3149],{"class":278},[272,15908,2493],{"class":366},[272,15910,15911],{"class":289},"!this.",[272,15913,15597],{"class":282},[272,15915,2317],{"class":366},[272,15917,360],{"class":289},[272,15919,15920],{"class":274,"line":10280},[272,15921,14337],{"class":278},[272,15923,15924],{"class":274,"line":10286},[272,15925,3213],{"class":289},[272,15927,15928],{"class":274,"line":10292},[272,15929,302],{"emptyLinePlaceholder":169},[272,15931,15932,15934,15937,15940,15942,15944,15946,15948],{"class":274,"line":10297},[272,15933,10032],{"class":289},[272,15935,15936],{"class":282},"transformX",[272,15938,15939],{"class":289}," +=",[272,15941,13609],{"class":289},[272,15943,15786],{"class":282},[272,15945,12270],{"class":289},[272,15947,13609],{"class":289},[272,15949,15950],{"class":282},"offset\n",[272,15952,15953,15955,15957,15959,15961,15964,15966,15968,15970,15972,15974,15976,15979,15981,15984,15987,15989,15991,15993,15995,15998],{"class":274,"line":10302},[272,15954,12113],{"class":366},[272,15956,12097],{"class":289},[272,15958,12100],{"class":282},[272,15960,430],{"class":289},[272,15962,15963],{"class":282},"slide",[272,15965,3432],{"class":278},[272,15967,12126],{"class":801},[272,15969,188],{"class":366},[272,15971,430],{"class":289},[272,15973,2211],{"class":282},[272,15975,430],{"class":289},[272,15977,15978],{"class":282},"transform",[272,15980,3127],{"class":289},[272,15982,15983],{"class":289}," `",[272,15985,15986],{"class":293},"translate(",[272,15988,2830],{"class":289},[272,15990,12097],{"class":289},[272,15992,15936],{"class":282},[272,15994,677],{"class":289},[272,15996,15997],{"class":293},"px, 0)",[272,15999,12162],{"class":289},[272,16001,16002,16004,16006],{"class":274,"line":10307},[272,16003,10032],{"class":289},[272,16005,15687],{"class":282},[272,16007,16008],{"class":289},"--\n",[272,16010,16011],{"class":274,"line":10313},[272,16012,1140],{"class":289},[272,16014,16015],{"class":274,"line":10318},[272,16016,302],{"emptyLinePlaceholder":169},[272,16018,16019,16022,16024,16026],{"class":274,"line":10324},[272,16020,16021],{"class":366},"    following",[272,16023,13022],{"class":289},[272,16025,3553],{"class":801},[272,16027,373],{"class":289},[272,16029,16030,16032,16034,16036,16038,16040],{"class":274,"line":10330},[272,16031,3149],{"class":278},[272,16033,2493],{"class":366},[272,16035,15911],{"class":289},[272,16037,15643],{"class":282},[272,16039,2317],{"class":366},[272,16041,360],{"class":289},[272,16043,16044],{"class":274,"line":10335},[272,16045,14337],{"class":278},[272,16047,16048],{"class":274,"line":10341},[272,16049,3213],{"class":289},[272,16051,16052],{"class":274,"line":10346},[272,16053,302],{"emptyLinePlaceholder":169},[272,16055,16056,16058,16060,16063,16065,16067,16069,16071],{"class":274,"line":10351},[272,16057,10032],{"class":289},[272,16059,15936],{"class":282},[272,16061,16062],{"class":289}," -=",[272,16064,13609],{"class":289},[272,16066,15786],{"class":282},[272,16068,12270],{"class":289},[272,16070,13609],{"class":289},[272,16072,15950],{"class":282},[272,16074,16075,16077,16079,16081,16083,16085,16087,16089,16091,16093,16095,16097,16099,16101,16103,16105,16107,16109,16111,16113,16115],{"class":274,"line":10357},[272,16076,12113],{"class":366},[272,16078,12097],{"class":289},[272,16080,12100],{"class":282},[272,16082,430],{"class":289},[272,16084,15963],{"class":282},[272,16086,3432],{"class":278},[272,16088,12126],{"class":801},[272,16090,188],{"class":366},[272,16092,430],{"class":289},[272,16094,2211],{"class":282},[272,16096,430],{"class":289},[272,16098,15978],{"class":282},[272,16100,3127],{"class":289},[272,16102,15983],{"class":289},[272,16104,15986],{"class":293},[272,16106,2830],{"class":289},[272,16108,12097],{"class":289},[272,16110,15936],{"class":282},[272,16112,677],{"class":289},[272,16114,15997],{"class":293},[272,16116,12162],{"class":289},[272,16118,16119,16121,16123],{"class":274,"line":10362},[272,16120,10032],{"class":289},[272,16122,15687],{"class":282},[272,16124,16125],{"class":289},"++\n",[272,16127,16128],{"class":274,"line":10367},[272,16129,1140],{"class":289},[272,16131,16132],{"class":274,"line":10373},[272,16133,671],{"class":289},[272,16135,16136,16138],{"class":274,"line":10379},[272,16137,677],{"class":289},[272,16139,680],{"class":282},[272,16141,16142,16144,16146],{"class":274,"line":10385},[272,16143,4113],{"class":289},[272,16145,4021],{"class":366},[272,16147,4038],{"class":289},[272,16149,16150],{"class":274,"line":10391},[272,16151,302],{"emptyLinePlaceholder":169},[272,16153,16154,16156,16158,16160,16162,16164,16166,16168,16170],{"class":274,"line":10396},[272,16155,3081],{"class":289},[272,16157,2211],{"class":366},[272,16159,4024],{"class":781},[272,16161,2294],{"class":289},[272,16163,2334],{"class":289},[272,16165,4206],{"class":293},[272,16167,2334],{"class":289},[272,16169,4211],{"class":781},[272,16171,4038],{"class":289},[272,16173,16174],{"class":274,"line":10401},[272,16175,16176],{"class":282},".ume-gallery {\n",[272,16178,16179],{"class":274,"line":10407},[272,16180,16181],{"class":282},"  display: flex;\n",[272,16183,16184],{"class":274,"line":10413},[272,16185,16186],{"class":282},"  justify-content: center;\n",[272,16188,16189],{"class":274,"line":10419},[272,16190,16191],{"class":282},"  align-items: center;\n",[272,16193,16194],{"class":274,"line":10425},[272,16195,302],{"emptyLinePlaceholder":169},[272,16197,16198],{"class":274,"line":10431},[272,16199,16200],{"class":282},"  @media only screen and (max-width: 940px) {\n",[272,16202,16203],{"class":274,"line":10437},[272,16204,16205],{"class":282},"    margin: 0;\n",[272,16207,16208],{"class":274,"line":10443},[272,16209,909],{"class":282},[272,16211,16212],{"class":274,"line":10449},[272,16213,302],{"emptyLinePlaceholder":169},[272,16215,16216],{"class":274,"line":10455},[272,16217,16218],{"class":282},"  .icon {\n",[272,16220,16221],{"class":274,"line":10461},[272,16222,16223],{"class":282},"    height: 24px;\n",[272,16225,16226],{"class":274,"line":10467},[272,16227,16228],{"class":282},"    width: 28px;\n",[272,16230,16231],{"class":274,"line":10472},[272,16232,909],{"class":282},[272,16234,16235],{"class":274,"line":10478},[272,16236,302],{"emptyLinePlaceholder":169},[272,16238,16239],{"class":274,"line":10484},[272,16240,16241],{"class":282},"  .clickable {\n",[272,16243,16244],{"class":274,"line":10489},[272,16245,16246],{"class":282},"    fill: #c7c7cc;\n",[272,16248,16249],{"class":274,"line":10494},[272,16250,909],{"class":282},[272,16252,16253],{"class":274,"line":10499},[272,16254,302],{"emptyLinePlaceholder":169},[272,16256,16257],{"class":274,"line":10504},[272,16258,16259],{"class":282},"  .non-clickable {\n",[272,16261,16263],{"class":274,"line":16262},133,[272,16264,16265],{"class":282},"    fill: #d1d1d6;\n",[272,16267,16269],{"class":274,"line":16268},134,[272,16270,909],{"class":282},[272,16272,16274],{"class":274,"line":16273},135,[272,16275,302],{"emptyLinePlaceholder":169},[272,16277,16279],{"class":274,"line":16278},136,[272,16280,16281],{"class":282},"  .slide-list-wrapper {\n",[272,16283,16285],{"class":274,"line":16284},137,[272,16286,12565],{"class":282},[272,16288,16290],{"class":274,"line":16289},138,[272,16291,16292],{"class":282},"    margin: 0 auto;\n",[272,16294,16296],{"class":274,"line":16295},139,[272,16297,302],{"emptyLinePlaceholder":169},[272,16299,16301],{"class":274,"line":16300},140,[272,16302,16303],{"class":282},"    .slide-list {\n",[272,16305,16307],{"class":274,"line":16306},141,[272,16308,16309],{"class":282},"      transition: 0.5s;\n",[272,16311,16313],{"class":274,"line":16312},142,[272,16314,16315],{"class":282},"      display: flex;\n",[272,16317,16319],{"class":274,"line":16318},143,[272,16320,6018],{"class":282},[272,16322,16324],{"class":274,"line":16323},144,[272,16325,909],{"class":282},[272,16327,16329],{"class":274,"line":16328},145,[272,16330,965],{"class":282},[272,16332,16334,16336,16338],{"class":274,"line":16333},146,[272,16335,4113],{"class":289},[272,16337,2211],{"class":366},[272,16339,4038],{"class":289},[11,16341,2194],{"id":2194},[15,16343,16344,16345,16347],{},"ざっと書いてきましたが、2020 年に Nuxt.js で実装してきたアニメーションを Vue.js の ",[203,16346,9266],{}," タグを使ったケースと使わなかったケースでまとめてみました。元々は OSS のライブラリを使うときのコストを下げたい、またデザインや仕様変更に対して柔軟に対応するため、自分で実装してきましたが手を動かして実装した分、多くのことを学んだと思っています。",[15,16349,16350],{},"振り返りをして思ったのは、アニメーションの実装って楽しいと再認識したことです。プログラミングに挑戦したいときっかけにもなった「作ったものが動く」という感動を思い出し、初心に返ることができました。\n少しはできることが増えたのかなと思いつつも、まだまだリッチなアニメーションだとスラスラ実装できないレベルです。来年は自分のフロント力をもっと伸ばしていける年になるといいなと思っています。",[15,16352,16353,16354,16359],{},"最後まで読んでいただき、ありがとうございました。\n(上で書いたコードは ",[80,16355,16358],{"href":16356,"rel":16357,"target":87},"https:\u002F\u002Fgithub.com\u002Foffich\u002Fanimation-collection",[84,85,86],"Github のレポジトリ","にまとめました。もし参考になったなどあれば、star してくれると嬉しいです。)",[15,16361,16362],{},"明日は STORES 予約の@yksihimoto さんによる、「next.js + Fullcalendar v5 を攻略する」です。お楽しみに。",[2211,16364,16365],{},"html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}",{"title":154,"searchDepth":155,"depth":155,"links":16367},[16368,16369,16370,16376,16380],{"id":5426,"depth":155,"text":5426},{"id":9283,"depth":155,"text":9283},{"id":9320,"depth":155,"text":9320,"children":16371},[16372,16373,16374,16375],{"id":9323,"depth":305,"text":9324},{"id":9330,"depth":305,"text":9330},{"id":9333,"depth":305,"text":9333},{"id":9336,"depth":305,"text":9336},{"id":13674,"depth":155,"text":13675,"children":16377},[16378,16379],{"id":13694,"depth":305,"text":13694},{"id":14876,"depth":305,"text":14876},{"id":2194,"depth":155,"text":2194},[2229,2230],"Nuxt.jsで実装してきたアニメーションをまとめました",{},"\u002Ftech\u002Fnuxtjs-animation","2020-12-07",{"title":9220,"description":16382},"tech\u002Fnuxtjs-animation","Y2PHiR-hDZ1xnUm5re2mB1cYUrhqBUqDbyQDJU-Uw5k",{"id":16390,"title":16391,"body":16392,"categories":16808,"description":16809,"draft":166,"extension":167,"meta":16810,"navigation":169,"path":16811,"priority":171,"publishedAt":16812,"secret":166,"seo":16813,"stem":16814,"updatedAt":16812,"__hash__":16815},"posts\u002Ftech\u002Fincrease-filesize-encoded-in-base64.md","[Nuxtjs] base64エンコードする画像のファイルサイズの上限を変更する",{"type":8,"value":16393,"toc":16802},[16394,16398,16404,16406,16409,16416,16425,16428,16431,16502,16515,16773,16783,16786,16792,16794,16799],[11,16395,16397],{"id":16396},"tl-dr","TL; DR",[15,16399,16400,16403],{},[203,16401,16402],{},"nuxt.config.js"," の build プロパティで、base64 エンコードできる画像のファイルサイズの上限を変更できる。",[11,16405,5426],{"id":5426},[15,16407,16408],{},"nuxtjs で web サービスの自社プロダクトの開発と運用をやっているエンジニアです。",[15,16410,16411,16412,16415],{},"ある日、ロゴの画像を変更してほしいとデザイナーから依頼があり、",[203,16413,16414],{},"static","ディレクトリにある画像を差し替え社内開発環境にリリースしました。しかし、ブラウザキャッシュが効いてしまい、昔のロゴが表示されてしまいました。",[15,16417,16418,16419,16424],{},"これについて、何かクエリバラメーターをつけるなどして、画像のパスを変更すれば解決します。何か別の解決方法がないかを探したところ、assets に静的ファイルをおけば、webpack が静的ファイルを base64 エンコードし、html や css に埋め込みをしてくれるみたいでした。しかし、試したところ、どうやら",[80,16420,16423],{"href":16421,"rel":16422,"target":87},"https:\u002F\u002Fja.nuxtjs.org\u002Fguide\u002Fassets\u002F#webpack",[84,85,86],"base64エンコードしてくれる画像のファイルサイズがデフォルトで1KB","と決まっているみたいです。それを変更した変更したかったのですが、やり方を探しても見つからなかったので、せっかくならと思い記事にまとめました。",[11,16426,16427],{"id":16427},"実際にどうやるか",[15,16429,16430],{},"結論から話すと、下のように書くと、base64 エンコードしてくれる静的ファイルのサイズ上限を変更できました。",[264,16432,16436],{"className":16433,"code":16434,"filename":16402,"language":16435,"meta":154,"style":154},"language-js shiki shiki-themes material-theme","module.exports = {\n  extend(config, { loaders }) {\n    \u002F\u002F これで1MB以下のassetsディレクトリにある静的ファイルがbase64エンコードされます。\n    loaders.imgUrl.limit = 100000\n  },\n}\n","js",[203,16437,16438,16447,16469,16474,16494,16498],{"__ignoreMap":154},[272,16439,16440,16443,16445],{"class":274,"line":275},[272,16441,16442],{"class":289},"module.exports",[272,16444,3127],{"class":289},[272,16446,373],{"class":289},[272,16448,16449,16452,16454,16457,16459,16461,16464,16467],{"class":274,"line":155},[272,16450,16451],{"class":366},"  extend",[272,16453,357],{"class":289},[272,16455,16456],{"class":2496},"config",[272,16458,316],{"class":289},[272,16460,310],{"class":289},[272,16462,16463],{"class":2496}," loaders",[272,16465,16466],{"class":289}," })",[272,16468,373],{"class":289},[272,16470,16471],{"class":274,"line":305},[272,16472,16473],{"class":2656},"    \u002F\u002F これで1MB以下のassetsディレクトリにある静的ファイルがbase64エンコードされます。\n",[272,16475,16476,16479,16481,16484,16486,16489,16491],{"class":274,"line":340},[272,16477,16478],{"class":282},"    loaders",[272,16480,430],{"class":289},[272,16482,16483],{"class":282},"imgUrl",[272,16485,430],{"class":289},[272,16487,16488],{"class":282},"limit",[272,16490,3127],{"class":289},[272,16492,16493],{"class":2297}," 100000\n",[272,16495,16496],{"class":274,"line":345},[272,16497,671],{"class":289},[272,16499,16500],{"class":274,"line":363},[272,16501,965],{"class":289},[15,16503,16504,16505,3413,16508,16510,16511],{},"この ",[203,16506,16507],{},"loaders",[203,16509,16483],{}," がどこから来たからというと、下のドキュメントに記載されていました。\n",[80,16512,16513],{"href":16513,"rel":16514,"target":87},"https:\u002F\u002Fja.nuxtjs.org\u002Fapi\u002Fconfiguration-build\u002F#loaders",[84,85,86],[264,16516,16519],{"className":16433,"code":16517,"filename":16518,"language":16435,"meta":154,"style":154},"\u002F\u002F loadersの中身\n{\n  file: {},\n  fontUrl: { limit: 1000 },\n  imgUrl: { limit: 1000 }, \u002F\u002F デフォルトは1KB\n  pugPlain: {},\n  vue: {\n    transformAssetUrls: {\n      video: 'src',\n      source: 'src',\n      object: 'src',\n      embed: 'src'\n    }\n  },\n  css: {},\n  cssModules: {\n    localIdentName: '[local]_[hash:base64:5]'\n  },\n  less: {},\n  sass: {\n    indentedSyntax: true\n  },\n  scss: {},\n  stylus: {},\n  vueStyle: {}\n}\n","loaders.js",[203,16520,16521,16526,16530,16540,16559,16580,16589,16598,16607,16623,16637,16652,16665,16669,16673,16682,16691,16705,16709,16718,16727,16737,16741,16750,16759,16769],{"__ignoreMap":154},[272,16522,16523],{"class":274,"line":275},[272,16524,16525],{"class":2656},"\u002F\u002F loadersの中身\n",[272,16527,16528],{"class":274,"line":155},[272,16529,360],{"class":289},[272,16531,16532,16535,16537],{"class":274,"line":305},[272,16533,16534],{"class":801},"  file",[272,16536,370],{"class":289},[272,16538,16539],{"class":289}," {},\n",[272,16541,16542,16545,16547,16549,16552,16554,16557],{"class":274,"line":340},[272,16543,16544],{"class":801},"  fontUrl",[272,16546,370],{"class":289},[272,16548,310],{"class":289},[272,16550,16551],{"class":801}," limit",[272,16553,370],{"class":289},[272,16555,16556],{"class":2297}," 1000",[272,16558,6958],{"class":289},[272,16560,16561,16564,16566,16568,16570,16572,16574,16577],{"class":274,"line":345},[272,16562,16563],{"class":801},"  imgUrl",[272,16565,370],{"class":289},[272,16567,310],{"class":289},[272,16569,16551],{"class":801},[272,16571,370],{"class":289},[272,16573,16556],{"class":2297},[272,16575,16576],{"class":289}," },",[272,16578,16579],{"class":2656}," \u002F\u002F デフォルトは1KB\n",[272,16581,16582,16585,16587],{"class":274,"line":363},[272,16583,16584],{"class":801},"  pugPlain",[272,16586,370],{"class":289},[272,16588,16539],{"class":289},[272,16590,16591,16594,16596],{"class":274,"line":376},[272,16592,16593],{"class":801},"  vue",[272,16595,370],{"class":289},[272,16597,373],{"class":289},[272,16599,16600,16603,16605],{"class":274,"line":390},[272,16601,16602],{"class":801},"    transformAssetUrls",[272,16604,370],{"class":289},[272,16606,373],{"class":289},[272,16608,16609,16612,16614,16616,16619,16621],{"class":274,"line":409},[272,16610,16611],{"class":801},"      video",[272,16613,370],{"class":289},[272,16615,290],{"class":289},[272,16617,16618],{"class":293},"src",[272,16620,403],{"class":289},[272,16622,406],{"class":289},[272,16624,16625,16627,16629,16631,16633,16635],{"class":274,"line":419},[272,16626,412],{"class":801},[272,16628,370],{"class":289},[272,16630,290],{"class":289},[272,16632,16618],{"class":293},[272,16634,403],{"class":289},[272,16636,406],{"class":289},[272,16638,16639,16642,16644,16646,16648,16650],{"class":274,"line":449},[272,16640,16641],{"class":801},"      object",[272,16643,370],{"class":289},[272,16645,290],{"class":289},[272,16647,16618],{"class":293},[272,16649,403],{"class":289},[272,16651,406],{"class":289},[272,16653,16654,16657,16659,16661,16663],{"class":274,"line":466},[272,16655,16656],{"class":801},"      embed",[272,16658,370],{"class":289},[272,16660,290],{"class":289},[272,16662,16618],{"class":293},[272,16664,297],{"class":289},[272,16666,16667],{"class":274,"line":472},[272,16668,6018],{"class":289},[272,16670,16671],{"class":274,"line":491},[272,16672,671],{"class":289},[272,16674,16675,16678,16680],{"class":274,"line":511},[272,16676,16677],{"class":801},"  css",[272,16679,370],{"class":289},[272,16681,16539],{"class":289},[272,16683,16684,16687,16689],{"class":274,"line":529},[272,16685,16686],{"class":801},"  cssModules",[272,16688,370],{"class":289},[272,16690,373],{"class":289},[272,16692,16693,16696,16698,16700,16703],{"class":274,"line":547},[272,16694,16695],{"class":801},"    localIdentName",[272,16697,370],{"class":289},[272,16699,290],{"class":289},[272,16701,16702],{"class":293},"[local]_[hash:base64:5]",[272,16704,297],{"class":289},[272,16706,16707],{"class":274,"line":565},[272,16708,671],{"class":289},[272,16710,16711,16714,16716],{"class":274,"line":592},[272,16712,16713],{"class":801},"  less",[272,16715,370],{"class":289},[272,16717,16539],{"class":289},[272,16719,16720,16723,16725],{"class":274,"line":611},[272,16721,16722],{"class":801},"  sass",[272,16724,370],{"class":289},[272,16726,373],{"class":289},[272,16728,16729,16732,16734],{"class":274,"line":629},[272,16730,16731],{"class":801},"    indentedSyntax",[272,16733,370],{"class":289},[272,16735,16736],{"class":2762}," true\n",[272,16738,16739],{"class":274,"line":648},[272,16740,671],{"class":289},[272,16742,16743,16746,16748],{"class":274,"line":658},[272,16744,16745],{"class":801},"  scss",[272,16747,370],{"class":289},[272,16749,16539],{"class":289},[272,16751,16752,16755,16757],{"class":274,"line":668},[272,16753,16754],{"class":801},"  stylus",[272,16756,370],{"class":289},[272,16758,16539],{"class":289},[272,16760,16761,16764,16766],{"class":274,"line":674},[272,16762,16763],{"class":801},"  vueStyle",[272,16765,370],{"class":289},[272,16767,16768],{"class":289}," {}\n",[272,16770,16771],{"class":274,"line":1161},[272,16772,965],{"class":289},[15,16774,16775,16776,16778,16779,16782],{},"全部のコードを追えていないため、 ",[203,16777,16483],{}," のプロパティがどう ",[203,16780,16781],{},"url-loader"," の設定と紐づいているかまではわかっていないのですが、プロパティの名前から予測ができた。実際試したところ、うまく base64 エンコードされました。",[15,16784,16785],{},"ちなみに、base64 エンコードされると html ではこのようになります。",[15,16787,16788],{},[21,16789],{"alt":16790,"src":16791},"結果","\u002Fcontent\u002Fincrease-filesize-encoded-in-base64\u002Fresult.png",[11,16793,2194],{"id":2194},[35,16795,16796],{},[38,16797,16798],{},"これで今後画像のパスを無理やり変更しなくても、画像によってエンコードした結果が変わるので、ブラウザキャッシュでファイルの中身が変更されないという問題は回避されるのかなと思いました。内容が少しニッチな気持ちもしますが、同じ問題で困った人の役に立てればと思い、qiita にまとめました。最後まで読んでいただき、ありがとうございました。",[2211,16800,16801],{},"html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .s0_hs, html code.shiki .s0_hs{--shiki-default:#546E7A;--shiki-default-font-style:italic}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .s5Dmg, html code.shiki .s5Dmg{--shiki-default:#FFCB6B}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}",{"title":154,"searchDepth":155,"depth":155,"links":16803},[16804,16805,16806,16807],{"id":16396,"depth":155,"text":16397},{"id":5426,"depth":155,"text":5426},{"id":16427,"depth":155,"text":16427},{"id":2194,"depth":155,"text":2194},[2229,2230],"nuxt.config.js のbuildプロパティで、base64エンコードできる画像のファイルサイズの上限を変更できる。",{},"\u002Ftech\u002Fincrease-filesize-encoded-in-base64","2020-01-12",{"title":16391,"description":16809},"tech\u002Fincrease-filesize-encoded-in-base64","SY_SK0u1hRjTpojzOPL4-Mbma9T6wj1OsDiPhE_AjTQ",{"id":16817,"title":16818,"body":16819,"categories":18362,"description":18364,"draft":166,"extension":167,"meta":18365,"navigation":169,"path":18366,"priority":171,"publishedAt":18367,"secret":166,"seo":18368,"stem":18369,"updatedAt":18367,"__hash__":18370},"posts\u002Ftech\u002Feffective-way-to-register-external-module-func.md","[Nuxt.js] 別ファイルで定義した関数を template で効率よく使えるようにする",{"type":8,"value":16820,"toc":18354},[16821,16825,16828,16832,16835,16841,16844,16847,16855,16858,16861,16955,17193,17196,17497,17499,17502,17601,17847,17850,18050,18346,18348,18351],[11,16822,16824],{"id":16823},"tldr","TL;DR",[15,16826,16827],{},"外部モジュールで定義した関数を直接 template で使用できないため、computed に登録することで使えるようにできる。",[11,16829,16831],{"id":16830},"why","WHY",[15,16833,16834],{},"Nuxt.js でメディアコンテンツ入稿ツール(以下: ダッシュボードツール)を開発しています。\nページやコンポーネントの JavaScript のコードが肥大化しないように、使用する関数を外部モジュールに定義しました。それをインポートしようとし、直接 template 内で使用したところ、下のエラーが発生し困っていました。",[264,16836,16839],{"className":16837,"code":16838,"language":726,"meta":154},[723],"Property or method \"helperFunc\" is not defined on the instance but referenced during render.\nMake sure to declare reactive data properties in the data option.\n",[203,16840,16838],{"__ignoreMap":154},[15,16842,16843],{},"解決したのですが、ググったところ簡単に解決策が出てこなったので、せっかくなら記事にまとめようと思いました。",[11,16845,16846],{"id":16846},"技術スタック",[35,16848,16849,16852],{},[38,16850,16851],{},"Nuxt.js 2.x",[38,16853,16854],{},"Vuetify 2.x",[11,16856,16857],{"id":16857},"具体的なケース",[15,16859,16860],{},"上の WHY に書いた、エラーコードがこちらです。\nあるモデルの属性をラジオボタンで決めてもらおうと思い、下のようにファイルを用意しました。",[264,16862,16865],{"className":16433,"code":16863,"filename":16864,"language":16435,"meta":154,"style":154},"export default {\n  contentTypeRadios() {\n    return [\n      { label: 'デフォルト', value: 0 },\n      { label: 'オプション付き', value: 1 },\n    ]\n  },\n}\n","~\u002Fhelpers\u002Findex.js",[203,16866,16867,16875,16884,16890,16918,16943,16947,16951],{"__ignoreMap":154},[272,16868,16869,16871,16873],{"class":274,"line":275},[272,16870,348],{"class":278},[272,16872,351],{"class":278},[272,16874,373],{"class":289},[272,16876,16877,16880,16882],{"class":274,"line":155},[272,16878,16879],{"class":366},"  contentTypeRadios",[272,16881,506],{"class":289},[272,16883,373],{"class":289},[272,16885,16886,16888],{"class":274,"line":305},[272,16887,3256],{"class":278},[272,16889,9078],{"class":366},[272,16891,16892,16895,16898,16900,16902,16905,16907,16909,16912,16914,16916],{"class":274,"line":340},[272,16893,16894],{"class":289},"      {",[272,16896,16897],{"class":366}," label",[272,16899,370],{"class":289},[272,16901,290],{"class":289},[272,16903,16904],{"class":293},"デフォルト",[272,16906,403],{"class":289},[272,16908,316],{"class":289},[272,16910,16911],{"class":366}," value",[272,16913,370],{"class":289},[272,16915,15531],{"class":2297},[272,16917,6958],{"class":289},[272,16919,16920,16922,16924,16926,16928,16931,16933,16935,16937,16939,16941],{"class":274,"line":345},[272,16921,16894],{"class":289},[272,16923,16897],{"class":366},[272,16925,370],{"class":289},[272,16927,290],{"class":289},[272,16929,16930],{"class":293},"オプション付き",[272,16932,403],{"class":289},[272,16934,316],{"class":289},[272,16936,16911],{"class":366},[272,16938,370],{"class":289},[272,16940,13051],{"class":2297},[272,16942,6958],{"class":289},[272,16944,16945],{"class":274,"line":363},[272,16946,13403],{"class":366},[272,16948,16949],{"class":274,"line":376},[272,16950,671],{"class":289},[272,16952,16953],{"class":274,"line":390},[272,16954,965],{"class":289},[264,16956,16959],{"className":4009,"code":16957,"filename":16958,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cv-radio-group v-model=\"contentType\" :column=\"false\" label=\"コンテンツ種別\">\n    \u003Cv-radio\n      v-for=\"(contentTypeRadio, i) in helpers.contentTypeRadios\"\n      :key=\"i\"\n      :label=\"contentTypeRadio.label\"\n      :value=\"contentTypeRadio.value\"\n      class=\"mx-2\"\n    \u002F>\n  \u003C\u002Fv-radio-group>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport helpers from '~\u002Fhelpers\u002Findex.js'\n\nexport default {\n  data() {\n    return {\n      contentType: 0,\n    }\n  },\n}\n\u003C\u002Fscript>\n","pages\u002Fexamples\u002Findex.vue",[203,16960,16961,16969,17011,17018,17032,17046,17060,17074,17088,17093,17101,17109,17113,17121,17136,17140,17148,17156,17162,17173,17177,17181,17185],{"__ignoreMap":154},[272,16962,16963,16965,16967],{"class":274,"line":275},[272,16964,3081],{"class":289},[272,16966,4128],{"class":366},[272,16968,4038],{"class":289},[272,16970,16971,16973,16976,16978,16980,16982,16985,16987,16990,16992,16994,16996,16998,17000,17002,17004,17007,17009],{"class":274,"line":155},[272,16972,4135],{"class":289},[272,16974,16975],{"class":366},"v-radio-group",[272,16977,10559],{"class":781},[272,16979,2294],{"class":289},[272,16981,2334],{"class":289},[272,16983,16984],{"class":293},"contentType",[272,16986,2334],{"class":289},[272,16988,16989],{"class":781}," :column",[272,16991,2294],{"class":289},[272,16993,2334],{"class":289},[272,16995,9303],{"class":293},[272,16997,2334],{"class":289},[272,16999,16897],{"class":781},[272,17001,2294],{"class":289},[272,17003,2334],{"class":289},[272,17005,17006],{"class":293},"コンテンツ種別",[272,17008,2334],{"class":289},[272,17010,4038],{"class":289},[272,17012,17013,17015],{"class":274,"line":305},[272,17014,4157],{"class":289},[272,17016,17017],{"class":366},"v-radio\n",[272,17019,17020,17023,17025,17027,17030],{"class":274,"line":340},[272,17021,17022],{"class":781},"      v-for",[272,17024,2294],{"class":289},[272,17026,2334],{"class":289},[272,17028,17029],{"class":293},"(contentTypeRadio, i) in helpers.contentTypeRadios",[272,17031,6108],{"class":289},[272,17033,17034,17037,17039,17041,17044],{"class":274,"line":345},[272,17035,17036],{"class":781},"      :key",[272,17038,2294],{"class":289},[272,17040,2334],{"class":289},[272,17042,17043],{"class":293},"i",[272,17045,6108],{"class":289},[272,17047,17048,17051,17053,17055,17058],{"class":274,"line":363},[272,17049,17050],{"class":781},"      :label",[272,17052,2294],{"class":289},[272,17054,2334],{"class":289},[272,17056,17057],{"class":293},"contentTypeRadio.label",[272,17059,6108],{"class":289},[272,17061,17062,17065,17067,17069,17072],{"class":274,"line":376},[272,17063,17064],{"class":781},"      :value",[272,17066,2294],{"class":289},[272,17068,2334],{"class":289},[272,17070,17071],{"class":293},"contentTypeRadio.value",[272,17073,6108],{"class":289},[272,17075,17076,17079,17081,17083,17086],{"class":274,"line":390},[272,17077,17078],{"class":781},"      class",[272,17080,2294],{"class":289},[272,17082,2334],{"class":289},[272,17084,17085],{"class":293},"mx-2",[272,17087,6108],{"class":289},[272,17089,17090],{"class":274,"line":409},[272,17091,17092],{"class":289},"    \u002F>\n",[272,17094,17095,17097,17099],{"class":274,"line":419},[272,17096,4175],{"class":289},[272,17098,16975],{"class":366},[272,17100,4038],{"class":289},[272,17102,17103,17105,17107],{"class":274,"line":449},[272,17104,4113],{"class":289},[272,17106,4128],{"class":366},[272,17108,4038],{"class":289},[272,17110,17111],{"class":274,"line":466},[272,17112,302],{"emptyLinePlaceholder":169},[272,17114,17115,17117,17119],{"class":274,"line":472},[272,17116,3081],{"class":289},[272,17118,4021],{"class":366},[272,17120,4038],{"class":289},[272,17122,17123,17125,17128,17130,17132,17134],{"class":274,"line":491},[272,17124,279],{"class":278},[272,17126,17127],{"class":282}," helpers ",[272,17129,286],{"class":278},[272,17131,290],{"class":289},[272,17133,16864],{"class":293},[272,17135,297],{"class":289},[272,17137,17138],{"class":274,"line":511},[272,17139,302],{"emptyLinePlaceholder":169},[272,17141,17142,17144,17146],{"class":274,"line":529},[272,17143,348],{"class":278},[272,17145,351],{"class":278},[272,17147,373],{"class":289},[272,17149,17150,17152,17154],{"class":274,"line":547},[272,17151,13019],{"class":366},[272,17153,506],{"class":289},[272,17155,373],{"class":289},[272,17157,17158,17160],{"class":274,"line":565},[272,17159,3256],{"class":278},[272,17161,373],{"class":289},[272,17163,17164,17167,17169,17171],{"class":274,"line":592},[272,17165,17166],{"class":366},"      contentType",[272,17168,370],{"class":289},[272,17170,15531],{"class":2297},[272,17172,406],{"class":289},[272,17174,17175],{"class":274,"line":611},[272,17176,6018],{"class":289},[272,17178,17179],{"class":274,"line":629},[272,17180,671],{"class":289},[272,17182,17183],{"class":274,"line":648},[272,17184,965],{"class":289},[272,17186,17187,17189,17191],{"class":274,"line":658},[272,17188,4113],{"class":289},[272,17190,4021],{"class":366},[272,17192,4038],{"class":289},[15,17194,17195],{},"おそらく template で使う関数自体を script タグの中に登録していないからであるが、下のように SCF に登録するのも冗長です。しかし、mixins に定義するほどのものではないしと思い、色々と調べてみました。",[264,17197,17199],{"className":4009,"code":17198,"filename":10521,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cv-container>\n    \u003Cv-layout>\n      \u003Cv-radio-group v-model=\"contentType\" :column=\"false\" label=\"コンテンツ種別\">\n        \u003Cv-radio\n          v-for=\"(contentTypeRadio, i) in contentTypeRadios\"\n          :key=\"i\"\n          :label=\"contentTypeRadio.label\"\n          :value=\"contentTypeRadio.value\"\n          class=\"mx-2\"\n       \u002F>\n      \u003C\u002Fv-radio-group>\n    \u003Cv-layout>\n  \u003Cv-container>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport helpers from '~\u002Fhelpers\u002Findex.js'\n\nexport default {\n  data() {\n    return {\n      contentType: 0,\n    }\n  },\n\n  computed: {\n    contentTypeRadios() {\n      return helpers.contentTypeRadios\n    },\n  },\n}\n\u003C\u002Fscript>\n",[203,17200,17201,17209,17218,17227,17265,17271,17285,17298,17311,17324,17337,17342,17350,17358,17366,17374,17378,17386,17400,17404,17412,17420,17426,17436,17440,17444,17448,17456,17465,17477,17481,17485,17489],{"__ignoreMap":154},[272,17202,17203,17205,17207],{"class":274,"line":275},[272,17204,3081],{"class":289},[272,17206,4128],{"class":366},[272,17208,4038],{"class":289},[272,17210,17211,17213,17216],{"class":274,"line":155},[272,17212,4135],{"class":289},[272,17214,17215],{"class":366},"v-container",[272,17217,4038],{"class":289},[272,17219,17220,17222,17225],{"class":274,"line":305},[272,17221,4157],{"class":289},[272,17223,17224],{"class":366},"v-layout",[272,17226,4038],{"class":289},[272,17228,17229,17231,17233,17235,17237,17239,17241,17243,17245,17247,17249,17251,17253,17255,17257,17259,17261,17263],{"class":274,"line":340},[272,17230,6139],{"class":289},[272,17232,16975],{"class":366},[272,17234,10559],{"class":781},[272,17236,2294],{"class":289},[272,17238,2334],{"class":289},[272,17240,16984],{"class":293},[272,17242,2334],{"class":289},[272,17244,16989],{"class":781},[272,17246,2294],{"class":289},[272,17248,2334],{"class":289},[272,17250,9303],{"class":293},[272,17252,2334],{"class":289},[272,17254,16897],{"class":781},[272,17256,2294],{"class":289},[272,17258,2334],{"class":289},[272,17260,17006],{"class":293},[272,17262,2334],{"class":289},[272,17264,4038],{"class":289},[272,17266,17267,17269],{"class":274,"line":345},[272,17268,9530],{"class":289},[272,17270,17017],{"class":366},[272,17272,17273,17276,17278,17280,17283],{"class":274,"line":363},[272,17274,17275],{"class":781},"          v-for",[272,17277,2294],{"class":289},[272,17279,2334],{"class":289},[272,17281,17282],{"class":293},"(contentTypeRadio, i) in contentTypeRadios",[272,17284,6108],{"class":289},[272,17286,17287,17290,17292,17294,17296],{"class":274,"line":376},[272,17288,17289],{"class":781},"          :key",[272,17291,2294],{"class":289},[272,17293,2334],{"class":289},[272,17295,17043],{"class":293},[272,17297,6108],{"class":289},[272,17299,17300,17303,17305,17307,17309],{"class":274,"line":390},[272,17301,17302],{"class":781},"          :label",[272,17304,2294],{"class":289},[272,17306,2334],{"class":289},[272,17308,17057],{"class":293},[272,17310,6108],{"class":289},[272,17312,17313,17316,17318,17320,17322],{"class":274,"line":409},[272,17314,17315],{"class":781},"          :value",[272,17317,2294],{"class":289},[272,17319,2334],{"class":289},[272,17321,17071],{"class":293},[272,17323,6108],{"class":289},[272,17325,17326,17329,17331,17333,17335],{"class":274,"line":419},[272,17327,17328],{"class":781},"          class",[272,17330,2294],{"class":289},[272,17332,2334],{"class":289},[272,17334,17085],{"class":293},[272,17336,6108],{"class":289},[272,17338,17339],{"class":274,"line":449},[272,17340,17341],{"class":289},"       \u002F>\n",[272,17343,17344,17346,17348],{"class":274,"line":466},[272,17345,6153],{"class":289},[272,17347,16975],{"class":366},[272,17349,4038],{"class":289},[272,17351,17352,17354,17356],{"class":274,"line":472},[272,17353,4157],{"class":289},[272,17355,17224],{"class":366},[272,17357,4038],{"class":289},[272,17359,17360,17362,17364],{"class":274,"line":491},[272,17361,4135],{"class":289},[272,17363,17215],{"class":366},[272,17365,4038],{"class":289},[272,17367,17368,17370,17372],{"class":274,"line":511},[272,17369,4113],{"class":289},[272,17371,4128],{"class":366},[272,17373,4038],{"class":289},[272,17375,17376],{"class":274,"line":529},[272,17377,302],{"emptyLinePlaceholder":169},[272,17379,17380,17382,17384],{"class":274,"line":547},[272,17381,3081],{"class":289},[272,17383,4021],{"class":366},[272,17385,4038],{"class":289},[272,17387,17388,17390,17392,17394,17396,17398],{"class":274,"line":565},[272,17389,279],{"class":278},[272,17391,17127],{"class":282},[272,17393,286],{"class":278},[272,17395,290],{"class":289},[272,17397,16864],{"class":293},[272,17399,297],{"class":289},[272,17401,17402],{"class":274,"line":592},[272,17403,302],{"emptyLinePlaceholder":169},[272,17405,17406,17408,17410],{"class":274,"line":611},[272,17407,348],{"class":278},[272,17409,351],{"class":278},[272,17411,373],{"class":289},[272,17413,17414,17416,17418],{"class":274,"line":629},[272,17415,13019],{"class":366},[272,17417,506],{"class":289},[272,17419,373],{"class":289},[272,17421,17422,17424],{"class":274,"line":648},[272,17423,3256],{"class":278},[272,17425,373],{"class":289},[272,17427,17428,17430,17432,17434],{"class":274,"line":658},[272,17429,17166],{"class":366},[272,17431,370],{"class":289},[272,17433,15531],{"class":2297},[272,17435,406],{"class":289},[272,17437,17438],{"class":274,"line":668},[272,17439,6018],{"class":289},[272,17441,17442],{"class":274,"line":674},[272,17443,671],{"class":289},[272,17445,17446],{"class":274,"line":1161},[272,17447,302],{"emptyLinePlaceholder":169},[272,17449,17450,17452,17454],{"class":274,"line":1169},[272,17451,13495],{"class":366},[272,17453,370],{"class":289},[272,17455,373],{"class":289},[272,17457,17458,17461,17463],{"class":274,"line":1177},[272,17459,17460],{"class":366},"    contentTypeRadios",[272,17462,506],{"class":289},[272,17464,373],{"class":289},[272,17466,17467,17469,17472,17474],{"class":274,"line":1184},[272,17468,3222],{"class":278},[272,17470,17471],{"class":282}," helpers",[272,17473,430],{"class":289},[272,17475,17476],{"class":282},"contentTypeRadios\n",[272,17478,17479],{"class":274,"line":1192},[272,17480,1140],{"class":289},[272,17482,17483],{"class":274,"line":1200},[272,17484,671],{"class":289},[272,17486,17487],{"class":274,"line":1208},[272,17488,965],{"class":289},[272,17490,17491,17493,17495],{"class":274,"line":1216},[272,17492,4113],{"class":289},[272,17494,4021],{"class":366},[272,17496,4038],{"class":289},[11,17498,8630],{"id":8629},[15,17500,17501],{},"解決策としては、computed に登録するだけでした。ポイントは export するときに関数で返すことです。",[264,17503,17505],{"className":16433,"code":17504,"filename":16864,"language":16435,"meta":154,"style":154},"const contentTypeRadios = () => {\n  return [\n    { label: 'デフォルト', value: 0 },\n    { label: 'オプション付き', value: 1 },\n  ]\n}\n\nexport { contentTypeRadios }\n",[203,17506,17507,17522,17528,17553,17577,17582,17586,17590],{"__ignoreMap":154},[272,17508,17509,17511,17514,17516,17518,17520],{"class":274,"line":275},[272,17510,2288],{"class":781},[272,17512,17513],{"class":282}," contentTypeRadios ",[272,17515,2294],{"class":289},[272,17517,5750],{"class":289},[272,17519,3089],{"class":781},[272,17521,373],{"class":289},[272,17523,17524,17526],{"class":274,"line":155},[272,17525,3096],{"class":278},[272,17527,9078],{"class":366},[272,17529,17530,17533,17535,17537,17539,17541,17543,17545,17547,17549,17551],{"class":274,"line":305},[272,17531,17532],{"class":289},"    {",[272,17534,16897],{"class":366},[272,17536,370],{"class":289},[272,17538,290],{"class":289},[272,17540,16904],{"class":293},[272,17542,403],{"class":289},[272,17544,316],{"class":289},[272,17546,16911],{"class":366},[272,17548,370],{"class":289},[272,17550,15531],{"class":2297},[272,17552,6958],{"class":289},[272,17554,17555,17557,17559,17561,17563,17565,17567,17569,17571,17573,17575],{"class":274,"line":340},[272,17556,17532],{"class":289},[272,17558,16897],{"class":366},[272,17560,370],{"class":289},[272,17562,290],{"class":289},[272,17564,16930],{"class":293},[272,17566,403],{"class":289},[272,17568,316],{"class":289},[272,17570,16911],{"class":366},[272,17572,370],{"class":289},[272,17574,13051],{"class":2297},[272,17576,6958],{"class":289},[272,17578,17579],{"class":274,"line":345},[272,17580,17581],{"class":366},"  ]\n",[272,17583,17584],{"class":274,"line":363},[272,17585,965],{"class":289},[272,17587,17588],{"class":274,"line":376},[272,17589,302],{"emptyLinePlaceholder":169},[272,17591,17592,17594,17596,17599],{"class":274,"line":390},[272,17593,348],{"class":278},[272,17595,310],{"class":289},[272,17597,17598],{"class":282}," contentTypeRadios",[272,17600,1861],{"class":289},[264,17602,17605],{"className":4009,"code":17603,"filename":17604,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cv-radio-group v-model=\"contentType\" :column=\"false\" label=\"コンテンツ種別\">\n    \u003Cv-radio\n      v-for=\"(contentTypeRadio, i) in contentTypeRadios\"\n      :key=\"i\"\n      :label=\"contentTypeRadio.label\"\n      :value=\"contentTypeRadio.value\"\n      class=\"mx-2\"\n    \u002F>\n  \u003C\u002Fv-radio-group>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport { contentTypeRadios } from '~\u002Fhelpers\u002Findex.js'\n\nexport default {\n  data() {\n    return {\n      contentType: 0,\n    }\n  },\n\n  computed: {\n    contentTypeRadios,\n  },\n}\n\u003C\u002Fscript>\n","radio-group.vue",[203,17606,17607,17615,17653,17659,17671,17683,17695,17707,17719,17723,17731,17739,17743,17751,17769,17773,17781,17789,17795,17805,17809,17813,17817,17825,17831,17835,17839],{"__ignoreMap":154},[272,17608,17609,17611,17613],{"class":274,"line":275},[272,17610,3081],{"class":289},[272,17612,4128],{"class":366},[272,17614,4038],{"class":289},[272,17616,17617,17619,17621,17623,17625,17627,17629,17631,17633,17635,17637,17639,17641,17643,17645,17647,17649,17651],{"class":274,"line":155},[272,17618,4135],{"class":289},[272,17620,16975],{"class":366},[272,17622,10559],{"class":781},[272,17624,2294],{"class":289},[272,17626,2334],{"class":289},[272,17628,16984],{"class":293},[272,17630,2334],{"class":289},[272,17632,16989],{"class":781},[272,17634,2294],{"class":289},[272,17636,2334],{"class":289},[272,17638,9303],{"class":293},[272,17640,2334],{"class":289},[272,17642,16897],{"class":781},[272,17644,2294],{"class":289},[272,17646,2334],{"class":289},[272,17648,17006],{"class":293},[272,17650,2334],{"class":289},[272,17652,4038],{"class":289},[272,17654,17655,17657],{"class":274,"line":305},[272,17656,4157],{"class":289},[272,17658,17017],{"class":366},[272,17660,17661,17663,17665,17667,17669],{"class":274,"line":340},[272,17662,17022],{"class":781},[272,17664,2294],{"class":289},[272,17666,2334],{"class":289},[272,17668,17282],{"class":293},[272,17670,6108],{"class":289},[272,17672,17673,17675,17677,17679,17681],{"class":274,"line":345},[272,17674,17036],{"class":781},[272,17676,2294],{"class":289},[272,17678,2334],{"class":289},[272,17680,17043],{"class":293},[272,17682,6108],{"class":289},[272,17684,17685,17687,17689,17691,17693],{"class":274,"line":363},[272,17686,17050],{"class":781},[272,17688,2294],{"class":289},[272,17690,2334],{"class":289},[272,17692,17057],{"class":293},[272,17694,6108],{"class":289},[272,17696,17697,17699,17701,17703,17705],{"class":274,"line":376},[272,17698,17064],{"class":781},[272,17700,2294],{"class":289},[272,17702,2334],{"class":289},[272,17704,17071],{"class":293},[272,17706,6108],{"class":289},[272,17708,17709,17711,17713,17715,17717],{"class":274,"line":390},[272,17710,17078],{"class":781},[272,17712,2294],{"class":289},[272,17714,2334],{"class":289},[272,17716,17085],{"class":293},[272,17718,6108],{"class":289},[272,17720,17721],{"class":274,"line":409},[272,17722,17092],{"class":289},[272,17724,17725,17727,17729],{"class":274,"line":419},[272,17726,4175],{"class":289},[272,17728,16975],{"class":366},[272,17730,4038],{"class":289},[272,17732,17733,17735,17737],{"class":274,"line":449},[272,17734,4113],{"class":289},[272,17736,4128],{"class":366},[272,17738,4038],{"class":289},[272,17740,17741],{"class":274,"line":466},[272,17742,302],{"emptyLinePlaceholder":169},[272,17744,17745,17747,17749],{"class":274,"line":472},[272,17746,3081],{"class":289},[272,17748,4021],{"class":366},[272,17750,4038],{"class":289},[272,17752,17753,17755,17757,17759,17761,17763,17765,17767],{"class":274,"line":491},[272,17754,279],{"class":278},[272,17756,310],{"class":289},[272,17758,17598],{"class":282},[272,17760,327],{"class":289},[272,17762,330],{"class":278},[272,17764,290],{"class":289},[272,17766,16864],{"class":293},[272,17768,297],{"class":289},[272,17770,17771],{"class":274,"line":511},[272,17772,302],{"emptyLinePlaceholder":169},[272,17774,17775,17777,17779],{"class":274,"line":529},[272,17776,348],{"class":278},[272,17778,351],{"class":278},[272,17780,373],{"class":289},[272,17782,17783,17785,17787],{"class":274,"line":547},[272,17784,13019],{"class":366},[272,17786,506],{"class":289},[272,17788,373],{"class":289},[272,17790,17791,17793],{"class":274,"line":565},[272,17792,3256],{"class":278},[272,17794,373],{"class":289},[272,17796,17797,17799,17801,17803],{"class":274,"line":592},[272,17798,17166],{"class":366},[272,17800,370],{"class":289},[272,17802,15531],{"class":2297},[272,17804,406],{"class":289},[272,17806,17807],{"class":274,"line":611},[272,17808,6018],{"class":289},[272,17810,17811],{"class":274,"line":629},[272,17812,671],{"class":289},[272,17814,17815],{"class":274,"line":648},[272,17816,302],{"emptyLinePlaceholder":169},[272,17818,17819,17821,17823],{"class":274,"line":658},[272,17820,13495],{"class":366},[272,17822,370],{"class":289},[272,17824,373],{"class":289},[272,17826,17827,17829],{"class":274,"line":668},[272,17828,17460],{"class":282},[272,17830,406],{"class":289},[272,17832,17833],{"class":274,"line":674},[272,17834,671],{"class":289},[272,17836,17837],{"class":274,"line":1161},[272,17838,965],{"class":289},[272,17840,17841,17843,17845],{"class":274,"line":1169},[272,17842,4113],{"class":289},[272,17844,4021],{"class":366},[272,17846,4038],{"class":289},[15,17848,17849],{},"ちなみに引数が必要な場合は、下のように書きます。",[264,17851,17853],{"className":16433,"code":17852,"filename":16864,"language":16435,"meta":154,"style":154},"const contentTypeRadios = () => {\n  return (obj = null) => {\n    const radios = [\n      { label: 'デフォルト', value: 0 },\n      { label: 'オプション付き', value: 1 },\n    ]\n\n    if (obj && obj.type) {\n      radios.push({ label: 'プレミアム', value: 2 })\n    }\n\n    return radios\n  }\n}\n\nexport { contentTypeRadios }\n",[203,17854,17855,17869,17887,17898,17922,17946,17950,17954,17976,18013,18017,18021,18028,18032,18036,18040],{"__ignoreMap":154},[272,17856,17857,17859,17861,17863,17865,17867],{"class":274,"line":275},[272,17858,2288],{"class":781},[272,17860,17513],{"class":282},[272,17862,2294],{"class":289},[272,17864,5750],{"class":289},[272,17866,3089],{"class":781},[272,17868,373],{"class":289},[272,17870,17871,17873,17875,17878,17880,17883,17885],{"class":274,"line":155},[272,17872,3096],{"class":278},[272,17874,2493],{"class":289},[272,17876,17877],{"class":2496},"obj",[272,17879,3127],{"class":289},[272,17881,17882],{"class":289}," null)",[272,17884,3089],{"class":781},[272,17886,373],{"class":289},[272,17888,17889,17891,17894,17896],{"class":274,"line":305},[272,17890,3121],{"class":781},[272,17892,17893],{"class":282}," radios",[272,17895,3127],{"class":289},[272,17897,9078],{"class":366},[272,17899,17900,17902,17904,17906,17908,17910,17912,17914,17916,17918,17920],{"class":274,"line":340},[272,17901,16894],{"class":289},[272,17903,16897],{"class":366},[272,17905,370],{"class":289},[272,17907,290],{"class":289},[272,17909,16904],{"class":293},[272,17911,403],{"class":289},[272,17913,316],{"class":289},[272,17915,16911],{"class":366},[272,17917,370],{"class":289},[272,17919,15531],{"class":2297},[272,17921,6958],{"class":289},[272,17923,17924,17926,17928,17930,17932,17934,17936,17938,17940,17942,17944],{"class":274,"line":345},[272,17925,16894],{"class":289},[272,17927,16897],{"class":366},[272,17929,370],{"class":289},[272,17931,290],{"class":289},[272,17933,16930],{"class":293},[272,17935,403],{"class":289},[272,17937,316],{"class":289},[272,17939,16911],{"class":366},[272,17941,370],{"class":289},[272,17943,13051],{"class":2297},[272,17945,6958],{"class":289},[272,17947,17948],{"class":274,"line":363},[272,17949,13403],{"class":366},[272,17951,17952],{"class":274,"line":376},[272,17953,302],{"emptyLinePlaceholder":169},[272,17955,17956,17958,17960,17962,17965,17968,17970,17972,17974],{"class":274,"line":390},[272,17957,12092],{"class":278},[272,17959,2493],{"class":366},[272,17961,17877],{"class":282},[272,17963,17964],{"class":289}," &&",[272,17966,17967],{"class":282}," obj",[272,17969,430],{"class":289},[272,17971,2543],{"class":282},[272,17973,2317],{"class":366},[272,17975,360],{"class":289},[272,17977,17978,17981,17983,17986,17988,17990,17992,17994,17996,17999,18001,18003,18005,18007,18009,18011],{"class":274,"line":409},[272,17979,17980],{"class":282},"      radios",[272,17982,430],{"class":289},[272,17984,17985],{"class":354},"push",[272,17987,357],{"class":366},[272,17989,4351],{"class":289},[272,17991,16897],{"class":366},[272,17993,370],{"class":289},[272,17995,290],{"class":289},[272,17997,17998],{"class":293},"プレミアム",[272,18000,403],{"class":289},[272,18002,316],{"class":289},[272,18004,16911],{"class":366},[272,18006,370],{"class":289},[272,18008,13234],{"class":2297},[272,18010,327],{"class":289},[272,18012,680],{"class":366},[272,18014,18015],{"class":274,"line":419},[272,18016,6018],{"class":289},[272,18018,18019],{"class":274,"line":449},[272,18020,302],{"emptyLinePlaceholder":169},[272,18022,18023,18025],{"class":274,"line":466},[272,18024,3256],{"class":278},[272,18026,18027],{"class":282}," radios\n",[272,18029,18030],{"class":274,"line":472},[272,18031,909],{"class":289},[272,18033,18034],{"class":274,"line":491},[272,18035,965],{"class":289},[272,18037,18038],{"class":274,"line":511},[272,18039,302],{"emptyLinePlaceholder":169},[272,18041,18042,18044,18046,18048],{"class":274,"line":529},[272,18043,348],{"class":278},[272,18045,310],{"class":289},[272,18047,17598],{"class":282},[272,18049,1861],{"class":289},[264,18051,18053],{"className":4009,"code":18052,"filename":16958,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cv-container>\n    \u003Cv-layout>\n      \u003Cv-radio-group v-model=\"contentType\" :column=\"false\" label=\"コンテンツ種別\">\n        \u003Cv-radio\n          v-for=\"(contentTypeRadio, i) in contentTypeRadios(premiumType)\"\n          :key=\"i\"\n          :label=\"contentTypeRadio.label\"\n          :value=\"contentTypeRadio.value\"\n          class=\"mx-2\"\n       \u002F>\n      \u003C\u002Fv-radio-group>\n    \u003Cv-layout>\n  \u003Cv-container>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport helpers from '~\u002Fhelpers\u002Findex.js'\n\nexport default {\n  data() {\n    return {\n      contentType: 0,\n      premiumType: { type: 'premium' },\n    }\n  },\n\n  computed: {\n    contentTypeRadios,\n  },\n}\n\u003C\u002Fscript>\n",[203,18054,18055,18063,18071,18079,18117,18123,18136,18148,18160,18172,18184,18188,18196,18204,18212,18220,18224,18232,18246,18250,18258,18266,18272,18282,18304,18308,18312,18316,18324,18330,18334,18338],{"__ignoreMap":154},[272,18056,18057,18059,18061],{"class":274,"line":275},[272,18058,3081],{"class":289},[272,18060,4128],{"class":366},[272,18062,4038],{"class":289},[272,18064,18065,18067,18069],{"class":274,"line":155},[272,18066,4135],{"class":289},[272,18068,17215],{"class":366},[272,18070,4038],{"class":289},[272,18072,18073,18075,18077],{"class":274,"line":305},[272,18074,4157],{"class":289},[272,18076,17224],{"class":366},[272,18078,4038],{"class":289},[272,18080,18081,18083,18085,18087,18089,18091,18093,18095,18097,18099,18101,18103,18105,18107,18109,18111,18113,18115],{"class":274,"line":340},[272,18082,6139],{"class":289},[272,18084,16975],{"class":366},[272,18086,10559],{"class":781},[272,18088,2294],{"class":289},[272,18090,2334],{"class":289},[272,18092,16984],{"class":293},[272,18094,2334],{"class":289},[272,18096,16989],{"class":781},[272,18098,2294],{"class":289},[272,18100,2334],{"class":289},[272,18102,9303],{"class":293},[272,18104,2334],{"class":289},[272,18106,16897],{"class":781},[272,18108,2294],{"class":289},[272,18110,2334],{"class":289},[272,18112,17006],{"class":293},[272,18114,2334],{"class":289},[272,18116,4038],{"class":289},[272,18118,18119,18121],{"class":274,"line":345},[272,18120,9530],{"class":289},[272,18122,17017],{"class":366},[272,18124,18125,18127,18129,18131,18134],{"class":274,"line":363},[272,18126,17275],{"class":781},[272,18128,2294],{"class":289},[272,18130,2334],{"class":289},[272,18132,18133],{"class":293},"(contentTypeRadio, i) in contentTypeRadios(premiumType)",[272,18135,6108],{"class":289},[272,18137,18138,18140,18142,18144,18146],{"class":274,"line":376},[272,18139,17289],{"class":781},[272,18141,2294],{"class":289},[272,18143,2334],{"class":289},[272,18145,17043],{"class":293},[272,18147,6108],{"class":289},[272,18149,18150,18152,18154,18156,18158],{"class":274,"line":390},[272,18151,17302],{"class":781},[272,18153,2294],{"class":289},[272,18155,2334],{"class":289},[272,18157,17057],{"class":293},[272,18159,6108],{"class":289},[272,18161,18162,18164,18166,18168,18170],{"class":274,"line":409},[272,18163,17315],{"class":781},[272,18165,2294],{"class":289},[272,18167,2334],{"class":289},[272,18169,17071],{"class":293},[272,18171,6108],{"class":289},[272,18173,18174,18176,18178,18180,18182],{"class":274,"line":419},[272,18175,17328],{"class":781},[272,18177,2294],{"class":289},[272,18179,2334],{"class":289},[272,18181,17085],{"class":293},[272,18183,6108],{"class":289},[272,18185,18186],{"class":274,"line":449},[272,18187,17341],{"class":289},[272,18189,18190,18192,18194],{"class":274,"line":466},[272,18191,6153],{"class":289},[272,18193,16975],{"class":366},[272,18195,4038],{"class":289},[272,18197,18198,18200,18202],{"class":274,"line":472},[272,18199,4157],{"class":289},[272,18201,17224],{"class":366},[272,18203,4038],{"class":289},[272,18205,18206,18208,18210],{"class":274,"line":491},[272,18207,4135],{"class":289},[272,18209,17215],{"class":366},[272,18211,4038],{"class":289},[272,18213,18214,18216,18218],{"class":274,"line":511},[272,18215,4113],{"class":289},[272,18217,4128],{"class":366},[272,18219,4038],{"class":289},[272,18221,18222],{"class":274,"line":529},[272,18223,302],{"emptyLinePlaceholder":169},[272,18225,18226,18228,18230],{"class":274,"line":547},[272,18227,3081],{"class":289},[272,18229,4021],{"class":366},[272,18231,4038],{"class":289},[272,18233,18234,18236,18238,18240,18242,18244],{"class":274,"line":565},[272,18235,279],{"class":278},[272,18237,17127],{"class":282},[272,18239,286],{"class":278},[272,18241,290],{"class":289},[272,18243,16864],{"class":293},[272,18245,297],{"class":289},[272,18247,18248],{"class":274,"line":592},[272,18249,302],{"emptyLinePlaceholder":169},[272,18251,18252,18254,18256],{"class":274,"line":611},[272,18253,348],{"class":278},[272,18255,351],{"class":278},[272,18257,373],{"class":289},[272,18259,18260,18262,18264],{"class":274,"line":629},[272,18261,13019],{"class":366},[272,18263,506],{"class":289},[272,18265,373],{"class":289},[272,18267,18268,18270],{"class":274,"line":648},[272,18269,3256],{"class":278},[272,18271,373],{"class":289},[272,18273,18274,18276,18278,18280],{"class":274,"line":658},[272,18275,17166],{"class":366},[272,18277,370],{"class":289},[272,18279,15531],{"class":2297},[272,18281,406],{"class":289},[272,18283,18284,18287,18289,18291,18293,18295,18297,18300,18302],{"class":274,"line":668},[272,18285,18286],{"class":366},"      premiumType",[272,18288,370],{"class":289},[272,18290,310],{"class":289},[272,18292,752],{"class":366},[272,18294,370],{"class":289},[272,18296,290],{"class":289},[272,18298,18299],{"class":293},"premium",[272,18301,403],{"class":289},[272,18303,6958],{"class":289},[272,18305,18306],{"class":274,"line":674},[272,18307,6018],{"class":289},[272,18309,18310],{"class":274,"line":1161},[272,18311,671],{"class":289},[272,18313,18314],{"class":274,"line":1169},[272,18315,302],{"emptyLinePlaceholder":169},[272,18317,18318,18320,18322],{"class":274,"line":1177},[272,18319,13495],{"class":366},[272,18321,370],{"class":289},[272,18323,373],{"class":289},[272,18325,18326,18328],{"class":274,"line":1184},[272,18327,17460],{"class":282},[272,18329,406],{"class":289},[272,18331,18332],{"class":274,"line":1192},[272,18333,671],{"class":289},[272,18335,18336],{"class":274,"line":1200},[272,18337,965],{"class":289},[272,18339,18340,18342,18344],{"class":274,"line":1208},[272,18341,4113],{"class":289},[272,18343,4021],{"class":366},[272,18345,4038],{"class":289},[11,18347,2194],{"id":2194},[15,18349,18350],{},"いかかだったでしょうか。これで無理やり computed に登録しなくてもよくなり、記述量が減りました。これからも積極的に使っていきます。最後までお読みくださりありがとうございました。",[2211,18352,18353],{},"html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}",{"title":154,"searchDepth":155,"depth":155,"links":18355},[18356,18357,18358,18359,18360,18361],{"id":16823,"depth":155,"text":16824},{"id":16830,"depth":155,"text":16831},{"id":16846,"depth":155,"text":16846},{"id":16857,"depth":155,"text":16857},{"id":8629,"depth":155,"text":8630},{"id":2194,"depth":155,"text":2194},[2229,5403,2230,18363],"JavaScript","別ファイルで定義した関数を直接 template で使用することはできないので、computed に登録することで使えるようにできる。",{},"\u002Ftech\u002Feffective-way-to-register-external-module-func","2020-01-06",{"title":16818,"description":18364},"tech\u002Feffective-way-to-register-external-module-func","ivMjyHif6e-uh0jhiaSBsn43EQ1_xocAOqn1NAzYfh8",{"id":18372,"title":18373,"body":18374,"categories":19708,"description":19710,"draft":166,"extension":167,"meta":19711,"navigation":169,"path":19712,"priority":171,"publishedAt":19713,"secret":166,"seo":19714,"stem":19715,"updatedAt":19713,"__hash__":19716},"posts\u002Ftech\u002Fvee-validate-custom-rule.md","[Vue.js (Nuxt.js) ] VeeValidateでカスタムルールを作ってみた",{"type":8,"value":18375,"toc":19699},[18376,18378,18387,18389,18392,18401,18404,18407,18409,18417,18420,18423,18426,18434,18614,18623,18774,18777,19169,19172,19175,19683,19686,19691,19693,19696],[11,18377,16824],{"id":16823},[15,18379,18380,18381,18386],{},"自分が業務で使用している ",[80,18382,18385],{"href":18383,"rel":18384,"target":87},"https:\u002F\u002Fvee-validate.logaretm.com",[84,85,86],"VeeValidate 3.x"," のカスタムルールをまとめました。",[11,18388,5426],{"id":5426},[15,18390,18391],{},"自分はメディア運営会社のエンジニアとして働いているもので、メディアのコンテンツを入稿するツールを Nuxt.js で開発や運用しています。入稿されるデータに不整合が起きないように、データ作成\u002F更新前のバリデーションには気を使っています。バリデーションライブラリでは、VeeValidate を使用しています。",[15,18393,18394,18395,18400],{},"フィールドが多いデータ関しては、",[80,18396,18399],{"href":18397,"rel":18398,"target":87},"https:\u002F\u002Fvee-validate.logaretm.com\u002Fv3\u002Fguide\u002Frules.html",[84,85,86],"デフォルトで提供されているvee-validateのルール","だけだと対応できなく、色々とカスタムで実装しました。カスタムルールの作り方が見つからなかったので、今後の議事録のためにも、作り方などまとめました。",[11,18402,18403],{"id":18403},"対象者",[15,18405,18406],{},"VeeValidate は使ったことあり、これからカスタムルールをどう実装していく方。",[11,18408,16846],{"id":16846},[35,18410,18411,18413,18415],{},[38,18412,16851],{},[38,18414,16854],{},[38,18416,18385],{},[11,18418,18419],{"id":18419},"カスタムルールの作り方",[15,18421,18422],{},"ここでは、VeeValidate 3.x をどうやって Nuxt.js で使えるようにすればいいのかは割愛します。",[15,18424,18425],{},"まずは VeeValidate を Nuxt.js で使えるようにするためのプラグインを用意します。",[15,18427,18428,4535,18430,18433],{},[203,18429,16402],{},[203,18431,18432],{},"plugins"," プロパティで読み込みます。",[264,18435,18438],{"className":16433,"code":18436,"filename":18437,"language":16435,"meta":154,"style":154},"\u002F\u002F vee-validateからルールを拡張できる関数をインポート\nimport { extend } from 'vee-validate'\n\n\u002F\u002F vee-validateがデフォルトで用意してくれているルールをインポート\nimport * as Rules from 'vee-validate\u002Fdist\u002Frules'\n\n\u002F\u002F 自分が実装したvee-validateのカスタムルールをインポート\nimport * as CustomRules from '~\u002Futils\u002Fvalidation-custom-rules.js'\n\nfor (const rule in Rules) {\n  extend(rule, Rules[rule])\n}\n\nfor (const rule in CustomRules) {\n  extend(rule, CustomRules[rule])\n}\n","plugin\u002Fvee-validate.js",[203,18439,18440,18445,18465,18469,18474,18494,18498,18503,18523,18527,18546,18566,18570,18574,18591,18610],{"__ignoreMap":154},[272,18441,18442],{"class":274,"line":275},[272,18443,18444],{"class":2656},"\u002F\u002F vee-validateからルールを拡張できる関数をインポート\n",[272,18446,18447,18449,18451,18454,18456,18458,18460,18463],{"class":274,"line":155},[272,18448,279],{"class":278},[272,18450,310],{"class":289},[272,18452,18453],{"class":282}," extend",[272,18455,327],{"class":289},[272,18457,330],{"class":278},[272,18459,290],{"class":289},[272,18461,18462],{"class":293},"vee-validate",[272,18464,297],{"class":289},[272,18466,18467],{"class":274,"line":305},[272,18468,302],{"emptyLinePlaceholder":169},[272,18470,18471],{"class":274,"line":340},[272,18472,18473],{"class":2656},"\u002F\u002F vee-validateがデフォルトで用意してくれているルールをインポート\n",[272,18475,18476,18478,18480,18482,18485,18487,18489,18492],{"class":274,"line":345},[272,18477,279],{"class":278},[272,18479,3429],{"class":289},[272,18481,3432],{"class":278},[272,18483,18484],{"class":282}," Rules ",[272,18486,286],{"class":278},[272,18488,290],{"class":289},[272,18490,18491],{"class":293},"vee-validate\u002Fdist\u002Frules",[272,18493,297],{"class":289},[272,18495,18496],{"class":274,"line":363},[272,18497,302],{"emptyLinePlaceholder":169},[272,18499,18500],{"class":274,"line":376},[272,18501,18502],{"class":2656},"\u002F\u002F 自分が実装したvee-validateのカスタムルールをインポート\n",[272,18504,18505,18507,18509,18511,18514,18516,18518,18521],{"class":274,"line":390},[272,18506,279],{"class":278},[272,18508,3429],{"class":289},[272,18510,3432],{"class":278},[272,18512,18513],{"class":282}," CustomRules ",[272,18515,286],{"class":278},[272,18517,290],{"class":289},[272,18519,18520],{"class":293},"~\u002Futils\u002Fvalidation-custom-rules.js",[272,18522,297],{"class":289},[272,18524,18525],{"class":274,"line":409},[272,18526,302],{"emptyLinePlaceholder":169},[272,18528,18529,18531,18533,18535,18538,18541,18544],{"class":274,"line":419},[272,18530,8869],{"class":278},[272,18532,2493],{"class":282},[272,18534,2288],{"class":781},[272,18536,18537],{"class":282}," rule ",[272,18539,18540],{"class":289},"in",[272,18542,18543],{"class":282}," Rules) ",[272,18545,360],{"class":289},[272,18547,18548,18550,18552,18555,18557,18560,18562,18564],{"class":274,"line":449},[272,18549,16451],{"class":354},[272,18551,357],{"class":366},[272,18553,18554],{"class":282},"rule",[272,18556,316],{"class":289},[272,18558,18559],{"class":282}," Rules",[272,18561,5247],{"class":366},[272,18563,18554],{"class":282},[272,18565,2551],{"class":366},[272,18567,18568],{"class":274,"line":466},[272,18569,965],{"class":289},[272,18571,18572],{"class":274,"line":472},[272,18573,302],{"emptyLinePlaceholder":169},[272,18575,18576,18578,18580,18582,18584,18586,18589],{"class":274,"line":491},[272,18577,8869],{"class":278},[272,18579,2493],{"class":282},[272,18581,2288],{"class":781},[272,18583,18537],{"class":282},[272,18585,18540],{"class":289},[272,18587,18588],{"class":282}," CustomRules) ",[272,18590,360],{"class":289},[272,18592,18593,18595,18597,18599,18601,18604,18606,18608],{"class":274,"line":511},[272,18594,16451],{"class":354},[272,18596,357],{"class":366},[272,18598,18554],{"class":282},[272,18600,316],{"class":289},[272,18602,18603],{"class":282}," CustomRules",[272,18605,5247],{"class":366},[272,18607,18554],{"class":282},[272,18609,2551],{"class":366},[272,18611,18612],{"class":274,"line":529},[272,18613,965],{"class":289},[15,18615,18616,18617,18622],{},"そしてカスタムルールを下のように定義します。",[80,18618,18621],{"href":18619,"rel":18620,"target":87},"https:\u002F\u002Fvee-validate.logaretm.com\u002Fv3\u002Fadvanced\u002Fcross-field-validation.html#cross-field-validation",[84,85,86],"Cross Field Validation"," のページを参考にしました。",[264,18624,18627],{"className":16433,"code":18625,"filename":18626,"language":16435,"meta":154,"style":154},"const customRule = {\n  \u002F\u002F ルールを書くときに使う引数。\n  params: ['compare'],\n\n  \u002F\u002F バリデーションロジック\n  validate(field, { compare }) {\n    return true \u002F\u002F or false true: バリデーションエラーなし, false: バリデーションエラーあり\n  },\n\n  \u002F\u002F バリデーションエラーメッセージ\n  message(field, { compare }){\n    return `validation error. ${field}`\n  },\n}\n\nexport { customRule }\n","utils\u002Fvalidation-custom-rules.js",[203,18628,18629,18640,18645,18665,18669,18674,18695,18704,18708,18712,18717,18735,18751,18755,18759,18763],{"__ignoreMap":154},[272,18630,18631,18633,18636,18638],{"class":274,"line":275},[272,18632,2288],{"class":781},[272,18634,18635],{"class":282}," customRule ",[272,18637,2294],{"class":289},[272,18639,373],{"class":289},[272,18641,18642],{"class":274,"line":155},[272,18643,18644],{"class":2656},"  \u002F\u002F ルールを書くときに使う引数。\n",[272,18646,18647,18650,18652,18654,18656,18659,18661,18663],{"class":274,"line":305},[272,18648,18649],{"class":366},"  params",[272,18651,370],{"class":289},[272,18653,3313],{"class":282},[272,18655,403],{"class":289},[272,18657,18658],{"class":293},"compare",[272,18660,403],{"class":289},[272,18662,5019],{"class":282},[272,18664,406],{"class":289},[272,18666,18667],{"class":274,"line":340},[272,18668,302],{"emptyLinePlaceholder":169},[272,18670,18671],{"class":274,"line":345},[272,18672,18673],{"class":2656},"  \u002F\u002F バリデーションロジック\n",[272,18675,18676,18679,18681,18684,18686,18688,18691,18693],{"class":274,"line":363},[272,18677,18678],{"class":366},"  validate",[272,18680,357],{"class":289},[272,18682,18683],{"class":2496},"field",[272,18685,316],{"class":289},[272,18687,310],{"class":289},[272,18689,18690],{"class":2496}," compare",[272,18692,16466],{"class":289},[272,18694,373],{"class":289},[272,18696,18697,18699,18701],{"class":274,"line":376},[272,18698,3256],{"class":278},[272,18700,3513],{"class":2762},[272,18702,18703],{"class":2656}," \u002F\u002F or false true: バリデーションエラーなし, false: バリデーションエラーあり\n",[272,18705,18706],{"class":274,"line":390},[272,18707,671],{"class":289},[272,18709,18710],{"class":274,"line":409},[272,18711,302],{"emptyLinePlaceholder":169},[272,18713,18714],{"class":274,"line":419},[272,18715,18716],{"class":2656},"  \u002F\u002F バリデーションエラーメッセージ\n",[272,18718,18719,18722,18724,18726,18728,18730,18732],{"class":274,"line":449},[272,18720,18721],{"class":366},"  message",[272,18723,357],{"class":289},[272,18725,18683],{"class":2496},[272,18727,316],{"class":289},[272,18729,310],{"class":289},[272,18731,18690],{"class":2496},[272,18733,18734],{"class":289}," }){\n",[272,18736,18737,18739,18741,18744,18746,18748],{"class":274,"line":466},[272,18738,3256],{"class":278},[272,18740,15983],{"class":289},[272,18742,18743],{"class":293},"validation error. ",[272,18745,2830],{"class":289},[272,18747,18683],{"class":282},[272,18749,18750],{"class":289},"}`\n",[272,18752,18753],{"class":274,"line":472},[272,18754,671],{"class":289},[272,18756,18757],{"class":274,"line":491},[272,18758,965],{"class":289},[272,18760,18761],{"class":274,"line":511},[272,18762,302],{"emptyLinePlaceholder":169},[272,18764,18765,18767,18769,18772],{"class":274,"line":529},[272,18766,348],{"class":278},[272,18768,310],{"class":289},[272,18770,18771],{"class":282}," customRule",[272,18773,1861],{"class":289},[15,18775,18776],{},"プロジェクトで実装したカスタムルールの一部を記載。",[264,18778,18780],{"className":16433,"code":18779,"filename":18626,"language":16435,"meta":154,"style":154},"\u002F**\n * 数字が指定した桁数以下か検証する\n * @param max 最大桁数\n *\u002F\nconst maxDigits = {\n  params: ['max'],\n\n  validate(value, { max }) {\n    return value ? String(value).length \u003C= max : true\n  },\n\n  message(field, { max }) {\n    return `${field}は${max}桁以下でなければなりません`\n  },\n}\n\n\u002F**\n * コレクションの要素数が指定していた数以下かを検証する\n * @param maxLength 最大要素数\n *\u002F\nconst collectionMaxLength = {\n  params: ['maxLength'],\n\n  validate(value, { maxLength }) {\n    if (!Array.isArray(value)) {\n      return false\n    }\n\n    return value.length \u003C= maxLength\n  },\n\n  message(field, { maxLength }) {\n    return `${field}は${maxLength}つまでしか選択することができません。`\n  },\n}\n\nexport { maxDigits, collectionMaxLength }\n",[203,18781,18782,18787,18792,18810,18815,18826,18845,18849,18867,18897,18901,18905,18923,18947,18951,18955,18959,18963,18968,18982,18986,18997,19016,19020,19038,19062,19069,19073,19077,19092,19096,19100,19118,19141,19145,19149,19153],{"__ignoreMap":154},[272,18783,18784],{"class":274,"line":275},[272,18785,18786],{"class":2656},"\u002F**\n",[272,18788,18789],{"class":274,"line":155},[272,18790,18791],{"class":2656}," * 数字が指定した桁数以下か検証する\n",[272,18793,18794,18797,18800,18804,18807],{"class":274,"line":305},[272,18795,18796],{"class":2656}," * ",[272,18798,18799],{"class":278},"@",[272,18801,18803],{"class":18802},"sVyDW","param",[272,18805,18806],{"class":2496}," max",[272,18808,18809],{"class":2656}," 最大桁数\n",[272,18811,18812],{"class":274,"line":340},[272,18813,18814],{"class":2656}," *\u002F\n",[272,18816,18817,18819,18822,18824],{"class":274,"line":345},[272,18818,2288],{"class":781},[272,18820,18821],{"class":282}," maxDigits ",[272,18823,2294],{"class":289},[272,18825,373],{"class":289},[272,18827,18828,18830,18832,18834,18836,18839,18841,18843],{"class":274,"line":363},[272,18829,18649],{"class":366},[272,18831,370],{"class":289},[272,18833,3313],{"class":282},[272,18835,403],{"class":289},[272,18837,18838],{"class":293},"max",[272,18840,403],{"class":289},[272,18842,5019],{"class":282},[272,18844,406],{"class":289},[272,18846,18847],{"class":274,"line":376},[272,18848,302],{"emptyLinePlaceholder":169},[272,18850,18851,18853,18855,18857,18859,18861,18863,18865],{"class":274,"line":390},[272,18852,18678],{"class":366},[272,18854,357],{"class":289},[272,18856,2529],{"class":2496},[272,18858,316],{"class":289},[272,18860,310],{"class":289},[272,18862,18806],{"class":2496},[272,18864,16466],{"class":289},[272,18866,373],{"class":289},[272,18868,18869,18871,18873,18875,18878,18880,18882,18884,18886,18888,18891,18893,18895],{"class":274,"line":409},[272,18870,3256],{"class":278},[272,18872,16911],{"class":282},[272,18874,2536],{"class":289},[272,18876,18877],{"class":354}," String",[272,18879,357],{"class":366},[272,18881,2529],{"class":282},[272,18883,188],{"class":366},[272,18885,430],{"class":289},[272,18887,13457],{"class":282},[272,18889,18890],{"class":289}," \u003C=",[272,18892,18806],{"class":282},[272,18894,2546],{"class":289},[272,18896,16736],{"class":2762},[272,18898,18899],{"class":274,"line":419},[272,18900,671],{"class":289},[272,18902,18903],{"class":274,"line":449},[272,18904,302],{"emptyLinePlaceholder":169},[272,18906,18907,18909,18911,18913,18915,18917,18919,18921],{"class":274,"line":466},[272,18908,18721],{"class":366},[272,18910,357],{"class":289},[272,18912,18683],{"class":2496},[272,18914,316],{"class":289},[272,18916,310],{"class":289},[272,18918,18806],{"class":2496},[272,18920,16466],{"class":289},[272,18922,373],{"class":289},[272,18924,18925,18927,18929,18931,18933,18936,18938,18940,18942,18945],{"class":274,"line":472},[272,18926,3256],{"class":278},[272,18928,12141],{"class":289},[272,18930,18683],{"class":282},[272,18932,677],{"class":289},[272,18934,18935],{"class":293},"は",[272,18937,2830],{"class":289},[272,18939,18838],{"class":282},[272,18941,677],{"class":289},[272,18943,18944],{"class":293},"桁以下でなければなりません",[272,18946,12162],{"class":289},[272,18948,18949],{"class":274,"line":491},[272,18950,671],{"class":289},[272,18952,18953],{"class":274,"line":511},[272,18954,965],{"class":289},[272,18956,18957],{"class":274,"line":529},[272,18958,302],{"emptyLinePlaceholder":169},[272,18960,18961],{"class":274,"line":547},[272,18962,18786],{"class":2656},[272,18964,18965],{"class":274,"line":565},[272,18966,18967],{"class":2656}," * コレクションの要素数が指定していた数以下かを検証する\n",[272,18969,18970,18972,18974,18976,18979],{"class":274,"line":592},[272,18971,18796],{"class":2656},[272,18973,18799],{"class":278},[272,18975,18803],{"class":18802},[272,18977,18978],{"class":2496}," maxLength",[272,18980,18981],{"class":2656}," 最大要素数\n",[272,18983,18984],{"class":274,"line":611},[272,18985,18814],{"class":2656},[272,18987,18988,18990,18993,18995],{"class":274,"line":629},[272,18989,2288],{"class":781},[272,18991,18992],{"class":282}," collectionMaxLength ",[272,18994,2294],{"class":289},[272,18996,373],{"class":289},[272,18998,18999,19001,19003,19005,19007,19010,19012,19014],{"class":274,"line":648},[272,19000,18649],{"class":366},[272,19002,370],{"class":289},[272,19004,3313],{"class":282},[272,19006,403],{"class":289},[272,19008,19009],{"class":293},"maxLength",[272,19011,403],{"class":289},[272,19013,5019],{"class":282},[272,19015,406],{"class":289},[272,19017,19018],{"class":274,"line":658},[272,19019,302],{"emptyLinePlaceholder":169},[272,19021,19022,19024,19026,19028,19030,19032,19034,19036],{"class":274,"line":668},[272,19023,18678],{"class":366},[272,19025,357],{"class":289},[272,19027,2529],{"class":2496},[272,19029,316],{"class":289},[272,19031,310],{"class":289},[272,19033,18978],{"class":2496},[272,19035,16466],{"class":289},[272,19037,373],{"class":289},[272,19039,19040,19042,19044,19046,19049,19051,19054,19056,19058,19060],{"class":274,"line":674},[272,19041,12092],{"class":278},[272,19043,2493],{"class":366},[272,19045,4750],{"class":289},[272,19047,19048],{"class":282},"Array",[272,19050,430],{"class":289},[272,19052,19053],{"class":354},"isArray",[272,19055,357],{"class":366},[272,19057,2529],{"class":282},[272,19059,3578],{"class":366},[272,19061,360],{"class":289},[272,19063,19064,19066],{"class":274,"line":1161},[272,19065,3222],{"class":278},[272,19067,19068],{"class":2762}," false\n",[272,19070,19071],{"class":274,"line":1169},[272,19072,6018],{"class":289},[272,19074,19075],{"class":274,"line":1177},[272,19076,302],{"emptyLinePlaceholder":169},[272,19078,19079,19081,19083,19085,19087,19089],{"class":274,"line":1184},[272,19080,3256],{"class":278},[272,19082,16911],{"class":282},[272,19084,430],{"class":289},[272,19086,13457],{"class":282},[272,19088,18890],{"class":289},[272,19090,19091],{"class":282}," maxLength\n",[272,19093,19094],{"class":274,"line":1192},[272,19095,671],{"class":289},[272,19097,19098],{"class":274,"line":1200},[272,19099,302],{"emptyLinePlaceholder":169},[272,19101,19102,19104,19106,19108,19110,19112,19114,19116],{"class":274,"line":1208},[272,19103,18721],{"class":366},[272,19105,357],{"class":289},[272,19107,18683],{"class":2496},[272,19109,316],{"class":289},[272,19111,310],{"class":289},[272,19113,18978],{"class":2496},[272,19115,16466],{"class":289},[272,19117,373],{"class":289},[272,19119,19120,19122,19124,19126,19128,19130,19132,19134,19136,19139],{"class":274,"line":1216},[272,19121,3256],{"class":278},[272,19123,12141],{"class":289},[272,19125,18683],{"class":282},[272,19127,677],{"class":289},[272,19129,18935],{"class":293},[272,19131,2830],{"class":289},[272,19133,19009],{"class":282},[272,19135,677],{"class":289},[272,19137,19138],{"class":293},"つまでしか選択することができません。",[272,19140,12162],{"class":289},[272,19142,19143],{"class":274,"line":1221},[272,19144,671],{"class":289},[272,19146,19147],{"class":274,"line":1229},[272,19148,965],{"class":289},[272,19150,19151],{"class":274,"line":1237},[272,19152,302],{"emptyLinePlaceholder":169},[272,19154,19155,19157,19159,19162,19164,19167],{"class":274,"line":1245},[272,19156,348],{"class":278},[272,19158,310],{"class":289},[272,19160,19161],{"class":282}," maxDigits",[272,19163,316],{"class":289},[272,19165,19166],{"class":282}," collectionMaxLength",[272,19168,1861],{"class":289},[11,19170,19171],{"id":19171},"実際にどう使うか",[15,19173,19174],{},"実際にコンポーネントでどうカスタムルールを使うかを記載します。",[264,19176,19179],{"className":4009,"code":19177,"filename":19178,"language":4012,"meta":154,"style":154},"\u003Ctemplate>\n  \u003Cv-row justify=\"center\">\n    \u003Cv-col cols=\"12\">\n      \u003C!-- rulesを文字列で渡す場合 -->\n      \u003Cvalidation-provider v-slot=\"{ errors }\" name=\"記事ID\" rules=\"numeric|max_digits:7\">\n        \u003Cv-text-field v-model=\"articleId\" :error-messages=\"errors\" label=\"記事ID\" counter=\"7\" type=\"number\" \u002F>\n      \u003C\u002Fvalidation-provider>\n    \u003C\u002Fv-col>\n\n    \u003Cv-col cols=\"12\">\n      \u003C!-- オブジェクトを渡すこともできます。 -->\n      \u003Cvalidation-provider v-slot=\"{ errors }\" name=\"色\" :rules=\"{ collection_max_length: { maxLength: 3 } }\">\n        \u003Cv-select v-model=\"selectedColors\" multiple chips :items=\"colors\" :error-messages=\"errors\" \u002F>\n      \u003C\u002Fvalidation-provider>\n    \u003C\u002Fv-col>\n  \u003C\u002Fv-row>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n  data() {\n    return {\n      articleId: 0,\n\n      selectedColors: [],\n      colors: ['red', 'blue', 'yellow', 'green', 'purple'].map((color) => ({ value: color, text: color })),\n    }\n  },\n}\n\u003C\u002Fscript>\n","validation-usage.vue",[203,19180,19181,19189,19210,19231,19236,19279,19343,19351,19359,19363,19381,19386,19427,19475,19483,19491,19499,19507,19511,19519,19527,19535,19541,19552,19556,19567,19663,19667,19671,19675],{"__ignoreMap":154},[272,19182,19183,19185,19187],{"class":274,"line":275},[272,19184,3081],{"class":289},[272,19186,4128],{"class":366},[272,19188,4038],{"class":289},[272,19190,19191,19193,19196,19199,19201,19203,19206,19208],{"class":274,"line":155},[272,19192,4135],{"class":289},[272,19194,19195],{"class":366},"v-row",[272,19197,19198],{"class":781}," justify",[272,19200,2294],{"class":289},[272,19202,2334],{"class":289},[272,19204,19205],{"class":293},"center",[272,19207,2334],{"class":289},[272,19209,4038],{"class":289},[272,19211,19212,19214,19217,19220,19222,19224,19227,19229],{"class":274,"line":305},[272,19213,4157],{"class":289},[272,19215,19216],{"class":366},"v-col",[272,19218,19219],{"class":781}," cols",[272,19221,2294],{"class":289},[272,19223,2334],{"class":289},[272,19225,19226],{"class":293},"12",[272,19228,2334],{"class":289},[272,19230,4038],{"class":289},[272,19232,19233],{"class":274,"line":340},[272,19234,19235],{"class":2656},"      \u003C!-- rulesを文字列で渡す場合 -->\n",[272,19237,19238,19240,19243,19245,19247,19249,19252,19254,19256,19258,19260,19263,19265,19268,19270,19272,19275,19277],{"class":274,"line":345},[272,19239,6139],{"class":289},[272,19241,19242],{"class":366},"validation-provider",[272,19244,12706],{"class":781},[272,19246,2294],{"class":289},[272,19248,2334],{"class":289},[272,19250,19251],{"class":293},"{ errors }",[272,19253,2334],{"class":289},[272,19255,9474],{"class":781},[272,19257,2294],{"class":289},[272,19259,2334],{"class":289},[272,19261,19262],{"class":293},"記事ID",[272,19264,2334],{"class":289},[272,19266,19267],{"class":781}," rules",[272,19269,2294],{"class":289},[272,19271,2334],{"class":289},[272,19273,19274],{"class":293},"numeric|max_digits:7",[272,19276,2334],{"class":289},[272,19278,4038],{"class":289},[272,19280,19281,19283,19286,19288,19290,19292,19295,19297,19300,19302,19304,19307,19309,19311,19313,19315,19317,19319,19322,19324,19326,19329,19331,19333,19335,19337,19339,19341],{"class":274,"line":363},[272,19282,9530],{"class":289},[272,19284,19285],{"class":366},"v-text-field",[272,19287,10559],{"class":781},[272,19289,2294],{"class":289},[272,19291,2334],{"class":289},[272,19293,19294],{"class":293},"articleId",[272,19296,2334],{"class":289},[272,19298,19299],{"class":781}," :error-messages",[272,19301,2294],{"class":289},[272,19303,2334],{"class":289},[272,19305,19306],{"class":293},"errors",[272,19308,2334],{"class":289},[272,19310,16897],{"class":781},[272,19312,2294],{"class":289},[272,19314,2334],{"class":289},[272,19316,19262],{"class":293},[272,19318,2334],{"class":289},[272,19320,19321],{"class":781}," counter",[272,19323,2294],{"class":289},[272,19325,2334],{"class":289},[272,19327,19328],{"class":293},"7",[272,19330,2334],{"class":289},[272,19332,752],{"class":781},[272,19334,2294],{"class":289},[272,19336,2334],{"class":289},[272,19338,641],{"class":293},[272,19340,2334],{"class":289},[272,19342,7576],{"class":289},[272,19344,19345,19347,19349],{"class":274,"line":376},[272,19346,6153],{"class":289},[272,19348,19242],{"class":366},[272,19350,4038],{"class":289},[272,19352,19353,19355,19357],{"class":274,"line":390},[272,19354,6162],{"class":289},[272,19356,19216],{"class":366},[272,19358,4038],{"class":289},[272,19360,19361],{"class":274,"line":409},[272,19362,302],{"emptyLinePlaceholder":169},[272,19364,19365,19367,19369,19371,19373,19375,19377,19379],{"class":274,"line":419},[272,19366,4157],{"class":289},[272,19368,19216],{"class":366},[272,19370,19219],{"class":781},[272,19372,2294],{"class":289},[272,19374,2334],{"class":289},[272,19376,19226],{"class":293},[272,19378,2334],{"class":289},[272,19380,4038],{"class":289},[272,19382,19383],{"class":274,"line":449},[272,19384,19385],{"class":2656},"      \u003C!-- オブジェクトを渡すこともできます。 -->\n",[272,19387,19388,19390,19392,19394,19396,19398,19400,19402,19404,19406,19408,19411,19413,19416,19418,19420,19423,19425],{"class":274,"line":466},[272,19389,6139],{"class":289},[272,19391,19242],{"class":366},[272,19393,12706],{"class":781},[272,19395,2294],{"class":289},[272,19397,2334],{"class":289},[272,19399,19251],{"class":293},[272,19401,2334],{"class":289},[272,19403,9474],{"class":781},[272,19405,2294],{"class":289},[272,19407,2334],{"class":289},[272,19409,19410],{"class":293},"色",[272,19412,2334],{"class":289},[272,19414,19415],{"class":781}," :rules",[272,19417,2294],{"class":289},[272,19419,2334],{"class":289},[272,19421,19422],{"class":293},"{ collection_max_length: { maxLength: 3 } }",[272,19424,2334],{"class":289},[272,19426,4038],{"class":289},[272,19428,19429,19431,19434,19436,19438,19440,19443,19445,19448,19451,19454,19456,19458,19461,19463,19465,19467,19469,19471,19473],{"class":274,"line":472},[272,19430,9530],{"class":289},[272,19432,19433],{"class":366},"v-select",[272,19435,10559],{"class":781},[272,19437,2294],{"class":289},[272,19439,2334],{"class":289},[272,19441,19442],{"class":293},"selectedColors",[272,19444,2334],{"class":289},[272,19446,19447],{"class":781}," multiple",[272,19449,19450],{"class":781}," chips",[272,19452,19453],{"class":781}," :items",[272,19455,2294],{"class":289},[272,19457,2334],{"class":289},[272,19459,19460],{"class":293},"colors",[272,19462,2334],{"class":289},[272,19464,19299],{"class":781},[272,19466,2294],{"class":289},[272,19468,2334],{"class":289},[272,19470,19306],{"class":293},[272,19472,2334],{"class":289},[272,19474,7576],{"class":289},[272,19476,19477,19479,19481],{"class":274,"line":491},[272,19478,6153],{"class":289},[272,19480,19242],{"class":366},[272,19482,4038],{"class":289},[272,19484,19485,19487,19489],{"class":274,"line":511},[272,19486,6162],{"class":289},[272,19488,19216],{"class":366},[272,19490,4038],{"class":289},[272,19492,19493,19495,19497],{"class":274,"line":529},[272,19494,4175],{"class":289},[272,19496,19195],{"class":366},[272,19498,4038],{"class":289},[272,19500,19501,19503,19505],{"class":274,"line":547},[272,19502,4113],{"class":289},[272,19504,4128],{"class":366},[272,19506,4038],{"class":289},[272,19508,19509],{"class":274,"line":565},[272,19510,302],{"emptyLinePlaceholder":169},[272,19512,19513,19515,19517],{"class":274,"line":592},[272,19514,3081],{"class":289},[272,19516,4021],{"class":366},[272,19518,4038],{"class":289},[272,19520,19521,19523,19525],{"class":274,"line":611},[272,19522,348],{"class":278},[272,19524,351],{"class":278},[272,19526,373],{"class":289},[272,19528,19529,19531,19533],{"class":274,"line":629},[272,19530,13019],{"class":366},[272,19532,506],{"class":289},[272,19534,373],{"class":289},[272,19536,19537,19539],{"class":274,"line":648},[272,19538,3256],{"class":278},[272,19540,373],{"class":289},[272,19542,19543,19546,19548,19550],{"class":274,"line":658},[272,19544,19545],{"class":366},"      articleId",[272,19547,370],{"class":289},[272,19549,15531],{"class":2297},[272,19551,406],{"class":289},[272,19553,19554],{"class":274,"line":668},[272,19555,302],{"emptyLinePlaceholder":169},[272,19557,19558,19561,19563,19565],{"class":274,"line":674},[272,19559,19560],{"class":366},"      selectedColors",[272,19562,370],{"class":289},[272,19564,8850],{"class":366},[272,19566,406],{"class":289},[272,19568,19569,19572,19574,19576,19578,19581,19583,19585,19587,19590,19592,19594,19596,19599,19601,19603,19605,19608,19610,19612,19614,19617,19619,19621,19623,19625,19627,19629,19632,19634,19636,19638,19640,19642,19644,19647,19649,19652,19654,19656,19658,19661],{"class":274,"line":1161},[272,19570,19571],{"class":366},"      colors",[272,19573,370],{"class":289},[272,19575,3313],{"class":366},[272,19577,403],{"class":289},[272,19579,19580],{"class":293},"red",[272,19582,403],{"class":289},[272,19584,316],{"class":289},[272,19586,290],{"class":289},[272,19588,19589],{"class":293},"blue",[272,19591,403],{"class":289},[272,19593,316],{"class":289},[272,19595,290],{"class":289},[272,19597,19598],{"class":293},"yellow",[272,19600,403],{"class":289},[272,19602,316],{"class":289},[272,19604,290],{"class":289},[272,19606,19607],{"class":293},"green",[272,19609,403],{"class":289},[272,19611,316],{"class":289},[272,19613,290],{"class":289},[272,19615,19616],{"class":293},"purple",[272,19618,403],{"class":289},[272,19620,5019],{"class":366},[272,19622,430],{"class":289},[272,19624,13464],{"class":354},[272,19626,357],{"class":366},[272,19628,357],{"class":289},[272,19630,19631],{"class":2496},"color",[272,19633,188],{"class":289},[272,19635,3089],{"class":781},[272,19637,2493],{"class":366},[272,19639,4351],{"class":289},[272,19641,16911],{"class":366},[272,19643,370],{"class":289},[272,19645,19646],{"class":282}," color",[272,19648,316],{"class":289},[272,19650,19651],{"class":366}," text",[272,19653,370],{"class":289},[272,19655,19646],{"class":282},[272,19657,327],{"class":289},[272,19659,19660],{"class":366},"))",[272,19662,406],{"class":289},[272,19664,19665],{"class":274,"line":1169},[272,19666,6018],{"class":289},[272,19668,19669],{"class":274,"line":1177},[272,19670,671],{"class":289},[272,19672,19673],{"class":274,"line":1184},[272,19674,965],{"class":289},[272,19676,19677,19679,19681],{"class":274,"line":1192},[272,19678,4113],{"class":289},[272,19680,4021],{"class":366},[272,19682,4038],{"class":289},[15,19684,19685],{},"指定したバリデーションエラーメッセージが表示されたことを確認。",[15,19687,19688],{},[21,19689],{"alt":16790,"src":19690},"\u002Fcontent\u002Fvee-validate-custom-rule\u002Fresult.png",[11,19692,2194],{"id":2194},[15,19694,19695],{},"メディアのコンテンツを入稿するツールを作っていく以上、不適切なデータが入稿され、メディアのブランドや信用性が損なわれるのを防ぐ必要があると思っています。\nこうやってカスタムでバリデーションルールを実装できるので、コンテンツを作るユーザーが安心して、良いコンテンツを入稿できるように、日々起こりうるデータの不整合をなくしていきたいです。最後まで読んでいただき、ありがとうございました。",[2211,19697,19698],{},"html pre.shiki code .s0_hs, html code.shiki .s0_hs{--shiki-default:#546E7A;--shiki-default-font-style:italic}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sAklC, html code.shiki .sAklC{--shiki-default:#89DDFF}html pre.shiki code .svy0-, html code.shiki .svy0-{--shiki-default:#EEFFFF}html pre.shiki code .sfyAc, html code.shiki .sfyAc{--shiki-default:#C3E88D}html pre.shiki code .sJ14y, html code.shiki .sJ14y{--shiki-default:#C792EA}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s-wAU, html code.shiki .s-wAU{--shiki-default:#F07178}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sLFUT, html code.shiki .sLFUT{--shiki-default:#EEFFFF;--shiki-default-font-style:italic}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}html pre.shiki code .sVyDW, html code.shiki .sVyDW{--shiki-default:#C792EA;--shiki-default-font-style:italic}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}",{"title":154,"searchDepth":155,"depth":155,"links":19700},[19701,19702,19703,19704,19705,19706,19707],{"id":16823,"depth":155,"text":16824},{"id":5426,"depth":155,"text":5426},{"id":18403,"depth":155,"text":18403},{"id":16846,"depth":155,"text":16846},{"id":18419,"depth":155,"text":18419},{"id":19171,"depth":155,"text":19171},{"id":2194,"depth":155,"text":2194},[2229,5403,2230,19709,18363],"VeeValidate","VeeValidate のカスタムルールの作り方",{},"\u002Ftech\u002Fvee-validate-custom-rule","2020-01-02",{"title":18373,"description":19710},"tech\u002Fvee-validate-custom-rule","lK2BthYnNuslflyzxZPNVCLGYX1X5ewrTsJ4JRIwl2M",1786259137728]