猫とGAS

猫の写真を載せる。ついでにGASやVueJSの開発備忘録を兼ねる。

GASでVueJSのcomponentを使う

See the Pen ポップアップを開くComponent on CodePen.

VueJSにはcomponentという非常に便利な機能があり、これを使うと機能を部品として切り出し再利用が可能になる上、ファイルを分けられるので可読性も上がる。componentを使う際は.vueファイルに定義したcomponentをexportし、使う側でimportするのが一般的であり、VueJSの書き方を調べるとこの書き方は非常によく目にする。しかしだ、GASの標準エディタはJavaScriptを記述する.gsファイルと.htmlファイル、それと例外的に.jsonファイルを作成することがしかできない。.vueファイルは作成できず、どんなに便利なcomponentを発見しても同じ書き方で実現することはできないのだ。ここではGASの標準エディタでcomponentの利用を可能にするまでの軌跡を、その奮闘の過程を、ドキュメンタリーに見ていただこう。いや嘘だ。長くなるので結果だけお伝えしたい。

以前作ったポップアップをcomponentを使った書き方に変更する。"templateタグでcomponent化したいHTMLを構築し、defineComponentでidを指定してcomponentを定義する。定義したcomponentはpopup変数に格納する。以前の記事は以下を参照。 neko-gas.hatenablog.com

templateタグを指定してcomponent化する

通常はimportしたcomponentを登録するが、importができないので代わりに変数に格納したcomponentを登録する。呼び出し側はたったこれだけで済んでしまう。

タグ名とdefineComponentの結果を格納した変数を指定してcomponentを登録する

componentを使ってお手軽に呼び出せるようになったが、今のままでは「はい」を押しても「いいえ」を押しても閉じるだけの無意味なポップアップを表示するだけの使い道のないcomponentになってしまう。slotを使ってポップアップの中身は呼び出し元で自由に定義できるようにしよう。

pop-upタグで囲まれた部分がslot部分に置換される

選択かごの中でcomponentと化したわたじい

componentを記述したファイルは.vueファイルのように、cssも含めて一つのhtmlファイルにまとめることができる。ただしimport文での変数名変更ができないため、変数名の同じcomponentは利用できない点、後から読んで変数がどこから来ているか分かりづらい点、呼び出し元のhtml内でスクリプトレットを用いたhtmlの呼び出しが必要になる点などを注意してほしい。

コード.gs

無題.html

ポップアップcomponent.html

IPアドレスフィルタリングでGASの安全性を確保する

See the Pen ip制限 on CodePen.

IPアドレスはHTML側で取得するため、doGet内ではチェックできない(できたら良かったけどね)。(仕方ないから)ロード時に取得してサーバ側ですぐにチェックする形を取る。HTMLは相手のPC上で展開されているのでIPアドレスが取れ、IPアドレスのチェックはサーバ側でするのでチェック処理を秘匿できる。そんなイメージで考えると分かりやすいのでは。

IPフィルタリングイメージ(あくまでイメージ)

IPアドレスの取得にはfetchを使う。fetchはサーバーと通信するためのコードで、IPアドレスを取得できるサービスにアクセスしていると思えばいい。ちなみに、.gsファイルではUrlFetchAppというサービスを使うとfetchが実現できるが、.gsファイル内で試してみてもログイン端末のIPアドレスは取得できなかった。サーバのIPアドレスが取れているのかも。

async,awaitでの取得イメージ

asyncの中でinitというメソッドを呼んでいる。初回の画面描画で実施したいので、bodyタグのonload内で処理をする。

実際には許可IPアドレスや制限IPアドレスは保守性を保つためにプロパティかSpreadSheetにある方がいい。エラーをthrowする形にしているため、htmlから呼び出す際にはwithFailureHandlerの中でエラー画面を表示する、といったエラー処理をしっかり書かないといけない。

仕事の邪魔をするわたじい

全体サンプル

無題.html

コード.gs

GASで可読性を意識したポップアップを実装する

See the Pen ポップアップ表示 on CodePen.

背景色はrgbで000を指定することで黒にした上で、透過に0.5を指定して後ろの画面が透けて見えるようにする。後ろの画面を透かすためには、positionを指定して絶対座標にする必要がある。また、bodyのmarginのせいでベゼルのような白い枠が残ってしまうので、topとleftを指定して完全に画面を覆うようにする。topとleftはpositionを絶対座標にしないと指定できないので注意。

白い枠が残っちゃう
絶対座標にして白い枠を消す

こちらもpositionを指定して絶対座標にした上、画面中央に表示したいのでtopとleftを指定する。しかし画面のサイズと本体のサイズのせいで、pxでもvhでも一筋縄では行かない。画面全体の50%ずつ上と左とにズラした後、本体の50%ずつ逆にずらすことで真ん中に表示できる(画像参照)。ちなみに、本体はborder-radiusで角を丸っこくして可愛くしている。

topとleftを50%ずつにすると右下に表示されちゃう
translateで本体の50%だけ左寄せ
translateで本体の50%だけ上寄せしたら完成

スクリプトレットでGASで書くコードをそのままHTML上で書くことができる。こういうやつ→<?! ここにコード ?> スクリプトレットで大元のHTMLから別ファイルに切り出したHTMLを呼び出している。ただしこの例は呼び出し時点で中身を変えられないため、汎用性があるとは言い難い。可読性を上げるだけのものだ。汎用性を求める方法については別の機会に紹介する。

本体のHTMLから別のHTMLの中身をそのまま呼び出し

ポップアップのように飛び出してきそうなわたじい

全体イメージ

コード.gs

無題.html

ポップアップ.html

JavaScript関数の色々な書き方を並べてみる

同じ処理でも複数の書き方ができるところがjavaScriptの混乱を招きやすいところである。ここではjavascript関数の書き方について備忘録的に簡単にまとめておく。

引数を受け取り、1を足して返すシンプルな関数である。plus1(2)と書いて実行すると、2に1が足され3が返ってくる。これを他の書き方で書いてみたい。

変数plus1に関数を代入した形である。plus1には関数が代入されているので、こちらもplus1(2)と書けばやはり3が返ってくる。

functionを省略した形である。引数を表す括弧と処理を表す中括弧をアロー(矢)のような記号で繋ぐのでアロー関数と呼ばれる。関数を引数に取る関数(Arrayの関数など)でよく用いられる。ちなみに、アロー関数で書くとうまくいかないものもある。 Vue インスタンスの methods にアロー関数を使ったら動作しない理由を this のスコープで説明します

アロー関数がそもそも省略形だが、処理が1行の場合は中括弧とreturnすら省略できる。戻り値を必要としない場合でも同じ書き方ができる。余談だが、括弧でくくることで即時実行することもできる。
((num)=>num+1)(2);
極限まで短く書いてやろうという強い執念を感じるが、この例で言えば普通に「2+1;」と書いた方が早い。

厳密には先ほどまでの処理と同じではないが、カッコでくくるとカンマまでに処理内容、カンマの後に返却する値、という形で1行で書ける。先ほどまでの処理と何が違うかというと、plus1(2)を実行して3が返ってくるまでは一緒だが、格納と返却を同時に行なっているため実行後にresultを確認すると3が格納されている。

これまでとは内容が異なるが、小慣れてくるとJSONオブジェクトの便利さに気がつき、アロー関数でも返却しようとすることがあると思う。その時つまづかないように今のうちに小石を拾っておこう。まずはダメな例を挙げる。 この処理を実行するとエラーになる。GASで書くとまず構文エラーで保存ができない。なぜかというと、中括弧を処理だと解釈するためだ。アロー関数の最初の例を見てみると理解してもらえると思う。
let plus1 = (num)=>{return {org: num, result: num+1}};
これであればうまくいく。しかし何かスマートでない。。。本当にこんな書き方しかできないのか?いや、そんなわけはない。もっとスマートな書き方がちゃんとある。最後にその書き方を記して本記事の締めくくりとするが、その前にわたじいを見ておこう。

椅子の足を枕にするわたじい
椅子の足を枕にするわたじい

だらしない。。。椅子の足に顎を乗っけて、ベストフィットの位置なのだろう。ローラーなんて近すぎて、もし座っていたら危なくて動けないな。

JSON記法のオブジェクトをアロー関数で返却する答え