tag:crieit.net,2005:https://crieit.net/tags/Buefy/feed 「Buefy」の記事 - Crieit Crieitでタグ「Buefy」に投稿された最近の記事 2021-01-26T20:25:54+09:00 https://crieit.net/tags/Buefy/feed tag:crieit.net,2005:PublicArticle/16651 2021-01-26T20:25:54+09:00 2021-01-26T20:25:54+09:00 https://crieit.net/posts/Bulma-Nuxt-Content-Prism-js BulmaとNuxt/Content(というかPrism.js)の相性が結構辛い <h2 id="環境"><a href="#%E7%92%B0%E5%A2%83">環境</a></h2> <ul> <li>nuxt: 2.14.6</li> <li>nuxt/content: 1.9.0</li> <li>prism-themes: 1.5.0</li> <li>nuxt-buefy: 0.4.3</li> </ul> <h2 id="デザイン大崩れ"><a href="#%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E5%A4%A7%E5%B4%A9%E3%82%8C">デザイン大崩れ</a></h2> <p>Nuxt/Contentを使っていて、かなり苦戦した。特にNuxt/Contentが内包している、Prism.jsでコードのハイライトを出そうとしたときが辛かった。<br /> <a href="https://crieit.now.sh/upload_images/8ab28d65442b113bed0f81d1e532434a5ff697044862b.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/8ab28d65442b113bed0f81d1e532434a5ff697044862b.png?mw=700" alt="image" /></a><br /> これ、酷くない?</p> <p>最初、何か設定をミスったのかと思って、prismの導入あたりのドキュメントを見ても問題ないし、じゃあ、何かのバグかっていうと、突拍子もなさすぎて訳わからん。<br /> しばらく悩んで気がついた。<br /> Bulmaのスタイルが当たってるんだ。<br /> どうやらnumberというクラスが競合しているようだ。<br /> (正直、このnumberクラス、ドキュメントにもないし、初めて見た。そして、何というか、今後使うことなさそう……)<br /> 他にもtagというクラスが競合するらしい(未確認)。</p> <p>cssに関しては大の苦手なので、具体的な施策を提示する自信がないのですが、<br /> とりあえず、Bulmaのスタイルより優先度上のセレクタで上書きする感じで無理矢理やりました。</p> <h2 id="結構いました。"><a href="#%E7%B5%90%E6%A7%8B%E3%81%84%E3%81%BE%E3%81%97%E3%81%9F%E3%80%82">結構いました。</a></h2> <p>調べてみたら同じ理由で困った人がちらほら。<br /> <a target="_blank" rel="nofollow noopener" href="https://papadays.com/post/5inybk0imz6r2ycmeoquwn/">Bulmaをやめてしまった人までいる。</a><br /> <a target="_blank" rel="nofollow noopener" href="https://stackoverrun.com/ja/q/9978069">みんな困ってるんだね。</a></p> <h2 id="他にも"><a href="#%E4%BB%96%E3%81%AB%E3%82%82">他にも</a></h2> <p>Nuxt/Content側の話で、見出しがやけに右に寄るなあ、てのもあった(画像2行目)<br /> <a href="https://crieit.now.sh/upload_images/7878ba53b27b21fcc3ce1b5c3b49da2e5ff6971d71552.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7878ba53b27b21fcc3ce1b5c3b49da2e5ff6971d71552.png?mw=700" alt="image" /></a><br /> 見出しのリンク(h2 > a > span)にiconというクラスが割り当てられていて、そこにBulmaのクラスが当たって幅を持ってしまっていた。<br /> まあ、そもそもNuxt/Contentは「<a target="_blank" rel="nofollow noopener" href="https://content.nuxtjs.org/ja/displaying#style">こういう感じで生成するから自分でデザインしてね</a>」なので良いのだが(自分ではなくBulmaが勝手にやってしまった、というのはあるけど)</p> <h2 id="感想"><a href="#%E6%84%9F%E6%83%B3">感想</a></h2> <p>Nuxt/Contentもprismも自分の預かり知らないところでHTMLを構成するので、意図せずCSSフレームワークと競合するのはしんどいなあという感想です。<br /> Nuxt/Contentは<a href="#他にも">上記の通り</a>なんだけど、prismは元々のデザインがあるから辛いなあと。<br /> あと、これでBulmaを辞めるという決断になると、同時にbuefyを辞めるという事になるので、結構辛いなあ。</p> hammhiko tag:crieit.net,2005:PublicArticle/15521 2019-10-31T08:02:37+09:00 2019-10-31T08:02:37+09:00 https://crieit.net/posts/Vue-Buefy Vue + Buefyでサーバーからファイルを受け取ってファイルアップロードにセットする <p>そんな需要がどこにあるのか知らんが。</p> <h2 id="動作環境"><a href="#%E5%8B%95%E4%BD%9C%E7%92%B0%E5%A2%83">動作環境</a></h2> <p>OS: macOS High Sierra 10.13.6<br /> ブラウザ: Chrome 77.0.3865.90<br /> vue: 2.6.10<br /> buefy: 0.8.4</p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>やりたいこととしては、タイトルの通りです。</p> <p>需要があるとは到底思えないのだけれど、思いついてやってみたらそれっぽくできてしまったので。</p> <p><del>無理やり使う場面を考えるとすると、例えば電子申請伝票に添付ファイルを(領収証とかをpdfで)つけたいのだけど、申請前に一時保存する機能をつけたい。保存時に添付ファイルはサーバーに送られるのだけど、再編集時にファイルアップロードにセットしたい、とか。でもそんな業務チックなシステムをvue + buefyでやるとは思えないので、やっぱり使う場面が思い浮かばない。</del></p> <h2 id="普通のファイルアップロードだと無理"><a href="#%E6%99%AE%E9%80%9A%E3%81%AE%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%A2%E3%83%83%E3%83%97%E3%83%AD%E3%83%BC%E3%83%89%E3%81%A0%E3%81%A8%E7%84%A1%E7%90%86">普通のファイルアップロードだと無理</a></h2> <p>普通のファイルアップロード(input type="file")だと<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/HTML/Element/Input/file#Using_file_inputs">セキュリティ上の理由で無理</a>。まあ、<a target="_blank" rel="nofollow noopener" href="https://stackoverflow.com/questions/1696877/how-to-set-a-value-to-a-file-input-in-html/1696884#1696884">そうだよな</a>って感じではありますが。<br /> 別に、valueに端末のパスを指定して悪さしたいわけじゃなくて、直にfiles[0]にFileオブジェクトを突っ込んでおきたいのだけど。。。</p> <h2 id="Buefyならなんとか"><a href="#Buefy%E3%81%AA%E3%82%89%E3%81%AA%E3%82%93%E3%81%A8%E3%81%8B">Buefyならなんとか</a></h2> <p>Buefyのb-uploadなら、VueのdataにFileオブジェクトを保持して、擬似的(?)にファイルアップロードを作っているっぽいのでできそうです。<br /> やる場面があるか知らんが。</p> <p>要は、VueのdataにFileオブジェクトを突っ込めれば良いので、サーバーからのファイルのデータをFileオブジェクトに変換するというのがメインの作業になります。</p> <p><del>面倒なので</del><a href="https://crieit.net/posts/Vue-Buefy-onChange">前回</a>のソースに手を加える感じにします。</p> <p>と、その前にサーバー側。<br /> よしなにやれば良いと思いますが、今回は簡単にLaravel使ってこんな感じでStorageでgetして返してます。</p> <pre><code class="php">return Storage::get('PUBLN-S-logo.png'); </code></pre> <p>でフロント側</p> <pre><code class="HTML"><template> <div> <b-field class="file"> <b-upload v-model="file"> <a class="button is-primary"> <b-icon icon="upload"></b-icon> <span>Click to upload</span> </a> </b-upload> <span class="file-name" v-if="file"> <span>{</span><span>{</span> file.name <span>}</span><span>}</span> </span> </b-field> <!-- サーバーから取得するボタンを追加 --> <b-button type="is-info" @click="getFile">サーバーから取得</b-button> <img :src="image" /> </div> </template> <script> export default { data:function(){ return { file:null } }, computed:{ image:function(){ return this.file ? window.URL.createObjectURL(this.file) : "" } }, // サーバーからファイルを取得するメソッドを追加 methods:{ getFile:async function(){ const response = await fetch('/api/getFile') if(response.ok){ const blob = await response.blob() this.file = new File([blob],'PUBLN-S-logo.png') } } } } </script> </code></pre> <p>fetchだとレスポンスをblobをブジェクトに変換するblobメソッドがあるので、それを使います。<br /> blobだとb-uploadが受け付けないのでFileオブジェクトにする必要がありますが、コンストラクタでblobを渡すことができるので、難しくありません。<a target="_blank" rel="nofollow noopener" href="https://developer.mozilla.org/ja/docs/Web/API/File/File">配列で渡す必要があるのをうっかりしそうですが。</a></p> <p><a href="https://crieit.now.sh/upload_images/ee8d5bfe911060c36b5051bfff42b5d25db2b970e38d6.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/ee8d5bfe911060c36b5051bfff42b5d25db2b970e38d6.png?mw=700" alt="ボタン押す前.png" /></a><br /> ボタンを押すと<br /> <a href="https://crieit.now.sh/upload_images/d73deec111f32c40e2f7e0bbdd5f81845db2b98570303.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/d73deec111f32c40e2f7e0bbdd5f81845db2b98570303.png?mw=700" alt="ボタン押した後.png" /></a><br /> サーバーから取ってきてセット(ついでにプレビュー)</p> <h2 id="終わりに"><a href="#%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%AB">終わりに</a></h2> <p>細かいところは検証してないですが、とりあえず動いたので。<br /> たぶん、色々セキュリティとかも含めちゃんとしなきゃいけないとは思います。<br /> そもそも使いどころはわかりませんが。</p> hammhiko tag:crieit.net,2005:PublicArticle/15450 2019-10-04T08:03:30+09:00 2019-10-04T08:03:30+09:00 https://crieit.net/posts/Vue-Buefy-onChange Vue + Buefy で画像ファイルのプレビューを実装しようとしたらonChangeが効かなくて少しだけ困った話 <p>まあ、自分のやろうとしたことが、正攻法じゃなかっただけかもしれないけど。</p> <h2 id="動作環境"><a href="#%E5%8B%95%E4%BD%9C%E7%92%B0%E5%A2%83">動作環境</a></h2> <p>まずは、一応<br /> OS: macOS High Sierra 10.13.6<br /> ブラウザ: Chrome 77.0.3865.90<br /> vue: 2.6.10<br /> buefy: 0.8.4</p> <h2 id="はじめに"><a href="#%E3%81%AF%E3%81%98%E3%82%81%E3%81%AB">はじめに</a></h2> <p>vue + buefy でwebサイトを作っていて、画像ファイルのアップロードとプレビューを実装しようと思った。<br /> それ自体は調べれば色々出てくるので難しいものではなかった。(ちょっと疑問は残ったけど<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup>)</p> <p>だいぶ雑に書くけど</p> <pre><code class="html"><template> <div> <input type="file" @change="changeImage"/></br> <img :src="image" /> </div> </template> <script> export default { data:function(){ return { image:"", } }, methods:{ changeImage:function(e){ const file = e.target.files[0] if(file){ this.image = window.URL.createObjectURL(file) } else{ this.image = "" } } } } </script> </code></pre> <p>こんな感じでできる。<br /> (ほんとは、ファイルがないときはimgタグ隠すとか、fileは画像ファイルだけ受け付けるとか色々必要だけど)<br /> <a href="https://crieit.now.sh/upload_images/a334b71dd1b2092bcb878ad39886cb0b5d959623f0738.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/a334b71dd1b2092bcb878ad39886cb0b5d959623f0738.png?mw=700" alt="input_選択前.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/839748f460ee8aa0e4ba5e0c6855668b5d959636858d7.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/839748f460ee8aa0e4ba5e0c6855668b5d959636858d7.png?mw=700" alt="input_選択後.png" /></a></p> <p>ところがこれを</p> <pre><code class="html"><template> <div> <b-input type="file" @change="changeImage"></b-input></br> <img :src="image" /> </div> </template> <script> export default { data:function(){ return { image:"", } }, methods:{ changeImage:function(e){ const file = e.target.files[0] if(file){ this.image = window.URL.createObjectURL(file) } else{ this.image = "" } } } } </script> </code></pre> <p>buefyのb-inputに変更したら途端に動かなくなった。<br /> どうもonChangeが発火していないみたい。</p> <p><a href="https://crieit.now.sh/upload_images/7d99cb8f10de2099da56aaf7f4fc7a615d95964c9582d.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/7d99cb8f10de2099da56aaf7f4fc7a615d95964c9582d.png?mw=700" alt="b-input_選択前.png" /></a><br /> <a href="https://crieit.now.sh/upload_images/48f566844156ce0351ddfc4edba1f50c5d95965866f6a.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/48f566844156ce0351ddfc4edba1f50c5d95965866f6a.png?mw=700" alt="b-input_選択後.png" /></a></p> <h2 id="解決策"><a href="#%E8%A7%A3%E6%B1%BA%E7%AD%96">解決策</a></h2> <p>原因がはっきりしないのだけど、(というか調べていない)とりあえずなんとかする方法はある。</p> <h3 id="1. b-inputをやめる"><a href="#1.+b-input%E3%82%92%E3%82%84%E3%82%81%E3%82%8B">1. b-inputをやめる</a></h3> <p>そもそも、元々動いていたのだから素直にinputを使う。で、bulmaなり素のcssでデザインをなんとかすれば良い。</p> <h3 id="2. b-inputではなくb-uploadを使う"><a href="#2.+b-input%E3%81%A7%E3%81%AF%E3%81%AA%E3%81%8Fb-upload%E3%82%92%E4%BD%BF%E3%81%86">2. b-inputではなくb-uploadを使う</a></h3> <p>こっちの方が正攻法のような気がする。<br /> そもそもbuefyにはb-input以外に、アップロード用のコンポーネントb-uploadがある。<br /> (正体は input type="file" っぽいけど)<br /> こっちだとv-modelでfileオブジェクトをバインドできるので、onChangeイベントも要らず算出プロパティでできたりする。<br /> ※ちなみにinputでv-modelを使おうとすると、type="file"の場合、vueのエラーになる。b-uploadも最終的にはinputになるのに、何故……?</p> <pre><code class="html"><template> <div> <b-field class="file"> <b-upload v-model="file"> <a class="button is-primary"> <b-icon icon="upload"></b-icon> <span>Click to upload</span> </a> </b-upload> <span class="file-name" v-if="file"> <span>{</span><span>{</span> file.name <span>}</span><span>}</span> </span> </b-field> <img :src="image" /> </div> </template> <script> export default { data:function(){ return { file:null } }, computed:{ image:function(){ return this.file ? window.URL.createObjectURL(this.file) : "" } } } </script> </code></pre> <p><a href="https://crieit.now.sh/upload_images/f7e91aa39348cc0c35490d9169a1fadb5d959a875dc2e.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f7e91aa39348cc0c35490d9169a1fadb5d959a875dc2e.png?mw=700" alt="b-upload_選択前.png" /></a><br /> (雑にやったせいかアイコンが出てないけど……)<br /> <a href="https://crieit.now.sh/upload_images/f6bf7fd4c8a99b234c2ec464f45251095d959a94d6819.png" target="_blank" rel="nofollow noopener"><img src="https://crieit.now.sh/upload_images/f6bf7fd4c8a99b234c2ec464f45251095d959a94d6819.png?mw=700" alt="b-upload_選択後.png" /></a></p> <h3 id="番外編 b-inputでv-modelを使う(ダメでした)"><a href="#%E7%95%AA%E5%A4%96%E7%B7%A8+b-input%E3%81%A7v-model%E3%82%92%E4%BD%BF%E3%81%86%EF%BC%88%E3%83%80%E3%83%A1%E3%81%A7%E3%81%97%E3%81%9F%EF%BC%89">番外編 b-inputでv-modelを使う(ダメでした)</a></h3> <p>この記事を書いていて、「あれ? 最終的にinputになるb-uploadがv-model使えるのなら、b-inputのtype="file"でもv-model使えるんじゃね?」って思ってやってみたけどダメだった。<br /> vue側ではエラーにならないけど、バインドされるのがFileオブジェクトではなくファイルパスの文字列だった。<br /> b-uploadはコンポーネントの中で色々よしなに頑張ってくれているんだろうなあ。</p> <h2 id="終わりに"><a href="#%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%AB">終わりに</a></h2> <p>個人的には、いかにも「ファイルアップロードです!」みたいな見た目が嫌いではないし、対応としてはどっちでも良いと思うのだけれど、まあ、状況に合わせて対応すれば良いと思う。</p> <div class="footnotes" role="doc-endnotes"> <hr /> <ol> <li id="fn:1" role="doc-endnote"> <p>みんなonChangeでFileオブジェクト取得してFileReaderでonloadしてreadAsDataURLでimgのsrcに入れてるんだけど、今回やってるみたいにFileオブジェクトからwindow.URL.createObjectURLじゃダメなの? <a href="#fnref:1" class="footnote-backref" role="doc-backlink">↩︎</a></p> </li> </ol> </div> hammhiko tag:crieit.net,2005:PublicArticle/15019 2019-05-24T20:28:38+09:00 2019-05-26T18:40:52+09:00 https://crieit.net/posts/nuxt-buefy-Bulma nuxt-buefyの色をBulmaのデフォルトと同じにする <p>Nuxt.jsでBuefyを使うためにnuxt-buefyを入れると、Buefyでテーマカラーが変更されているためBulmaとは違う色になってしまう。それをBulmaのデフォルトの色にする方法。</p> <p>まずnuxt.config.jsにてnuxt-buefyを読み込んでいるところで、オプションを使ってBuefyのCSSを読み込まないようにする。</p> <pre><code class="javascript"> ['nuxt-buefy', { css: false }], </code></pre> <p>あとはひとまずデフォルトの色を定義したvariables.scssのようなものを作っておく。</p> <pre><code class="scss">$primary: hsl(171, 100%, 41%) !default; $info: hsl(204, 86%, 53%) !default; $success: hsl(141, 71%, 48%) !default; $warning: hsl(48, 100%, 67%) !default; $danger: hsl(348, 100%, 61%) !default; $light: hsl(0, 0%, 96%) !default; $dark: hsl(0, 0%, 21%) !default; </code></pre> <p>最後にapp.scssの先頭でこれとBuefyのscssをimportする。</p> <pre><code class="scss">@import 'variables'; @import '~buefy/src/scss/buefy-build.scss'; </code></pre> <p>細かい部分はチェックできていないがこれでなんとなくデフォルトのBulmaの色っぽくなった。</p> だら@Crieit開発者