[{"data":1,"prerenderedAt":6028},["ShallowReactive",2],{"series-concrete5vue-3":3},{"doc":4,"prev":3551,"next":3549},{"id":5,"title":6,"body":7,"category":3534,"createdAt":3536,"description":3537,"extension":3538,"index":88,"meta":3539,"navigation":91,"path":3540,"publish":91,"seo":3541,"series":3542,"seriesTitle":3543,"stem":3544,"tag":3545,"thumbnail":3548,"updatedAt":3549,"__hash__":3550},"series\u002Fseries\u002Fconcrete5vue-3.md","Concrete5にVueCLIを使ってUIを構築する。3【編集画面と一覧画面】",{"type":8,"value":9,"toc":3511},"minimark",[10,20,23,28,36,39,44,47,57,64,152,163,170,177,184,187,590,595,599,606,686,695,702,705,708,738,745,877,884,1151,1154,1161,1176,1179,1186,1191,1194,1197,1300,1303,1306,1312,1491,1498,1501,1504,1507,1510,1513,1516,1519,1522,2877,2880,2893,2896,2899,2902,2906,2911,3043,3047,3050,3056,3083,3086,3342,3348,3351,3354,3357,3360,3363,3366,3369,3372,3375,3378,3382,3385,3388,3391,3394,3494,3497,3500,3504,3507],[11,12,13,14,19],"p",{},"こんにちはjunです。",[15,16,18],"a",{"href":17},"\u002Fseries\u002Fconcrete5vue-2","Concrete5にVueCLIを使ってUIを構築する 2","の記事の続きを書いていきます。前回の記事ではフォームの作成・登録まで行いました。この記事では登録したデータの編集とファイルマネージャーのvueコンポーネント化を行っていきます。",[11,21,22],{},"編集画面は追加画面とコンポーネントを共有し、データベースからAjaxでデータを取得してコンポーネントに代入をします。そして登録したデータの操作が行える一覧画面を作成します。",[24,25,27],"h2",{"id":26},"編集画面のレンダーとajax設定","編集画面のレンダーとAjax設定",[11,29,30,31,35],{},"まずは編集画面から作成していきます。編集は追加と違ってデータベースからデータを取得して、初期値として当てはめる必要があります。PHPであれば",[32,33,34],"code",{},"value=\"\u003C?php echo $data?>\"","みたいに挿入することで簡単に実現できますが、vueを使うとなれば一捻り必要です。",[11,37,38],{},"jsでフロントを構築する場合、基本的にDBのデータはAjaxを用いて再度サーバーにデータを要求します。concrete5でもAjaxとそのエントリーを実装することができます。まずエントリーの設定からやってみましょう。",[40,41,43],"h3",{"id":42},"ajaxエントリーrest-apiの作成","Ajaxエントリー(REST API)の作成",[11,45,46],{},"今回はシングルページのコントローラーを用いてAjax用のエントリーを実装します。Ajaxでデータを取得する際は基本的に取得用のURLを作成して、そのURLに対してAjaxを飛ばしてJSONデータをレスポンスとして受け取るのが定石です。",[48,49,54],"pre",{"className":50,"code":52,"language":53},[51],"language-text","vuetest\n├── controller.php \u002F\u002Fこれはパッケージのcontroller\n├── controllers\n│   └── single_page\n│       └── dashboard\n│           └── vuetest.php\n└── single_pages\n    └── dashboard\n        └── vuetest\n            ├── add.php   \u002F\u002F追加画面シングルページ\n            ├── edit.php  \u002F\u002F編集画面シングルページ\n            └── view.php\n","text",[32,55,52],{"__ignoreMap":56},"",[11,58,59,60,63],{},"では ",[32,61,62],{},"vuetest\u002Fcontrollers\u002Fsingle_page\u002Fdashboard\u002Fvuetest.php"," に以下のように記述します。",[48,65,70],{"className":66,"code":67,"filename":68,"language":69,"meta":56,"style":56},"language-php shiki shiki-themes material-theme-ocean","public function edit($id=null){\n    if($id==null) return Redirect::to('\u002Fdashboard\u002Fvuetest\u002F')->send();\n\n    if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){\n        $db = Database::connection();\n        $db->Execute(\"START TRANSACTION\");\n        $result = $db->fetchAll('SELECT * FROM album WHERE ID = ?',array($id));\n        $db->Execute(\"COMMIT\");\n        return Core::make('helper\u002Fajax')->sendResult($result);\n    }\n\n    $this->render('\u002Fdashboard\u002Fvuetest\u002Fedit');\n}\n","vuetest.php","php",[32,71,72,80,86,93,99,105,111,117,123,129,135,140,146],{"__ignoreMap":56},[73,74,77],"span",{"class":75,"line":76},"line",1,[73,78,79],{},"public function edit($id=null){\n",[73,81,83],{"class":75,"line":82},2,[73,84,85],{},"    if($id==null) return Redirect::to('\u002Fdashboard\u002Fvuetest\u002F')->send();\n",[73,87,89],{"class":75,"line":88},3,[73,90,92],{"emptyLinePlaceholder":91},true,"\n",[73,94,96],{"class":75,"line":95},4,[73,97,98],{},"    if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){\n",[73,100,102],{"class":75,"line":101},5,[73,103,104],{},"        $db = Database::connection();\n",[73,106,108],{"class":75,"line":107},6,[73,109,110],{},"        $db->Execute(\"START TRANSACTION\");\n",[73,112,114],{"class":75,"line":113},7,[73,115,116],{},"        $result = $db->fetchAll('SELECT * FROM album WHERE ID = ?',array($id));\n",[73,118,120],{"class":75,"line":119},8,[73,121,122],{},"        $db->Execute(\"COMMIT\");\n",[73,124,126],{"class":75,"line":125},9,[73,127,128],{},"        return Core::make('helper\u002Fajax')->sendResult($result);\n",[73,130,132],{"class":75,"line":131},10,[73,133,134],{},"    }\n",[73,136,138],{"class":75,"line":137},11,[73,139,92],{"emptyLinePlaceholder":91},[73,141,143],{"class":75,"line":142},12,[73,144,145],{},"    $this->render('\u002Fdashboard\u002Fvuetest\u002Fedit');\n",[73,147,149],{"class":75,"line":148},13,[73,150,151],{},"}\n",[11,153,154,155,158,159,162],{},"まずは編集画面を ",[32,156,157],{},"\u002Fdashboard\u002Fvuetest\u002Fedit"," というURLで表示できるようにします。このメソッドではパラメータがあるので ",[32,160,161],{},"\u002Fdashboard\u002Fvuetest\u002Fedit\u002F2"," のようなURLを送信できます。数字の部分はアルバムのDBでのIDとします。（アルバムID）",[11,164,165,166,169],{},"つまり",[32,167,168],{},"\u002Fdashboard\u002Fvuetest\u002Fedit\u002F"," にアルバムIDを加えて送信することで、指定したIDのデータを表示できるようにします。そしてリクエストがXMLHttpRequestつまり、AjaxであればデータJSONで返し、そうでなければ404を返すようにします。",[11,171,172,173,176],{},"リクエストの種別を限定することで、ブラウザなどでAjax専用の ",[32,174,175],{},"\u002Fdashboard\u002Fvuetest\u002FloadData"," というURLを叩いても404しか表示されません。",[178,179,183],"div",{"className":180},[181,182],"alert","alert-info","\nこのようなAPIを作成するときは、データを差し出してもいいユーザーなのかをチェックする必要があります。しかし今回のような管理画面配下のページ（dashboard）でルーティングする場合は特に気にする必要はありません。\n",[11,185,186],{},"\u002Fdashboard\u002F* 配下はリクエストからログインユーザーであるかをチェックしており、ログインユーザーでないリクエストの場合、ログインページのHTMLが返されます。実際にcurlで上記のURLを打ってみると",[48,188,192],{"className":189,"code":190,"language":191,"meta":56,"style":56},"language-html shiki shiki-themes material-theme-ocean","\u003C!DOCTYPE html>\n\u003Chtml>\n\u003Chead>\n    \u003Clink rel=\"stylesheet\" type=\"text\u002Fcss\" href=\"\u002Fconcrete\u002Fthemes\u002Fconcrete\u002Fmain.css\" \u002F>\n    \n\u003Ctitle>ログイン :: c5test\u003C\u002Ftitle>\n\n\u003Cmeta http-equiv=\"content-type\" content=\"text\u002Fhtml; charset=UTF-8\"\u002F>\n\u003Cmeta name=\"generator\" content=\"concrete5 - 8.5.4\"\u002F>\n\u003Clink rel=\"canonical\" href=\"http:\u002F\u002Flocalhost:8888\u002Flogin\">\n\u003Cscript type=\"text\u002Fjavascript\">\n    var CCM_DISPATCHER_FILENAME = \"\u002Findex.php\";\n    var CCM_CID = 174;\n    var CCM_EDIT_MODE = false;\n    var CCM_ARRANGE_MODE = false;\n    var CCM_IMAGE_PATH = \"\u002Fconcrete\u002Fimages\";\n    var CCM_TOOLS_PATH = \"\u002Findex.php\u002Ftools\u002Frequired\";\n    var CCM_APPLICATION_URL = \"http:\u002F\u002Flocalhost:8888\";\n    var CCM_REL = \"\";\n    var CCM_ACTIVE_LOCALE = \"ja_JP\";\n\u003C\u002Fscript>\n","html",[32,193,194,211,220,229,279,285,305,309,343,374,404,424,445,460,476,490,509,528,547,562,581],{"__ignoreMap":56},[73,195,196,200,204,208],{"class":75,"line":76},[73,197,199],{"class":198},"sAklC","\u003C!",[73,201,203],{"class":202},"s-wAU","DOCTYPE",[73,205,207],{"class":206},"sJ14y"," html",[73,209,210],{"class":198},">\n",[73,212,213,216,218],{"class":75,"line":82},[73,214,215],{"class":198},"\u003C",[73,217,191],{"class":202},[73,219,210],{"class":198},[73,221,222,224,227],{"class":75,"line":88},[73,223,215],{"class":198},[73,225,226],{"class":202},"head",[73,228,210],{"class":198},[73,230,231,234,237,240,243,246,250,252,255,257,259,262,264,267,269,271,274,276],{"class":75,"line":95},[73,232,233],{"class":198},"    \u003C",[73,235,236],{"class":202},"link",[73,238,239],{"class":206}," rel",[73,241,242],{"class":198},"=",[73,244,245],{"class":198},"\"",[73,247,249],{"class":248},"sfyAc","stylesheet",[73,251,245],{"class":198},[73,253,254],{"class":206}," type",[73,256,242],{"class":198},[73,258,245],{"class":198},[73,260,261],{"class":248},"text\u002Fcss",[73,263,245],{"class":198},[73,265,266],{"class":206}," href",[73,268,242],{"class":198},[73,270,245],{"class":198},[73,272,273],{"class":248},"\u002Fconcrete\u002Fthemes\u002Fconcrete\u002Fmain.css",[73,275,245],{"class":198},[73,277,278],{"class":198}," \u002F>\n",[73,280,281],{"class":75,"line":101},[73,282,284],{"class":283},"s0W1g","    \n",[73,286,287,289,292,295,298,301,303],{"class":75,"line":107},[73,288,215],{"class":198},[73,290,291],{"class":202},"title",[73,293,294],{"class":198},">",[73,296,297],{"class":283},"ログイン :: c5test",[73,299,300],{"class":198},"\u003C\u002F",[73,302,291],{"class":202},[73,304,210],{"class":198},[73,306,307],{"class":75,"line":113},[73,308,92],{"emptyLinePlaceholder":91},[73,310,311,313,316,319,321,323,326,328,331,333,335,338,340],{"class":75,"line":119},[73,312,215],{"class":198},[73,314,315],{"class":202},"meta",[73,317,318],{"class":206}," http-equiv",[73,320,242],{"class":198},[73,322,245],{"class":198},[73,324,325],{"class":248},"content-type",[73,327,245],{"class":198},[73,329,330],{"class":206}," content",[73,332,242],{"class":198},[73,334,245],{"class":198},[73,336,337],{"class":248},"text\u002Fhtml; charset=UTF-8",[73,339,245],{"class":198},[73,341,342],{"class":198},"\u002F>\n",[73,344,345,347,349,352,354,356,359,361,363,365,367,370,372],{"class":75,"line":125},[73,346,215],{"class":198},[73,348,315],{"class":202},[73,350,351],{"class":206}," name",[73,353,242],{"class":198},[73,355,245],{"class":198},[73,357,358],{"class":248},"generator",[73,360,245],{"class":198},[73,362,330],{"class":206},[73,364,242],{"class":198},[73,366,245],{"class":198},[73,368,369],{"class":248},"concrete5 - 8.5.4",[73,371,245],{"class":198},[73,373,342],{"class":198},[73,375,376,378,380,382,384,386,389,391,393,395,397,400,402],{"class":75,"line":131},[73,377,215],{"class":198},[73,379,236],{"class":202},[73,381,239],{"class":206},[73,383,242],{"class":198},[73,385,245],{"class":198},[73,387,388],{"class":248},"canonical",[73,390,245],{"class":198},[73,392,266],{"class":206},[73,394,242],{"class":198},[73,396,245],{"class":198},[73,398,399],{"class":248},"http:\u002F\u002Flocalhost:8888\u002Flogin",[73,401,245],{"class":198},[73,403,210],{"class":198},[73,405,406,408,411,413,415,417,420,422],{"class":75,"line":137},[73,407,215],{"class":198},[73,409,410],{"class":202},"script",[73,412,254],{"class":206},[73,414,242],{"class":198},[73,416,245],{"class":198},[73,418,419],{"class":248},"text\u002Fjavascript",[73,421,245],{"class":198},[73,423,210],{"class":198},[73,425,426,429,432,434,437,440,442],{"class":75,"line":142},[73,427,428],{"class":206},"    var",[73,430,431],{"class":283}," CCM_DISPATCHER_FILENAME ",[73,433,242],{"class":198},[73,435,436],{"class":198}," \"",[73,438,439],{"class":248},"\u002Findex.php",[73,441,245],{"class":198},[73,443,444],{"class":198},";\n",[73,446,447,449,452,454,458],{"class":75,"line":148},[73,448,428],{"class":206},[73,450,451],{"class":283}," CCM_CID ",[73,453,242],{"class":198},[73,455,457],{"class":456},"sx098"," 174",[73,459,444],{"class":198},[73,461,463,465,468,470,474],{"class":75,"line":462},14,[73,464,428],{"class":206},[73,466,467],{"class":283}," CCM_EDIT_MODE ",[73,469,242],{"class":198},[73,471,473],{"class":472},"sbqyR"," false",[73,475,444],{"class":198},[73,477,479,481,484,486,488],{"class":75,"line":478},15,[73,480,428],{"class":206},[73,482,483],{"class":283}," CCM_ARRANGE_MODE ",[73,485,242],{"class":198},[73,487,473],{"class":472},[73,489,444],{"class":198},[73,491,493,495,498,500,502,505,507],{"class":75,"line":492},16,[73,494,428],{"class":206},[73,496,497],{"class":283}," CCM_IMAGE_PATH ",[73,499,242],{"class":198},[73,501,436],{"class":198},[73,503,504],{"class":248},"\u002Fconcrete\u002Fimages",[73,506,245],{"class":198},[73,508,444],{"class":198},[73,510,512,514,517,519,521,524,526],{"class":75,"line":511},17,[73,513,428],{"class":206},[73,515,516],{"class":283}," CCM_TOOLS_PATH ",[73,518,242],{"class":198},[73,520,436],{"class":198},[73,522,523],{"class":248},"\u002Findex.php\u002Ftools\u002Frequired",[73,525,245],{"class":198},[73,527,444],{"class":198},[73,529,531,533,536,538,540,543,545],{"class":75,"line":530},18,[73,532,428],{"class":206},[73,534,535],{"class":283}," CCM_APPLICATION_URL ",[73,537,242],{"class":198},[73,539,436],{"class":198},[73,541,542],{"class":248},"http:\u002F\u002Flocalhost:8888",[73,544,245],{"class":198},[73,546,444],{"class":198},[73,548,550,552,555,557,560],{"class":75,"line":549},19,[73,551,428],{"class":206},[73,553,554],{"class":283}," CCM_REL ",[73,556,242],{"class":198},[73,558,559],{"class":198}," \"\"",[73,561,444],{"class":198},[73,563,565,567,570,572,574,577,579],{"class":75,"line":564},20,[73,566,428],{"class":206},[73,568,569],{"class":283}," CCM_ACTIVE_LOCALE ",[73,571,242],{"class":198},[73,573,436],{"class":198},[73,575,576],{"class":248},"ja_JP",[73,578,245],{"class":198},[73,580,444],{"class":198},[73,582,584,586,588],{"class":75,"line":583},21,[73,585,300],{"class":198},[73,587,410],{"class":202},[73,589,210],{"class":198},[178,591,594],{"className":592},[181,593],"alert-danger","\n内部の生データが外部からアクセスされるのは非常にまずいのでdashbord配下にルーティングを置き、さらにリクエストの種類をXHRだけにしましょう。\n",[40,596,598],{"id":597},"コンポーネントにajaxアクセスを実装","コンポーネントにAjaxアクセスを実装",[11,600,601,602,605],{},"URLとデータの取得処理は書いたので、vue側でそこにAjaxを飛ばすようにします。前回作成した",[32,603,604],{},"form.vue"," にAjaxの処理を書きます。",[48,607,611],{"className":608,"code":609,"filename":604,"language":610,"meta":56,"style":56},"language-vue shiki shiki-themes material-theme-ocean","created(){\n    if(this.isEdit){\n        $.ajax({\n            url:location.href,\n            type:'GET',\n            success: (data)=> {\n                let result = JSON.parse(data)[0]; \u002F\u002F returns array\n                this.title = result.title;\n            },\n            error: (xhr, textStatus, errorThrown)=>{\n                console.error('Error! ' + textStatus + ' ' + errorThrown);\n            }\n        })\n    }\n}\n","vue",[32,612,613,618,623,628,633,638,643,648,653,658,663,668,673,678,682],{"__ignoreMap":56},[73,614,615],{"class":75,"line":76},[73,616,617],{"class":283},"created(){\n",[73,619,620],{"class":75,"line":82},[73,621,622],{"class":283},"    if(this.isEdit){\n",[73,624,625],{"class":75,"line":88},[73,626,627],{"class":283},"        $.ajax({\n",[73,629,630],{"class":75,"line":95},[73,631,632],{"class":283},"            url:location.href,\n",[73,634,635],{"class":75,"line":101},[73,636,637],{"class":283},"            type:'GET',\n",[73,639,640],{"class":75,"line":107},[73,641,642],{"class":283},"            success: (data)=> {\n",[73,644,645],{"class":75,"line":113},[73,646,647],{"class":283},"                let result = JSON.parse(data)[0]; \u002F\u002F returns array\n",[73,649,650],{"class":75,"line":119},[73,651,652],{"class":283},"                this.title = result.title;\n",[73,654,655],{"class":75,"line":125},[73,656,657],{"class":283},"            },\n",[73,659,660],{"class":75,"line":131},[73,661,662],{"class":283},"            error: (xhr, textStatus, errorThrown)=>{\n",[73,664,665],{"class":75,"line":137},[73,666,667],{"class":283},"                console.error('Error! ' + textStatus + ' ' + errorThrown);\n",[73,669,670],{"class":75,"line":142},[73,671,672],{"class":283},"            }\n",[73,674,675],{"class":75,"line":148},[73,676,677],{"class":283},"        })\n",[73,679,680],{"class":75,"line":462},[73,681,134],{"class":283},[73,683,684],{"class":75,"line":478},[73,685,151],{"class":283},[11,687,688,690,691,694],{},[32,689,604],{},"は編集と新規追加を併用しているので、",[32,692,693],{},"isEdit","というプロパティでAjaxを飛ばすかを制御しています。現在のURLに対してAjaxを飛ばすと、先ほどのコードで書かれているようにIDに紐づいたアルバム情報をDBから取ってきてくれます。",[11,696,697,698,701],{},"データはJSONで戻ってくるので　",[32,699,700],{},"JSON.prase","を用いてJSで用いられるようにします。もし仮にAjaxが失敗した場合\b（400、500系のエラー）、コンソールでエラーが吐かれるようになっています。",[40,703,704],{"id":704},"編集用コンポーネントのレンダリング設定",[11,706,707],{},"シングルページそのものはエントリーポイントだけ。",[48,709,712],{"className":66,"code":710,"filename":711,"language":69,"meta":56,"style":56},"\u003C?php\ndefined('C5_EXECUTE') or die('Access Denied.');\n?>\n\n\u003Cdiv id=\"edit\">\u003C\u002Fdiv>\n","edit.php",[32,713,714,719,724,729,733],{"__ignoreMap":56},[73,715,716],{"class":75,"line":76},[73,717,718],{},"\u003C?php\n",[73,720,721],{"class":75,"line":82},[73,722,723],{},"defined('C5_EXECUTE') or die('Access Denied.');\n",[73,725,726],{"class":75,"line":88},[73,727,728],{},"?>\n",[73,730,731],{"class":75,"line":95},[73,732,92],{"emptyLinePlaceholder":91},[73,734,735],{"class":75,"line":101},[73,736,737],{},"\u003Cdiv id=\"edit\">\u003C\u002Fdiv>\n",[11,739,740,741,744],{},"そしてvue側のeditコンポーネントはpropsを変えるだけで",[32,742,743],{},"add.vue","とほぼ同じ",[48,746,749],{"className":608,"code":747,"filename":748,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003CAlbumForm :isEdit=\"true\"\u002F>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport AlbumForm from '.\u002Fcomponents\u002Fform';\nexport default {\n    name:'add',\n    components:{AlbumForm}\n}\n\u003C\u002Fscript>\n","edit.vue",[32,750,751,760,781,789,793,801,824,835,853,865,869],{"__ignoreMap":56},[73,752,753,755,758],{"class":75,"line":76},[73,754,215],{"class":198},[73,756,757],{"class":202},"template",[73,759,210],{"class":198},[73,761,762,764,767,770,772,774,777,779],{"class":75,"line":82},[73,763,233],{"class":198},[73,765,766],{"class":202},"AlbumForm",[73,768,769],{"class":206}," :isEdit",[73,771,242],{"class":198},[73,773,245],{"class":198},[73,775,776],{"class":248},"true",[73,778,245],{"class":198},[73,780,342],{"class":198},[73,782,783,785,787],{"class":75,"line":88},[73,784,300],{"class":198},[73,786,757],{"class":202},[73,788,210],{"class":198},[73,790,791],{"class":75,"line":95},[73,792,92],{"emptyLinePlaceholder":91},[73,794,795,797,799],{"class":75,"line":101},[73,796,215],{"class":198},[73,798,410],{"class":202},[73,800,210],{"class":198},[73,802,803,807,810,813,816,819,822],{"class":75,"line":107},[73,804,806],{"class":805},"s6cf3","import",[73,808,809],{"class":283}," AlbumForm ",[73,811,812],{"class":805},"from",[73,814,815],{"class":198}," '",[73,817,818],{"class":248},".\u002Fcomponents\u002Fform",[73,820,821],{"class":198},"'",[73,823,444],{"class":198},[73,825,826,829,832],{"class":75,"line":113},[73,827,828],{"class":805},"export",[73,830,831],{"class":805}," default",[73,833,834],{"class":198}," {\n",[73,836,837,840,843,845,848,850],{"class":75,"line":119},[73,838,839],{"class":202},"    name",[73,841,842],{"class":198},":",[73,844,821],{"class":198},[73,846,847],{"class":248},"add",[73,849,821],{"class":198},[73,851,852],{"class":198},",\n",[73,854,855,858,861,863],{"class":75,"line":125},[73,856,857],{"class":202},"    components",[73,859,860],{"class":198},":{",[73,862,766],{"class":283},[73,864,151],{"class":198},[73,866,867],{"class":75,"line":131},[73,868,151],{"class":198},[73,870,871,873,875],{"class":75,"line":137},[73,872,300],{"class":198},[73,874,410],{"class":202},[73,876,210],{"class":198},[11,878,879,880,883],{},"最後にレンダー用の",[32,881,882],{},"main.js","を以下のようにしておきます。",[48,885,889],{"className":886,"code":887,"filename":882,"language":888,"meta":56,"style":56},"language-javascript shiki shiki-themes material-theme-ocean","import Vue from 'vue'\nimport Add from '.\u002Fadd.vue'\nimport Edit from '.\u002Fedit.vue'\n\n\nVue.config.productionTip = false\n\nfunction renderIfidExits(id,vueRoot){\n  if(document.getElementById(id) !== null){\n    return new Vue({\n      render: h => h(vueRoot),\n    }).$mount('#'+id)\n  }\n}\n\nrenderIfidExits('add',Add);\nrenderIfidExits('edit',Edit);\n","javascript",[32,890,891,907,923,939,943,947,968,972,997,1031,1046,1069,1098,1103,1107,1111,1131],{"__ignoreMap":56},[73,892,893,895,898,900,902,904],{"class":75,"line":76},[73,894,806],{"class":805},[73,896,897],{"class":283}," Vue ",[73,899,812],{"class":805},[73,901,815],{"class":198},[73,903,610],{"class":248},[73,905,906],{"class":198},"'\n",[73,908,909,911,914,916,918,921],{"class":75,"line":82},[73,910,806],{"class":805},[73,912,913],{"class":283}," Add ",[73,915,812],{"class":805},[73,917,815],{"class":198},[73,919,920],{"class":248},".\u002Fadd.vue",[73,922,906],{"class":198},[73,924,925,927,930,932,934,937],{"class":75,"line":88},[73,926,806],{"class":805},[73,928,929],{"class":283}," Edit ",[73,931,812],{"class":805},[73,933,815],{"class":198},[73,935,936],{"class":248},".\u002Fedit.vue",[73,938,906],{"class":198},[73,940,941],{"class":75,"line":95},[73,942,92],{"emptyLinePlaceholder":91},[73,944,945],{"class":75,"line":101},[73,946,92],{"emptyLinePlaceholder":91},[73,948,949,952,955,958,960,963,965],{"class":75,"line":107},[73,950,951],{"class":283},"Vue",[73,953,954],{"class":198},".",[73,956,957],{"class":283},"config",[73,959,954],{"class":198},[73,961,962],{"class":283},"productionTip ",[73,964,242],{"class":198},[73,966,967],{"class":472}," false\n",[73,969,970],{"class":75,"line":113},[73,971,92],{"emptyLinePlaceholder":91},[73,973,974,977,981,984,988,991,994],{"class":75,"line":119},[73,975,976],{"class":206},"function",[73,978,980],{"class":979},"sdLwU"," renderIfidExits",[73,982,983],{"class":198},"(",[73,985,987],{"class":986},"s7ZW3","id",[73,989,990],{"class":198},",",[73,992,993],{"class":986},"vueRoot",[73,995,996],{"class":198},"){\n",[73,998,999,1002,1004,1007,1009,1012,1014,1016,1019,1022,1025,1028],{"class":75,"line":125},[73,1000,1001],{"class":805},"  if",[73,1003,983],{"class":202},[73,1005,1006],{"class":283},"document",[73,1008,954],{"class":198},[73,1010,1011],{"class":979},"getElementById",[73,1013,983],{"class":202},[73,1015,987],{"class":283},[73,1017,1018],{"class":202},") ",[73,1020,1021],{"class":198},"!==",[73,1023,1024],{"class":198}," null",[73,1026,1027],{"class":202},")",[73,1029,1030],{"class":198},"{\n",[73,1032,1033,1036,1039,1042,1044],{"class":75,"line":131},[73,1034,1035],{"class":805},"    return",[73,1037,1038],{"class":198}," new",[73,1040,1041],{"class":979}," Vue",[73,1043,983],{"class":202},[73,1045,1030],{"class":198},[73,1047,1048,1051,1053,1056,1059,1061,1063,1065,1067],{"class":75,"line":137},[73,1049,1050],{"class":979},"      render",[73,1052,842],{"class":198},[73,1054,1055],{"class":986}," h",[73,1057,1058],{"class":206}," =>",[73,1060,1055],{"class":979},[73,1062,983],{"class":202},[73,1064,993],{"class":283},[73,1066,1027],{"class":202},[73,1068,852],{"class":198},[73,1070,1071,1074,1076,1078,1081,1083,1085,1088,1090,1093,1095],{"class":75,"line":142},[73,1072,1073],{"class":198},"    }",[73,1075,1027],{"class":202},[73,1077,954],{"class":198},[73,1079,1080],{"class":979},"$mount",[73,1082,983],{"class":202},[73,1084,821],{"class":198},[73,1086,1087],{"class":248},"#",[73,1089,821],{"class":198},[73,1091,1092],{"class":198},"+",[73,1094,987],{"class":283},[73,1096,1097],{"class":202},")\n",[73,1099,1100],{"class":75,"line":148},[73,1101,1102],{"class":198},"  }\n",[73,1104,1105],{"class":75,"line":462},[73,1106,151],{"class":198},[73,1108,1109],{"class":75,"line":478},[73,1110,92],{"emptyLinePlaceholder":91},[73,1112,1113,1116,1118,1120,1122,1124,1126,1129],{"class":75,"line":492},[73,1114,1115],{"class":979},"renderIfidExits",[73,1117,983],{"class":283},[73,1119,821],{"class":198},[73,1121,847],{"class":248},[73,1123,821],{"class":198},[73,1125,990],{"class":198},[73,1127,1128],{"class":283},"Add)",[73,1130,444],{"class":198},[73,1132,1133,1135,1137,1139,1142,1144,1146,1149],{"class":75,"line":511},[73,1134,1115],{"class":979},[73,1136,983],{"class":283},[73,1138,821],{"class":198},[73,1140,1141],{"class":248},"edit",[73,1143,821],{"class":198},[73,1145,990],{"class":198},[73,1147,1148],{"class":283},"Edit)",[73,1150,444],{"class":198},[11,1152,1153],{},"前回はAddコンポーネントだけでしたが、今回はEditもあります。さらにこのmain.jsで全てのコンポーネントのレンダーを制御しているので、エントリーポイント のIDが存在すればそこにコンポーネントをレンダリングする。という方法を取っています。",[11,1155,1156,1157,1160],{},"本当はコンポーネントごとにレンダー用のjs（",[32,1158,1159],{},"add.js,edit.js","みたいな）を作成するのですが、面倒だったのでこうしました。",[11,1162,1163,1164,1167,1168,1171,1172,1175],{},"そしてform.vueで編集の場合（",[32,1165,1166],{},"isEdit = true","）に",[32,1169,1170],{},"created()","でAjaxを飛ばしてデータを取得し、",[32,1173,1174],{},"data()","に代入するようします。",[24,1177,1178],{"id":1178},"実際にレンダーしてみる",[11,1180,1181,1182,1185],{},"ビルドをして ",[32,1183,1184],{},"\u002Fdashboard\u002Fvuetest\u002Fedit\u002F{id}"," へアクセスします。IDがあっていればそのデータを取ってきてくれます。",[1187,1188],"image-render",{":src":1189,":width":1190},"'_mix\u002Fsch-2020-10-04-1.14.27-768x527.png'","'100%'",[1187,1192],{":src":1193,":width":1190},"'_mix\u002Fajax-768x764.png'",[11,1195,1196],{},"きちんと画面には前回入力した追加内容が表示されています。開発者ツールでNetworkでAjaxを確認してみましょう。Request Header を確認すると確かに、現在のURLにアクセスしておりさらにXMLHttpRequestで送信されています。Resonseをみてみると",[48,1198,1202],{"className":1199,"code":1200,"language":1201,"meta":56,"style":56},"language-json shiki shiki-themes material-theme-ocean","[\n    {\n        \"id\":\"1\",\n        \"title\":\"\\u30c6\\u30b9\\u30c8\",\n        \"created\":\"2020-08-27 00:28:38\",\n        \"modified\":\"2020-08-27 00:28:38\"\n    }\n]\n","json",[32,1203,1204,1209,1214,1234,1253,1273,1291,1295],{"__ignoreMap":56},[73,1205,1206],{"class":75,"line":76},[73,1207,1208],{"class":198},"[\n",[73,1210,1211],{"class":75,"line":82},[73,1212,1213],{"class":198},"    {\n",[73,1215,1216,1219,1221,1223,1225,1227,1230,1232],{"class":75,"line":88},[73,1217,1218],{"class":198},"        \"",[73,1220,987],{"class":206},[73,1222,245],{"class":198},[73,1224,842],{"class":198},[73,1226,245],{"class":198},[73,1228,1229],{"class":248},"1",[73,1231,245],{"class":198},[73,1233,852],{"class":198},[73,1235,1236,1238,1240,1242,1244,1246,1249,1251],{"class":75,"line":95},[73,1237,1218],{"class":198},[73,1239,291],{"class":206},[73,1241,245],{"class":198},[73,1243,842],{"class":198},[73,1245,245],{"class":198},[73,1247,1248],{"class":283},"\\u30c6\\u30b9\\u30c8",[73,1250,245],{"class":198},[73,1252,852],{"class":198},[73,1254,1255,1257,1260,1262,1264,1266,1269,1271],{"class":75,"line":101},[73,1256,1218],{"class":198},[73,1258,1259],{"class":206},"created",[73,1261,245],{"class":198},[73,1263,842],{"class":198},[73,1265,245],{"class":198},[73,1267,1268],{"class":248},"2020-08-27 00:28:38",[73,1270,245],{"class":198},[73,1272,852],{"class":198},[73,1274,1275,1277,1280,1282,1284,1286,1288],{"class":75,"line":107},[73,1276,1218],{"class":198},[73,1278,1279],{"class":206},"modified",[73,1281,245],{"class":198},[73,1283,842],{"class":198},[73,1285,245],{"class":198},[73,1287,1268],{"class":248},[73,1289,1290],{"class":198},"\"\n",[73,1292,1293],{"class":75,"line":113},[73,1294,134],{"class":198},[73,1296,1297],{"class":75,"line":119},[73,1298,1299],{"class":198},"]\n",[11,1301,1302],{},"このようにデータベースから取ってきた内容がJSONとして渡されているのが確認できます。ちなみに日本語はエンコードされているので、js側でJSON praseを使うことで元の文章に戻すことができます。",[24,1304,1305],{"id":1305},"内容を更新する",[11,1307,1308,1309,1311],{},"編集画面を表示した際の初期表示はできるようになったので、次は内容が書き換えてDBの内容を変更できるようにしましょう。しかし触るのはバックエンドの部分だけです。",[32,1310,62],{},"を以下のように変更します。",[48,1313,1315],{"className":66,"code":1314,"filename":68,"language":69,"meta":56,"style":56},"pupublic function edit($id=null){\n\n    \u002F\u002F パラメータがない場合は一覧画面へリダイレクト\n    if($id==null) return Redirect::to('\u002Fdashboard\u002Fvuetest\u002F')->send();\n\n    \u002F\u002F Ajax エンドポイント\n    if($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){\n        $db = Database::connection();\n        $db->Execute(\"START TRANSACTION\");\n        $result = $db->fetchAll('SELECT * FROM album ORDER BY ID DESC');\n        $db->Execute(\"COMMIT\");\n        return Core::make('helper\u002Fajax')->sendResult($result);\n    }\n\n    \u002F\u002Fpost処理(ここを追記)\n    if(Request::isPost() == true){\n        $title = $this->post('title');\n\n        if(empty($title)==false){\n            $db = Database::connection();\n            $db->executeQuery(\"START TRANSACTION\");\n            $db->executeQuery(\n                'UPDATE album SET `title`=?, `modified`=now() WHERE `ID`=?',\n                array($title,$id)\n            );\n            $db->executeQuery(\"COMMIT\");\n            Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n        }else{\n            Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n        }\n\n    }else{\n        $this->render('\u002Fdashboard\u002Fvuetest\u002Fadd');\n    }\n}\n",[32,1316,1317,1322,1326,1331,1335,1339,1344,1348,1352,1356,1361,1365,1369,1373,1377,1382,1387,1392,1396,1401,1406,1411,1417,1423,1429,1435,1441,1447,1453,1458,1464,1469,1475,1481,1486],{"__ignoreMap":56},[73,1318,1319],{"class":75,"line":76},[73,1320,1321],{},"pupublic function edit($id=null){\n",[73,1323,1324],{"class":75,"line":82},[73,1325,92],{"emptyLinePlaceholder":91},[73,1327,1328],{"class":75,"line":88},[73,1329,1330],{},"    \u002F\u002F パラメータがない場合は一覧画面へリダイレクト\n",[73,1332,1333],{"class":75,"line":95},[73,1334,85],{},[73,1336,1337],{"class":75,"line":101},[73,1338,92],{"emptyLinePlaceholder":91},[73,1340,1341],{"class":75,"line":107},[73,1342,1343],{},"    \u002F\u002F Ajax エンドポイント\n",[73,1345,1346],{"class":75,"line":113},[73,1347,98],{},[73,1349,1350],{"class":75,"line":119},[73,1351,104],{},[73,1353,1354],{"class":75,"line":125},[73,1355,110],{},[73,1357,1358],{"class":75,"line":131},[73,1359,1360],{},"        $result = $db->fetchAll('SELECT * FROM album ORDER BY ID DESC');\n",[73,1362,1363],{"class":75,"line":137},[73,1364,122],{},[73,1366,1367],{"class":75,"line":142},[73,1368,128],{},[73,1370,1371],{"class":75,"line":148},[73,1372,134],{},[73,1374,1375],{"class":75,"line":462},[73,1376,92],{"emptyLinePlaceholder":91},[73,1378,1379],{"class":75,"line":478},[73,1380,1381],{},"    \u002F\u002Fpost処理(ここを追記)\n",[73,1383,1384],{"class":75,"line":492},[73,1385,1386],{},"    if(Request::isPost() == true){\n",[73,1388,1389],{"class":75,"line":511},[73,1390,1391],{},"        $title = $this->post('title');\n",[73,1393,1394],{"class":75,"line":530},[73,1395,92],{"emptyLinePlaceholder":91},[73,1397,1398],{"class":75,"line":549},[73,1399,1400],{},"        if(empty($title)==false){\n",[73,1402,1403],{"class":75,"line":564},[73,1404,1405],{},"            $db = Database::connection();\n",[73,1407,1408],{"class":75,"line":583},[73,1409,1410],{},"            $db->executeQuery(\"START TRANSACTION\");\n",[73,1412,1414],{"class":75,"line":1413},22,[73,1415,1416],{},"            $db->executeQuery(\n",[73,1418,1420],{"class":75,"line":1419},23,[73,1421,1422],{},"                'UPDATE album SET `title`=?, `modified`=now() WHERE `ID`=?',\n",[73,1424,1426],{"class":75,"line":1425},24,[73,1427,1428],{},"                array($title,$id)\n",[73,1430,1432],{"class":75,"line":1431},25,[73,1433,1434],{},"            );\n",[73,1436,1438],{"class":75,"line":1437},26,[73,1439,1440],{},"            $db->executeQuery(\"COMMIT\");\n",[73,1442,1444],{"class":75,"line":1443},27,[73,1445,1446],{},"            Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n",[73,1448,1450],{"class":75,"line":1449},28,[73,1451,1452],{},"        }else{\n",[73,1454,1456],{"class":75,"line":1455},29,[73,1457,1446],{},[73,1459,1461],{"class":75,"line":1460},30,[73,1462,1463],{},"        }\n",[73,1465,1467],{"class":75,"line":1466},31,[73,1468,92],{"emptyLinePlaceholder":91},[73,1470,1472],{"class":75,"line":1471},32,[73,1473,1474],{},"    }else{\n",[73,1476,1478],{"class":75,"line":1477},33,[73,1479,1480],{},"        $this->render('\u002Fdashboard\u002Fvuetest\u002Fadd');\n",[73,1482,1484],{"class":75,"line":1483},34,[73,1485,134],{},[73,1487,1489],{"class":75,"line":1488},35,[73,1490,151],{},[11,1492,1493,1494,1497],{},"新規作成の際に使用される",[32,1495,1496],{},"pupublic function edit"," を一部変更したぐらいです。postがある場合、その値のバリデーションをして変更するIDを元に更新用のSQLを走らせるだけです。",[40,1499,1500],{"id":1500},"実際に変更してみる",[1187,1502],{":src":1503,":width":1190},"'_mix\u002Fsch-2020-10-04-13.37.28-768x396.png'",[1187,1505],{":src":1506,":width":1190},"'_mix\u002Fsch-2020-10-04-13.38.13.png'",[11,1508,1509],{},"無事、タイトルと編集時間が更新されました。これでCRUDの「Update」が完成しました。",[24,1511,1512],{"id":1512},"一覧画面を作成する",[11,1514,1515],{},"追加・編集の画面は完成しました。次は全ての登録データを一覧で見れる画面を作成していきます。\u002Fdashboard\u002Fvuetest\u002F にアクセスした際に一覧が表示されるようにします。",[40,1517,1518],{"id":1518},"一覧用コンポーネントの作成",[11,1520,1521],{},"一覧コンポーネントをindex.vueとしておきます。一覧画面では以下のような構成にしています。",[48,1523,1526],{"className":608,"code":1524,"filename":1525,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003Cdiv class=\"ccm-dashboard-content-inner\">\n        \u003Ch3>アルバム一覧\u003C\u002Fh3>\n        \u003Chr>\n\n        \u003Ctable class=\"p-package-index table table-hover\">\n            \u003Cthead>\n                \u003Ctr>\n                    \u003Cth class=\"c-dol-title\">タイトル\u003C\u002Fth>\n                    \u003Cth class=\"c-dol-publish-date\">作成日\u003C\u002Fth>\n                    \u003Cth class=\"c-dol-operation\">操作\u003C\u002Fth>\n                \u003C\u002Ftr>\n            \u003C\u002Fthead>\n            \u003Ctbody>\n                \u003Ctr v-for=\"val in list\" :key=\"val.id\" tabindex=\"0\">\n                    \u003Ctd style=\"vertical-align:middle;\">{{val.title}}\u003C\u002Ftd>\n                    \u003Ctd style=\"vertical-align:middle;\">{{val.created}}\u003C\u002Ftd>\n                    \u003Ctd style=\"vertical-align:middle;\">\n                        \u003Ca :href=\"'\u002Fdashboard\u002Fvuetest\u002Fedit\u002F'+val.id\" type=\"button\" class=\"btn btn-success btn-sm\" style=\"margin-right:10px;\">編集\u003C\u002Fa>\n                        \u003Cbutton type=\"button\" class=\"btn btn-danger btn-sm\" v-on:click=\"cofirmDelete(val)\">削除\u003C\u002Fbutton>\n                    \u003C\u002Ftd>\n                \u003C\u002Ftr>\n            \u003C\u002Ftbody>\n        \u003C\u002Ftable>\n\n        \u003Cdiv class=\"ccm-dashboard-form-actions-wrapper\">\n            \u003Cdiv class=\"ccm-dashboard-form-actions\">\n                \u003Ca href=\"\u002Fdashboard\u002Fvuetest\u002Fadd\" class=\"pull-right btn btn-primary\">\n                    新規追加\n                \u003C\u002Fa>\n            \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n    name:'index',\n    data(){\n        return {\n            list:[],\n            isProcessing:false\n        }\n    },\n    methods:{\n        cofirmDelete(obj){\n            let result = window.confirm('アルバム：「'+obj.title+'」を本当に削除しますか？この操作は取り消せません。');\n            if(result) return this.deleteAlubm(obj.id);\n        },\n        deleteAlubm(id){\n            if(this.isProcessing==false){\n                this.isProcessing = true;\n\n                $.ajax({\n                    url:'\u002Fdashboard\u002Fvuetest\u002FdeleteData\u002F',\n                    type:'POST',\n                    data:{target:id},\n                    success: ()=> {\n                        let targetIndex = this.list.findIndex((ele)=>{\n                            return ele.ID == id;\n                        });\n                        this.list.splice(targetIndex,1);\n                        this.isProcessing = false;\n                    },\n                    error: (xhr, textStatus, errorThrown)=>{\n                        console.log('Error! ' + textStatus + ' ' + errorThrown);\n                    }\n                })\n            }\n        },\n    },\n    created(){\n        $.ajax({\n            url:'\u002Fdashboard\u002Fvuetest\u002FloadData',\n            type:'GET',\n            success: (data)=> {\n                this.list = JSON.parse(data); \u002F\u002F returns array\n            },\n            error: (xhr, textStatus, errorThrown)=>{\n                console.error('Error! ' + textStatus + ' ' + errorThrown);\n            }\n        })\n    }\n}\n\u003C\u002Fscript>\n","index.vue",[32,1527,1528,1536,1556,1574,1583,1587,1607,1617,1627,1657,1685,1713,1722,1731,1740,1784,1814,1841,1859,1922,1972,1981,1989,1997,2006,2010,2029,2048,2078,2083,2091,2099,2107,2116,2124,2128,2137,2146,2162,2171,2179,2192,2203,2208,2214,2223,2236,2286,2320,2326,2338,2361,2376,2381,2396,2413,2430,2448,2464,2498,2520,2530,2556,2569,2575,2605,2644,2650,2658,2663,2668,2673,2681,2695,2711,2728,2747,2777,2782,2808,2845,2850,2858,2863,2868],{"__ignoreMap":56},[73,1529,1530,1532,1534],{"class":75,"line":76},[73,1531,215],{"class":198},[73,1533,757],{"class":202},[73,1535,210],{"class":198},[73,1537,1538,1540,1542,1545,1547,1549,1552,1554],{"class":75,"line":82},[73,1539,233],{"class":198},[73,1541,178],{"class":202},[73,1543,1544],{"class":206}," class",[73,1546,242],{"class":198},[73,1548,245],{"class":198},[73,1550,1551],{"class":248},"ccm-dashboard-content-inner",[73,1553,245],{"class":198},[73,1555,210],{"class":198},[73,1557,1558,1561,1563,1565,1568,1570,1572],{"class":75,"line":88},[73,1559,1560],{"class":198},"        \u003C",[73,1562,40],{"class":202},[73,1564,294],{"class":198},[73,1566,1567],{"class":283},"アルバム一覧",[73,1569,300],{"class":198},[73,1571,40],{"class":202},[73,1573,210],{"class":198},[73,1575,1576,1578,1581],{"class":75,"line":95},[73,1577,1560],{"class":198},[73,1579,1580],{"class":202},"hr",[73,1582,210],{"class":198},[73,1584,1585],{"class":75,"line":101},[73,1586,92],{"emptyLinePlaceholder":91},[73,1588,1589,1591,1594,1596,1598,1600,1603,1605],{"class":75,"line":107},[73,1590,1560],{"class":198},[73,1592,1593],{"class":202},"table",[73,1595,1544],{"class":206},[73,1597,242],{"class":198},[73,1599,245],{"class":198},[73,1601,1602],{"class":248},"p-package-index table table-hover",[73,1604,245],{"class":198},[73,1606,210],{"class":198},[73,1608,1609,1612,1615],{"class":75,"line":113},[73,1610,1611],{"class":198},"            \u003C",[73,1613,1614],{"class":202},"thead",[73,1616,210],{"class":198},[73,1618,1619,1622,1625],{"class":75,"line":119},[73,1620,1621],{"class":198},"                \u003C",[73,1623,1624],{"class":202},"tr",[73,1626,210],{"class":198},[73,1628,1629,1632,1635,1637,1639,1641,1644,1646,1648,1651,1653,1655],{"class":75,"line":125},[73,1630,1631],{"class":198},"                    \u003C",[73,1633,1634],{"class":202},"th",[73,1636,1544],{"class":206},[73,1638,242],{"class":198},[73,1640,245],{"class":198},[73,1642,1643],{"class":248},"c-dol-title",[73,1645,245],{"class":198},[73,1647,294],{"class":198},[73,1649,1650],{"class":283},"タイトル",[73,1652,300],{"class":198},[73,1654,1634],{"class":202},[73,1656,210],{"class":198},[73,1658,1659,1661,1663,1665,1667,1669,1672,1674,1676,1679,1681,1683],{"class":75,"line":131},[73,1660,1631],{"class":198},[73,1662,1634],{"class":202},[73,1664,1544],{"class":206},[73,1666,242],{"class":198},[73,1668,245],{"class":198},[73,1670,1671],{"class":248},"c-dol-publish-date",[73,1673,245],{"class":198},[73,1675,294],{"class":198},[73,1677,1678],{"class":283},"作成日",[73,1680,300],{"class":198},[73,1682,1634],{"class":202},[73,1684,210],{"class":198},[73,1686,1687,1689,1691,1693,1695,1697,1700,1702,1704,1707,1709,1711],{"class":75,"line":137},[73,1688,1631],{"class":198},[73,1690,1634],{"class":202},[73,1692,1544],{"class":206},[73,1694,242],{"class":198},[73,1696,245],{"class":198},[73,1698,1699],{"class":248},"c-dol-operation",[73,1701,245],{"class":198},[73,1703,294],{"class":198},[73,1705,1706],{"class":283},"操作",[73,1708,300],{"class":198},[73,1710,1634],{"class":202},[73,1712,210],{"class":198},[73,1714,1715,1718,1720],{"class":75,"line":142},[73,1716,1717],{"class":198},"                \u003C\u002F",[73,1719,1624],{"class":202},[73,1721,210],{"class":198},[73,1723,1724,1727,1729],{"class":75,"line":148},[73,1725,1726],{"class":198},"            \u003C\u002F",[73,1728,1614],{"class":202},[73,1730,210],{"class":198},[73,1732,1733,1735,1738],{"class":75,"line":462},[73,1734,1611],{"class":198},[73,1736,1737],{"class":202},"tbody",[73,1739,210],{"class":198},[73,1741,1742,1744,1746,1749,1751,1753,1756,1758,1761,1763,1765,1768,1770,1773,1775,1777,1780,1782],{"class":75,"line":478},[73,1743,1621],{"class":198},[73,1745,1624],{"class":202},[73,1747,1748],{"class":206}," v-for",[73,1750,242],{"class":198},[73,1752,245],{"class":198},[73,1754,1755],{"class":248},"val in list",[73,1757,245],{"class":198},[73,1759,1760],{"class":206}," :key",[73,1762,242],{"class":198},[73,1764,245],{"class":198},[73,1766,1767],{"class":248},"val.id",[73,1769,245],{"class":198},[73,1771,1772],{"class":206}," tabindex",[73,1774,242],{"class":198},[73,1776,245],{"class":198},[73,1778,1779],{"class":248},"0",[73,1781,245],{"class":198},[73,1783,210],{"class":198},[73,1785,1786,1788,1791,1794,1796,1798,1801,1803,1805,1808,1810,1812],{"class":75,"line":492},[73,1787,1631],{"class":198},[73,1789,1790],{"class":202},"td",[73,1792,1793],{"class":206}," style",[73,1795,242],{"class":198},[73,1797,245],{"class":198},[73,1799,1800],{"class":248},"vertical-align:middle;",[73,1802,245],{"class":198},[73,1804,294],{"class":198},[73,1806,1807],{"class":283},"{{val.title}}",[73,1809,300],{"class":198},[73,1811,1790],{"class":202},[73,1813,210],{"class":198},[73,1815,1816,1818,1820,1822,1824,1826,1828,1830,1832,1835,1837,1839],{"class":75,"line":511},[73,1817,1631],{"class":198},[73,1819,1790],{"class":202},[73,1821,1793],{"class":206},[73,1823,242],{"class":198},[73,1825,245],{"class":198},[73,1827,1800],{"class":248},[73,1829,245],{"class":198},[73,1831,294],{"class":198},[73,1833,1834],{"class":283},"{{val.created}}",[73,1836,300],{"class":198},[73,1838,1790],{"class":202},[73,1840,210],{"class":198},[73,1842,1843,1845,1847,1849,1851,1853,1855,1857],{"class":75,"line":530},[73,1844,1631],{"class":198},[73,1846,1790],{"class":202},[73,1848,1793],{"class":206},[73,1850,242],{"class":198},[73,1852,245],{"class":198},[73,1854,1800],{"class":248},[73,1856,245],{"class":198},[73,1858,210],{"class":198},[73,1860,1861,1864,1866,1869,1871,1873,1876,1878,1880,1882,1884,1887,1889,1891,1893,1895,1898,1900,1902,1904,1906,1909,1911,1913,1916,1918,1920],{"class":75,"line":549},[73,1862,1863],{"class":198},"                        \u003C",[73,1865,15],{"class":202},[73,1867,1868],{"class":206}," :href",[73,1870,242],{"class":198},[73,1872,245],{"class":198},[73,1874,1875],{"class":248},"'\u002Fdashboard\u002Fvuetest\u002Fedit\u002F'+val.id",[73,1877,245],{"class":198},[73,1879,254],{"class":206},[73,1881,242],{"class":198},[73,1883,245],{"class":198},[73,1885,1886],{"class":248},"button",[73,1888,245],{"class":198},[73,1890,1544],{"class":206},[73,1892,242],{"class":198},[73,1894,245],{"class":198},[73,1896,1897],{"class":248},"btn btn-success btn-sm",[73,1899,245],{"class":198},[73,1901,1793],{"class":206},[73,1903,242],{"class":198},[73,1905,245],{"class":198},[73,1907,1908],{"class":248},"margin-right:10px;",[73,1910,245],{"class":198},[73,1912,294],{"class":198},[73,1914,1915],{"class":283},"編集",[73,1917,300],{"class":198},[73,1919,15],{"class":202},[73,1921,210],{"class":198},[73,1923,1924,1926,1928,1930,1932,1934,1936,1938,1940,1942,1944,1947,1949,1952,1954,1956,1959,1961,1963,1966,1968,1970],{"class":75,"line":564},[73,1925,1863],{"class":198},[73,1927,1886],{"class":202},[73,1929,254],{"class":206},[73,1931,242],{"class":198},[73,1933,245],{"class":198},[73,1935,1886],{"class":248},[73,1937,245],{"class":198},[73,1939,1544],{"class":206},[73,1941,242],{"class":198},[73,1943,245],{"class":198},[73,1945,1946],{"class":248},"btn btn-danger btn-sm",[73,1948,245],{"class":198},[73,1950,1951],{"class":206}," v-on:click",[73,1953,242],{"class":198},[73,1955,245],{"class":198},[73,1957,1958],{"class":248},"cofirmDelete(val)",[73,1960,245],{"class":198},[73,1962,294],{"class":198},[73,1964,1965],{"class":283},"削除",[73,1967,300],{"class":198},[73,1969,1886],{"class":202},[73,1971,210],{"class":198},[73,1973,1974,1977,1979],{"class":75,"line":583},[73,1975,1976],{"class":198},"                    \u003C\u002F",[73,1978,1790],{"class":202},[73,1980,210],{"class":198},[73,1982,1983,1985,1987],{"class":75,"line":1413},[73,1984,1717],{"class":198},[73,1986,1624],{"class":202},[73,1988,210],{"class":198},[73,1990,1991,1993,1995],{"class":75,"line":1419},[73,1992,1726],{"class":198},[73,1994,1737],{"class":202},[73,1996,210],{"class":198},[73,1998,1999,2002,2004],{"class":75,"line":1425},[73,2000,2001],{"class":198},"        \u003C\u002F",[73,2003,1593],{"class":202},[73,2005,210],{"class":198},[73,2007,2008],{"class":75,"line":1431},[73,2009,92],{"emptyLinePlaceholder":91},[73,2011,2012,2014,2016,2018,2020,2022,2025,2027],{"class":75,"line":1437},[73,2013,1560],{"class":198},[73,2015,178],{"class":202},[73,2017,1544],{"class":206},[73,2019,242],{"class":198},[73,2021,245],{"class":198},[73,2023,2024],{"class":248},"ccm-dashboard-form-actions-wrapper",[73,2026,245],{"class":198},[73,2028,210],{"class":198},[73,2030,2031,2033,2035,2037,2039,2041,2044,2046],{"class":75,"line":1443},[73,2032,1611],{"class":198},[73,2034,178],{"class":202},[73,2036,1544],{"class":206},[73,2038,242],{"class":198},[73,2040,245],{"class":198},[73,2042,2043],{"class":248},"ccm-dashboard-form-actions",[73,2045,245],{"class":198},[73,2047,210],{"class":198},[73,2049,2050,2052,2054,2056,2058,2060,2063,2065,2067,2069,2071,2074,2076],{"class":75,"line":1449},[73,2051,1621],{"class":198},[73,2053,15],{"class":202},[73,2055,266],{"class":206},[73,2057,242],{"class":198},[73,2059,245],{"class":198},[73,2061,2062],{"class":248},"\u002Fdashboard\u002Fvuetest\u002Fadd",[73,2064,245],{"class":198},[73,2066,1544],{"class":206},[73,2068,242],{"class":198},[73,2070,245],{"class":198},[73,2072,2073],{"class":248},"pull-right btn btn-primary",[73,2075,245],{"class":198},[73,2077,210],{"class":198},[73,2079,2080],{"class":75,"line":1455},[73,2081,2082],{"class":283},"                    新規追加\n",[73,2084,2085,2087,2089],{"class":75,"line":1460},[73,2086,1717],{"class":198},[73,2088,15],{"class":202},[73,2090,210],{"class":198},[73,2092,2093,2095,2097],{"class":75,"line":1466},[73,2094,1726],{"class":198},[73,2096,178],{"class":202},[73,2098,210],{"class":198},[73,2100,2101,2103,2105],{"class":75,"line":1471},[73,2102,2001],{"class":198},[73,2104,178],{"class":202},[73,2106,210],{"class":198},[73,2108,2109,2112,2114],{"class":75,"line":1477},[73,2110,2111],{"class":198},"    \u003C\u002F",[73,2113,178],{"class":202},[73,2115,210],{"class":198},[73,2117,2118,2120,2122],{"class":75,"line":1483},[73,2119,300],{"class":198},[73,2121,757],{"class":202},[73,2123,210],{"class":198},[73,2125,2126],{"class":75,"line":1488},[73,2127,92],{"emptyLinePlaceholder":91},[73,2129,2131,2133,2135],{"class":75,"line":2130},36,[73,2132,215],{"class":198},[73,2134,410],{"class":202},[73,2136,210],{"class":198},[73,2138,2140,2142,2144],{"class":75,"line":2139},37,[73,2141,828],{"class":805},[73,2143,831],{"class":805},[73,2145,834],{"class":198},[73,2147,2149,2151,2153,2155,2158,2160],{"class":75,"line":2148},38,[73,2150,839],{"class":202},[73,2152,842],{"class":198},[73,2154,821],{"class":198},[73,2156,2157],{"class":248},"index",[73,2159,821],{"class":198},[73,2161,852],{"class":198},[73,2163,2165,2168],{"class":75,"line":2164},39,[73,2166,2167],{"class":202},"    data",[73,2169,2170],{"class":198},"(){\n",[73,2172,2174,2177],{"class":75,"line":2173},40,[73,2175,2176],{"class":805},"        return",[73,2178,834],{"class":198},[73,2180,2182,2185,2187,2190],{"class":75,"line":2181},41,[73,2183,2184],{"class":202},"            list",[73,2186,842],{"class":198},[73,2188,2189],{"class":202},"[]",[73,2191,852],{"class":198},[73,2193,2195,2198,2200],{"class":75,"line":2194},42,[73,2196,2197],{"class":202},"            isProcessing",[73,2199,842],{"class":198},[73,2201,2202],{"class":472},"false\n",[73,2204,2206],{"class":75,"line":2205},43,[73,2207,1463],{"class":198},[73,2209,2211],{"class":75,"line":2210},44,[73,2212,2213],{"class":198},"    },\n",[73,2215,2217,2220],{"class":75,"line":2216},45,[73,2218,2219],{"class":202},"    methods",[73,2221,2222],{"class":198},":{\n",[73,2224,2226,2229,2231,2234],{"class":75,"line":2225},46,[73,2227,2228],{"class":202},"        cofirmDelete",[73,2230,983],{"class":198},[73,2232,2233],{"class":986},"obj",[73,2235,996],{"class":198},[73,2237,2239,2242,2245,2248,2251,2253,2256,2258,2260,2263,2265,2267,2269,2271,2273,2275,2277,2280,2282,2284],{"class":75,"line":2238},47,[73,2240,2241],{"class":206},"            let",[73,2243,2244],{"class":283}," result",[73,2246,2247],{"class":198}," =",[73,2249,2250],{"class":283}," window",[73,2252,954],{"class":198},[73,2254,2255],{"class":979},"confirm",[73,2257,983],{"class":202},[73,2259,821],{"class":198},[73,2261,2262],{"class":248},"アルバム：「",[73,2264,821],{"class":198},[73,2266,1092],{"class":198},[73,2268,2233],{"class":283},[73,2270,954],{"class":198},[73,2272,291],{"class":283},[73,2274,1092],{"class":198},[73,2276,821],{"class":198},[73,2278,2279],{"class":248},"」を本当に削除しますか？この操作は取り消せません。",[73,2281,821],{"class":198},[73,2283,1027],{"class":202},[73,2285,444],{"class":198},[73,2287,2289,2292,2294,2297,2299,2302,2305,2308,2310,2312,2314,2316,2318],{"class":75,"line":2288},48,[73,2290,2291],{"class":805},"            if",[73,2293,983],{"class":202},[73,2295,2296],{"class":283},"result",[73,2298,1018],{"class":202},[73,2300,2301],{"class":805},"return",[73,2303,2304],{"class":198}," this.",[73,2306,2307],{"class":979},"deleteAlubm",[73,2309,983],{"class":202},[73,2311,2233],{"class":283},[73,2313,954],{"class":198},[73,2315,987],{"class":283},[73,2317,1027],{"class":202},[73,2319,444],{"class":198},[73,2321,2323],{"class":75,"line":2322},49,[73,2324,2325],{"class":198},"        },\n",[73,2327,2329,2332,2334,2336],{"class":75,"line":2328},50,[73,2330,2331],{"class":202},"        deleteAlubm",[73,2333,983],{"class":198},[73,2335,987],{"class":986},[73,2337,996],{"class":198},[73,2339,2341,2343,2345,2348,2351,2354,2357,2359],{"class":75,"line":2340},51,[73,2342,2291],{"class":805},[73,2344,983],{"class":202},[73,2346,2347],{"class":198},"this.",[73,2349,2350],{"class":283},"isProcessing",[73,2352,2353],{"class":198},"==",[73,2355,2356],{"class":472},"false",[73,2358,1027],{"class":202},[73,2360,1030],{"class":198},[73,2362,2364,2367,2369,2371,2374],{"class":75,"line":2363},52,[73,2365,2366],{"class":198},"                this.",[73,2368,2350],{"class":283},[73,2370,2247],{"class":198},[73,2372,2373],{"class":472}," true",[73,2375,444],{"class":198},[73,2377,2379],{"class":75,"line":2378},53,[73,2380,92],{"emptyLinePlaceholder":91},[73,2382,2384,2387,2389,2392,2394],{"class":75,"line":2383},54,[73,2385,2386],{"class":283},"                $",[73,2388,954],{"class":198},[73,2390,2391],{"class":979},"ajax",[73,2393,983],{"class":202},[73,2395,1030],{"class":198},[73,2397,2399,2402,2404,2406,2409,2411],{"class":75,"line":2398},55,[73,2400,2401],{"class":202},"                    url",[73,2403,842],{"class":198},[73,2405,821],{"class":198},[73,2407,2408],{"class":248},"\u002Fdashboard\u002Fvuetest\u002FdeleteData\u002F",[73,2410,821],{"class":198},[73,2412,852],{"class":198},[73,2414,2416,2419,2421,2423,2426,2428],{"class":75,"line":2415},56,[73,2417,2418],{"class":202},"                    type",[73,2420,842],{"class":198},[73,2422,821],{"class":198},[73,2424,2425],{"class":248},"POST",[73,2427,821],{"class":198},[73,2429,852],{"class":198},[73,2431,2433,2436,2438,2441,2443,2445],{"class":75,"line":2432},57,[73,2434,2435],{"class":202},"                    data",[73,2437,860],{"class":198},[73,2439,2440],{"class":202},"target",[73,2442,842],{"class":198},[73,2444,987],{"class":283},[73,2446,2447],{"class":198},"},\n",[73,2449,2451,2454,2456,2459,2462],{"class":75,"line":2450},58,[73,2452,2453],{"class":979},"                    success",[73,2455,842],{"class":198},[73,2457,2458],{"class":198}," ()",[73,2460,2461],{"class":206},"=>",[73,2463,834],{"class":198},[73,2465,2467,2470,2473,2475,2477,2480,2482,2485,2487,2489,2492,2494,2496],{"class":75,"line":2466},59,[73,2468,2469],{"class":206},"                        let",[73,2471,2472],{"class":283}," targetIndex",[73,2474,2247],{"class":198},[73,2476,2304],{"class":198},[73,2478,2479],{"class":283},"list",[73,2481,954],{"class":198},[73,2483,2484],{"class":979},"findIndex",[73,2486,983],{"class":202},[73,2488,983],{"class":198},[73,2490,2491],{"class":986},"ele",[73,2493,1027],{"class":198},[73,2495,2461],{"class":206},[73,2497,1030],{"class":198},[73,2499,2501,2504,2507,2509,2512,2515,2518],{"class":75,"line":2500},60,[73,2502,2503],{"class":805},"                            return",[73,2505,2506],{"class":283}," ele",[73,2508,954],{"class":198},[73,2510,2511],{"class":283},"ID",[73,2513,2514],{"class":198}," ==",[73,2516,2517],{"class":283}," id",[73,2519,444],{"class":198},[73,2521,2523,2526,2528],{"class":75,"line":2522},61,[73,2524,2525],{"class":198},"                        }",[73,2527,1027],{"class":202},[73,2529,444],{"class":198},[73,2531,2533,2536,2538,2540,2543,2545,2548,2550,2552,2554],{"class":75,"line":2532},62,[73,2534,2535],{"class":198},"                        this.",[73,2537,2479],{"class":283},[73,2539,954],{"class":198},[73,2541,2542],{"class":979},"splice",[73,2544,983],{"class":202},[73,2546,2547],{"class":283},"targetIndex",[73,2549,990],{"class":198},[73,2551,1229],{"class":456},[73,2553,1027],{"class":202},[73,2555,444],{"class":198},[73,2557,2559,2561,2563,2565,2567],{"class":75,"line":2558},63,[73,2560,2535],{"class":198},[73,2562,2350],{"class":283},[73,2564,2247],{"class":198},[73,2566,473],{"class":472},[73,2568,444],{"class":198},[73,2570,2572],{"class":75,"line":2571},64,[73,2573,2574],{"class":198},"                    },\n",[73,2576,2578,2581,2583,2586,2589,2591,2594,2596,2599,2601,2603],{"class":75,"line":2577},65,[73,2579,2580],{"class":979},"                    error",[73,2582,842],{"class":198},[73,2584,2585],{"class":198}," (",[73,2587,2588],{"class":986},"xhr",[73,2590,990],{"class":198},[73,2592,2593],{"class":986}," textStatus",[73,2595,990],{"class":198},[73,2597,2598],{"class":986}," errorThrown",[73,2600,1027],{"class":198},[73,2602,2461],{"class":206},[73,2604,1030],{"class":198},[73,2606,2608,2611,2613,2616,2618,2620,2623,2625,2628,2630,2632,2634,2636,2638,2640,2642],{"class":75,"line":2607},66,[73,2609,2610],{"class":283},"                        console",[73,2612,954],{"class":198},[73,2614,2615],{"class":979},"log",[73,2617,983],{"class":202},[73,2619,821],{"class":198},[73,2621,2622],{"class":248},"Error! ",[73,2624,821],{"class":198},[73,2626,2627],{"class":198}," +",[73,2629,2593],{"class":283},[73,2631,2627],{"class":198},[73,2633,815],{"class":198},[73,2635,815],{"class":198},[73,2637,2627],{"class":198},[73,2639,2598],{"class":283},[73,2641,1027],{"class":202},[73,2643,444],{"class":198},[73,2645,2647],{"class":75,"line":2646},67,[73,2648,2649],{"class":198},"                    }\n",[73,2651,2653,2656],{"class":75,"line":2652},68,[73,2654,2655],{"class":198},"                }",[73,2657,1097],{"class":202},[73,2659,2661],{"class":75,"line":2660},69,[73,2662,672],{"class":198},[73,2664,2666],{"class":75,"line":2665},70,[73,2667,2325],{"class":198},[73,2669,2671],{"class":75,"line":2670},71,[73,2672,2213],{"class":198},[73,2674,2676,2679],{"class":75,"line":2675},72,[73,2677,2678],{"class":202},"    created",[73,2680,2170],{"class":198},[73,2682,2684,2687,2689,2691,2693],{"class":75,"line":2683},73,[73,2685,2686],{"class":283},"        $",[73,2688,954],{"class":198},[73,2690,2391],{"class":979},[73,2692,983],{"class":202},[73,2694,1030],{"class":198},[73,2696,2698,2701,2703,2705,2707,2709],{"class":75,"line":2697},74,[73,2699,2700],{"class":202},"            url",[73,2702,842],{"class":198},[73,2704,821],{"class":198},[73,2706,175],{"class":248},[73,2708,821],{"class":198},[73,2710,852],{"class":198},[73,2712,2714,2717,2719,2721,2724,2726],{"class":75,"line":2713},75,[73,2715,2716],{"class":202},"            type",[73,2718,842],{"class":198},[73,2720,821],{"class":198},[73,2722,2723],{"class":248},"GET",[73,2725,821],{"class":198},[73,2727,852],{"class":198},[73,2729,2731,2734,2736,2738,2741,2743,2745],{"class":75,"line":2730},76,[73,2732,2733],{"class":979},"            success",[73,2735,842],{"class":198},[73,2737,2585],{"class":198},[73,2739,2740],{"class":986},"data",[73,2742,1027],{"class":198},[73,2744,2461],{"class":206},[73,2746,834],{"class":198},[73,2748,2750,2752,2754,2756,2759,2761,2764,2766,2768,2770,2773],{"class":75,"line":2749},77,[73,2751,2366],{"class":198},[73,2753,2479],{"class":283},[73,2755,2247],{"class":198},[73,2757,2758],{"class":283}," JSON",[73,2760,954],{"class":198},[73,2762,2763],{"class":979},"parse",[73,2765,983],{"class":202},[73,2767,2740],{"class":283},[73,2769,1027],{"class":202},[73,2771,2772],{"class":198},";",[73,2774,2776],{"class":2775},"sC9rS"," \u002F\u002F returns array\n",[73,2778,2780],{"class":75,"line":2779},78,[73,2781,657],{"class":198},[73,2783,2785,2788,2790,2792,2794,2796,2798,2800,2802,2804,2806],{"class":75,"line":2784},79,[73,2786,2787],{"class":979},"            error",[73,2789,842],{"class":198},[73,2791,2585],{"class":198},[73,2793,2588],{"class":986},[73,2795,990],{"class":198},[73,2797,2593],{"class":986},[73,2799,990],{"class":198},[73,2801,2598],{"class":986},[73,2803,1027],{"class":198},[73,2805,2461],{"class":206},[73,2807,1030],{"class":198},[73,2809,2811,2814,2816,2819,2821,2823,2825,2827,2829,2831,2833,2835,2837,2839,2841,2843],{"class":75,"line":2810},80,[73,2812,2813],{"class":283},"                console",[73,2815,954],{"class":198},[73,2817,2818],{"class":979},"error",[73,2820,983],{"class":202},[73,2822,821],{"class":198},[73,2824,2622],{"class":248},[73,2826,821],{"class":198},[73,2828,2627],{"class":198},[73,2830,2593],{"class":283},[73,2832,2627],{"class":198},[73,2834,815],{"class":198},[73,2836,815],{"class":198},[73,2838,2627],{"class":198},[73,2840,2598],{"class":283},[73,2842,1027],{"class":202},[73,2844,444],{"class":198},[73,2846,2848],{"class":75,"line":2847},81,[73,2849,672],{"class":198},[73,2851,2853,2856],{"class":75,"line":2852},82,[73,2854,2855],{"class":198},"        }",[73,2857,1097],{"class":202},[73,2859,2861],{"class":75,"line":2860},83,[73,2862,134],{"class":198},[73,2864,2866],{"class":75,"line":2865},84,[73,2867,151],{"class":198},[73,2869,2871,2873,2875],{"class":75,"line":2870},85,[73,2872,300],{"class":198},[73,2874,410],{"class":202},[73,2876,210],{"class":198},[11,2878,2879],{},"レンダリングされる際は以下のような処理で一覧画面が表示されます。",[2881,2882,2883,2887,2890],"ol",{},[2884,2885,2886],"li",{},"createdでDB上の情報を取ってくるAjaxをエンドポイントに飛ばす。",[2884,2888,2889],{},"取得したデータをdata()のlistに挿入。",[2884,2891,2892],{},"v-forでlist分 の行を表示する。",[11,2894,2895],{},"これをレンダーすると以下のようになります。",[1187,2897],{":src":2898,":width":1190},"'_mix\u002Fsch-2020-10-04-14.40.28-768x285.png'",[11,2900,2901],{},"右側の「操作」で、「編集」でそのアルバムデータの編集画面へ移動、「削除」ではそのデータを削除するAjaxを飛ばします。また、「新規追加」では新規追加画面へ移動します。この画面があれば一通りのデータ操作がブラウザ画面からできるようになります。",[40,2903,2905],{"id":2904},"ロード用削除用エンドポイントを作成","ロード用・削除用エンドポイントを作成",[11,2907,2908,2910],{},[32,2909,62],{}," コントローラーでは一覧データ・対象のIDを削除するAjaxエンドポイントを作成します。",[48,2912,2914],{"className":66,"code":2913,"filename":68,"language":69,"meta":56,"style":56},"public function view() {\n    $this->render('\u002Fdashboard\u002Fvuetest\u002Fview');\n}\n\n\u002F\u002F ロード用のエンドポイント\npublic function loadData() {\n    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){\n        $db = Database::connection();\n        $db->Execute(\"START TRANSACTION\");\n        $result = $db->fetchAll('SELECT * FROM album ORDER BY ID DESC');\n        $db->Execute(\"COMMIT\");\n        return Core::make('helper\u002Fajax')->sendResult($result);\n    }else{\n        $this->replace('\u002Fpage_not_found');\n    }\n}\n\n\u002F\u002F 削除エンドポイント\npublic function deleteData(){\n    $targetID=$this->post('target');\n    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && !is_null($targetID)){\n        $db = Database::connection();\n        $db->Execute(\"START TRANSACTION\");\n        $db->executeQuery('DELETE FROM album WHERE `ID`=?',array($targetID));\n        $db->Execute(\"COMMIT\");\n    }else{\n        $this->replace('\u002Fpage_not_found');\n    }\n}\n",[32,2915,2916,2921,2926,2930,2934,2939,2944,2949,2953,2957,2961,2965,2969,2973,2978,2982,2986,2990,2995,3000,3005,3010,3014,3018,3023,3027,3031,3035,3039],{"__ignoreMap":56},[73,2917,2918],{"class":75,"line":76},[73,2919,2920],{},"public function view() {\n",[73,2922,2923],{"class":75,"line":82},[73,2924,2925],{},"    $this->render('\u002Fdashboard\u002Fvuetest\u002Fview');\n",[73,2927,2928],{"class":75,"line":88},[73,2929,151],{},[73,2931,2932],{"class":75,"line":95},[73,2933,92],{"emptyLinePlaceholder":91},[73,2935,2936],{"class":75,"line":101},[73,2937,2938],{},"\u002F\u002F ロード用のエンドポイント\n",[73,2940,2941],{"class":75,"line":107},[73,2942,2943],{},"public function loadData() {\n",[73,2945,2946],{"class":75,"line":113},[73,2947,2948],{},"    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'){\n",[73,2950,2951],{"class":75,"line":119},[73,2952,104],{},[73,2954,2955],{"class":75,"line":125},[73,2956,110],{},[73,2958,2959],{"class":75,"line":131},[73,2960,1360],{},[73,2962,2963],{"class":75,"line":137},[73,2964,122],{},[73,2966,2967],{"class":75,"line":142},[73,2968,128],{},[73,2970,2971],{"class":75,"line":148},[73,2972,1474],{},[73,2974,2975],{"class":75,"line":462},[73,2976,2977],{},"        $this->replace('\u002Fpage_not_found');\n",[73,2979,2980],{"class":75,"line":478},[73,2981,134],{},[73,2983,2984],{"class":75,"line":492},[73,2985,151],{},[73,2987,2988],{"class":75,"line":511},[73,2989,92],{"emptyLinePlaceholder":91},[73,2991,2992],{"class":75,"line":530},[73,2993,2994],{},"\u002F\u002F 削除エンドポイント\n",[73,2996,2997],{"class":75,"line":549},[73,2998,2999],{},"public function deleteData(){\n",[73,3001,3002],{"class":75,"line":564},[73,3003,3004],{},"    $targetID=$this->post('target');\n",[73,3006,3007],{"class":75,"line":583},[73,3008,3009],{},"    if ($_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest' && !is_null($targetID)){\n",[73,3011,3012],{"class":75,"line":1413},[73,3013,104],{},[73,3015,3016],{"class":75,"line":1419},[73,3017,110],{},[73,3019,3020],{"class":75,"line":1425},[73,3021,3022],{},"        $db->executeQuery('DELETE FROM album WHERE `ID`=?',array($targetID));\n",[73,3024,3025],{"class":75,"line":1431},[73,3026,122],{},[73,3028,3029],{"class":75,"line":1437},[73,3030,1474],{},[73,3032,3033],{"class":75,"line":1443},[73,3034,2977],{},[73,3036,3037],{"class":75,"line":1449},[73,3038,134],{},[73,3040,3041],{"class":75,"line":1455},[73,3042,151],{},[40,3044,3046],{"id":3045},"エントリーポイント-を作成","エントリーポイント を作成",[11,3048,3049],{},"上記のコンポーネントをレンダリングするために編集・追加の時のように、一覧用ページにレンダーできるように設定をします。",[11,3051,3052,3055],{},[32,3053,3054],{},"packages\u002Fvuetest\u002Fsingle_pages\u002Fdashboard\u002Fvuetest\u002Fview.php"," に以下のようにエントリーポイントを記述します。",[48,3057,3060],{"className":66,"code":3058,"filename":3059,"language":69,"meta":56,"style":56},"\u003C?php\ndefined('C5_EXECUTE') or die('Access Denied.');\n?>\n\n\u003Cdiv id=\"index\">\u003C\u002Fdiv>\n","view.php",[32,3061,3062,3066,3070,3074,3078],{"__ignoreMap":56},[73,3063,3064],{"class":75,"line":76},[73,3065,718],{},[73,3067,3068],{"class":75,"line":82},[73,3069,723],{},[73,3071,3072],{"class":75,"line":88},[73,3073,728],{},[73,3075,3076],{"class":75,"line":95},[73,3077,92],{"emptyLinePlaceholder":91},[73,3079,3080],{"class":75,"line":101},[73,3081,3082],{},"\u003Cdiv id=\"index\">\u003C\u002Fdiv>\n",[11,3084,3085],{},"そしてmain.jsでは",[48,3087,3089],{"className":886,"code":3088,"filename":882,"language":888,"meta":56,"style":56},"import Vue from 'vue'\nimport Index from '.\u002Findex.vue'\nimport Add from '.\u002Fadd.vue'\nimport Edit from '.\u002Fedit.vue'\n\n\nVue.config.productionTip = false\n\nfunction renderIfidExits(id,vueRoot){\n  if(document.getElementById(id) !== null){\n    return new Vue({\n      render: h => h(vueRoot),\n    }).$mount('#'+id)\n  }\n}\n\nrenderIfidExits('index',Index);\nrenderIfidExits('add',Add);\nrenderIfidExits('edit',Edit);\n",[32,3090,3091,3105,3121,3135,3149,3153,3157,3173,3177,3193,3219,3231,3251,3275,3279,3283,3287,3306,3324],{"__ignoreMap":56},[73,3092,3093,3095,3097,3099,3101,3103],{"class":75,"line":76},[73,3094,806],{"class":805},[73,3096,897],{"class":283},[73,3098,812],{"class":805},[73,3100,815],{"class":198},[73,3102,610],{"class":248},[73,3104,906],{"class":198},[73,3106,3107,3109,3112,3114,3116,3119],{"class":75,"line":82},[73,3108,806],{"class":805},[73,3110,3111],{"class":283}," Index ",[73,3113,812],{"class":805},[73,3115,815],{"class":198},[73,3117,3118],{"class":248},".\u002Findex.vue",[73,3120,906],{"class":198},[73,3122,3123,3125,3127,3129,3131,3133],{"class":75,"line":88},[73,3124,806],{"class":805},[73,3126,913],{"class":283},[73,3128,812],{"class":805},[73,3130,815],{"class":198},[73,3132,920],{"class":248},[73,3134,906],{"class":198},[73,3136,3137,3139,3141,3143,3145,3147],{"class":75,"line":95},[73,3138,806],{"class":805},[73,3140,929],{"class":283},[73,3142,812],{"class":805},[73,3144,815],{"class":198},[73,3146,936],{"class":248},[73,3148,906],{"class":198},[73,3150,3151],{"class":75,"line":101},[73,3152,92],{"emptyLinePlaceholder":91},[73,3154,3155],{"class":75,"line":107},[73,3156,92],{"emptyLinePlaceholder":91},[73,3158,3159,3161,3163,3165,3167,3169,3171],{"class":75,"line":113},[73,3160,951],{"class":283},[73,3162,954],{"class":198},[73,3164,957],{"class":283},[73,3166,954],{"class":198},[73,3168,962],{"class":283},[73,3170,242],{"class":198},[73,3172,967],{"class":472},[73,3174,3175],{"class":75,"line":119},[73,3176,92],{"emptyLinePlaceholder":91},[73,3178,3179,3181,3183,3185,3187,3189,3191],{"class":75,"line":125},[73,3180,976],{"class":206},[73,3182,980],{"class":979},[73,3184,983],{"class":198},[73,3186,987],{"class":986},[73,3188,990],{"class":198},[73,3190,993],{"class":986},[73,3192,996],{"class":198},[73,3194,3195,3197,3199,3201,3203,3205,3207,3209,3211,3213,3215,3217],{"class":75,"line":131},[73,3196,1001],{"class":805},[73,3198,983],{"class":202},[73,3200,1006],{"class":283},[73,3202,954],{"class":198},[73,3204,1011],{"class":979},[73,3206,983],{"class":202},[73,3208,987],{"class":283},[73,3210,1018],{"class":202},[73,3212,1021],{"class":198},[73,3214,1024],{"class":198},[73,3216,1027],{"class":202},[73,3218,1030],{"class":198},[73,3220,3221,3223,3225,3227,3229],{"class":75,"line":137},[73,3222,1035],{"class":805},[73,3224,1038],{"class":198},[73,3226,1041],{"class":979},[73,3228,983],{"class":202},[73,3230,1030],{"class":198},[73,3232,3233,3235,3237,3239,3241,3243,3245,3247,3249],{"class":75,"line":142},[73,3234,1050],{"class":979},[73,3236,842],{"class":198},[73,3238,1055],{"class":986},[73,3240,1058],{"class":206},[73,3242,1055],{"class":979},[73,3244,983],{"class":202},[73,3246,993],{"class":283},[73,3248,1027],{"class":202},[73,3250,852],{"class":198},[73,3252,3253,3255,3257,3259,3261,3263,3265,3267,3269,3271,3273],{"class":75,"line":148},[73,3254,1073],{"class":198},[73,3256,1027],{"class":202},[73,3258,954],{"class":198},[73,3260,1080],{"class":979},[73,3262,983],{"class":202},[73,3264,821],{"class":198},[73,3266,1087],{"class":248},[73,3268,821],{"class":198},[73,3270,1092],{"class":198},[73,3272,987],{"class":283},[73,3274,1097],{"class":202},[73,3276,3277],{"class":75,"line":462},[73,3278,1102],{"class":198},[73,3280,3281],{"class":75,"line":478},[73,3282,151],{"class":198},[73,3284,3285],{"class":75,"line":492},[73,3286,92],{"emptyLinePlaceholder":91},[73,3288,3289,3291,3293,3295,3297,3299,3301,3304],{"class":75,"line":511},[73,3290,1115],{"class":979},[73,3292,983],{"class":283},[73,3294,821],{"class":198},[73,3296,2157],{"class":248},[73,3298,821],{"class":198},[73,3300,990],{"class":198},[73,3302,3303],{"class":283},"Index)",[73,3305,444],{"class":198},[73,3307,3308,3310,3312,3314,3316,3318,3320,3322],{"class":75,"line":530},[73,3309,1115],{"class":979},[73,3311,983],{"class":283},[73,3313,821],{"class":198},[73,3315,847],{"class":248},[73,3317,821],{"class":198},[73,3319,990],{"class":198},[73,3321,1128],{"class":283},[73,3323,444],{"class":198},[73,3325,3326,3328,3330,3332,3334,3336,3338,3340],{"class":75,"line":549},[73,3327,1115],{"class":979},[73,3329,983],{"class":283},[73,3331,821],{"class":198},[73,3333,1141],{"class":248},[73,3335,821],{"class":198},[73,3337,990],{"class":198},[73,3339,1148],{"class":283},[73,3341,444],{"class":198},[11,3343,3344,3347],{},[32,3345,3346],{},"id='index'","があれば一覧のコンポーネントが出力されるようにしました。",[24,3349,3350],{"id":3350},"実際に操作してみる",[40,3352,3353],{"id":3353},"新しくデータを入れてみる",[1187,3355],{":src":3356,":width":1190},"'_mix\u002Fsch-2020-10-04-14.40.28-768x285-2.png'",[11,3358,3359],{},"右下の「新規追加」は \u002Fdashboard\u002Fvuetest\u002Fadd へリンクしています。そのためクリックすると追加画面が現れて、追加ができます。新規に「テスト２」としておきましょう。",[1187,3361],{":src":3362,":width":1190},"'_mix\u002Fsch-2020-10-04-15.11.23-768x216.png'",[11,3364,3365],{},"それで「登録」を押すとデータ挿入処理と共に一覧へリダイレクトされます。すると、",[1187,3367],{":src":3368,":width":1190},"'_mix\u002Fsch-2020-10-04-15.12.17-768x313.png'",[11,3370,3371],{},"きちんと一覧に反映されました。",[24,3373,3374],{"id":3374},"削除してみる",[11,3376,3377],{},"では削除を押すと、確認ダイアログがでてOKであれば削除APIが走って実行されます。",[1187,3379],{":src":3380,":width":3381,":center":776},"'_mix\u002Fsch-2020-10-04-15.13.59-768x251.png'","'500px'",[1187,3383],{":src":3384,":width":1190},"'_mix\u002Fsch-2020-10-04-15.22.02.png'",[11,3386,3387],{},"「変更テスト（id 1）」がDB上から削除されまた、一覧からも消えました。",[40,3389,3390],{"id":3390},"編集してみる",[11,3392,3393],{},"緑色の「編集」は編集画面のURLへリンクしています。vueでは以下のようにv-for内で動的に作成できるようにしています。",[48,3395,3397],{"className":608,"code":3396,"language":610,"meta":1525,"style":56},"\u003Ctr v-for=\"val in list\" :key=\"val.id\" tabindex=\"0\">\n...\n    \u003Ctd style=\"vertical-align:middle;\">\n        ...\n        \u003Ca target=\"_blank\" :href=\"'\u002Fdashboard\u002Fvuetest\u002Fedit\u002F'+val.id\">編集\u003C\u002Fa>\n        ...\n    \u003C\u002Ftd>\n...\n\u003C\u002Ftr>\n",[32,3398,3399,3453,3458,3463,3468,3473,3477,3482,3486],{"__ignoreMap":56},[73,3400,3401,3403,3405,3407,3409,3411,3414,3417,3420,3422,3425,3428,3430,3432,3435,3437,3439,3441,3443,3445,3447,3449,3451],{"class":75,"line":76},[73,3402,215],{"class":198},[73,3404,1624],{"class":202},[73,3406,1748],{"class":805},[73,3408,242],{"class":198},[73,3410,245],{"class":198},[73,3412,3413],{"class":283},"val ",[73,3415,3416],{"class":198},"in",[73,3418,3419],{"class":283}," list",[73,3421,245],{"class":198},[73,3423,3424],{"class":198}," :",[73,3426,3427],{"class":206},"key",[73,3429,242],{"class":198},[73,3431,245],{"class":198},[73,3433,3434],{"class":283},"val",[73,3436,954],{"class":198},[73,3438,987],{"class":283},[73,3440,245],{"class":198},[73,3442,1772],{"class":206},[73,3444,242],{"class":198},[73,3446,245],{"class":198},[73,3448,1779],{"class":248},[73,3450,245],{"class":198},[73,3452,210],{"class":198},[73,3454,3455],{"class":75,"line":82},[73,3456,3457],{"class":283},"...\n",[73,3459,3460],{"class":75,"line":88},[73,3461,3462],{"class":283},"    \u003Ctd style=\"vertical-align:middle;\">\n",[73,3464,3465],{"class":75,"line":95},[73,3466,3467],{"class":283},"        ...\n",[73,3469,3470],{"class":75,"line":101},[73,3471,3472],{"class":283},"        \u003Ca target=\"_blank\" :href=\"'\u002Fdashboard\u002Fvuetest\u002Fedit\u002F'+val.id\">編集\u003C\u002Fa>\n",[73,3474,3475],{"class":75,"line":107},[73,3476,3467],{"class":283},[73,3478,3479],{"class":75,"line":113},[73,3480,3481],{"class":283},"    \u003C\u002Ftd>\n",[73,3483,3484],{"class":75,"line":119},[73,3485,3457],{"class":283},[73,3487,3488,3490,3492],{"class":75,"line":125},[73,3489,300],{"class":198},[73,3491,1624],{"class":202},[73,3493,210],{"class":198},[11,3495,3496],{},"実際にリンクしてみると、選択したデータの編集画面が表示されました。",[1187,3498],{":src":3499,":width":3381,":center":776},"'_mix\u002Fsch-2020-10-04-15.29.21-768x342.png'",[24,3501,3503],{"id":3502},"次回は","次回は..",[11,3505,3506],{},"今回の記事では編集画面と一覧画面が完成しました。これで「作成」「読み取り」「更新」「削除」の実装ができました。次の記事では「タイトル」だけでなく「画像データ」「リッチテキスト」といったデータを使えるようにします。",[3508,3509,3510],"style",{},"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 .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 .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}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 .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}html pre.shiki code .sC9rS, html code.shiki .sC9rS{--shiki-default:#464B5D;--shiki-default-font-style:italic}",{"title":56,"searchDepth":88,"depth":88,"links":3512},[3513,3518,3519,3522,3527,3530,3533],{"id":26,"depth":82,"text":27,"children":3514},[3515,3516,3517],{"id":42,"depth":88,"text":43},{"id":597,"depth":88,"text":598},{"id":704,"depth":88,"text":704},{"id":1178,"depth":82,"text":1178},{"id":1305,"depth":82,"text":1305,"children":3520},[3521],{"id":1500,"depth":88,"text":1500},{"id":1512,"depth":82,"text":1512,"children":3523},[3524,3525,3526],{"id":1518,"depth":88,"text":1518},{"id":2904,"depth":88,"text":2905},{"id":3045,"depth":88,"text":3046},{"id":3350,"depth":82,"text":3350,"children":3528},[3529],{"id":3353,"depth":88,"text":3353},{"id":3374,"depth":82,"text":3374,"children":3531},[3532],{"id":3390,"depth":88,"text":3390},{"id":3502,"depth":82,"text":3503},[3535],"devstack","2020-10-04","oncrete5にVueCLIを使ってUIを構築する。編集画面と一覧画面。","md",{},"\u002Fseries\u002Fconcrete5vue-3",{"title":6,"description":3537},"concrete5vue","Concrete5にVueCLIを使ってUIを構築する。","series\u002Fconcrete5vue-3",[3546,3547,610],"concrete5","js","_mix\u002Fvuewithconcrete.png",null,"b60sq7M9Lg8p5F-WfOF_VM7wNdrKWtYXHxXbLU-P1O4",{"id":3552,"title":3553,"body":3554,"category":6020,"createdAt":6021,"description":6022,"extension":3538,"index":82,"meta":6023,"navigation":91,"path":17,"publish":91,"seo":6024,"series":3542,"seriesTitle":3543,"stem":6025,"tag":6026,"thumbnail":3548,"updatedAt":3549,"__hash__":6027},"series\u002Fseries\u002Fconcrete5vue-2.md","Concrete5にVueCLIを使ってUIを構築する。2【コンポーネント作成・データ登録編】",{"type":8,"value":3555,"toc":5999},[3556,3562,3565,3568,3571,3574,3589,3593,3596,3599,3603,3606,3817,3820,3824,3828,3831,3836,3842,3923,3926,3949,3956,3959,3981,3988,3991,3994,4000,4003,4006,4265,4268,4380,4389,4497,4503,4506,4518,4521,4524,4527,4531,4545,4959,4962,4965,5587,5602,5623,5626,5629,5634,5639,5645,5651,5661,5667,5673,5676,5679,5884,5897,5915,5919,5922,5941,5949,5952,5955,5958,5964,5967,5970,5973,5976,5979,5982,5993,5996],[11,3557,13,3558,3561],{},[15,3559,3560],{"href":17},"Concrete5にVueCLIを使ってUIを構築する。1【環境構築編】","の記事の続きを書いていきます。",[11,3563,3564],{},"今回の記事では",[11,3566,3567],{},"どんなフォームを作成するのか。\nテキストインプットを用いたフォームの簡易実装\nデータの保存のバックエンド実装\nを行いたいと思います。ファイルマネージャー、リッチテキストエディタをvueでレンダリングする方法は追加・編集・一覧化が終わった後に書きたいと思います。まずは簡単なフォーム（テキスト）とデータの保存をvueとともに実装していきましょう。",[24,3569,3570],{"id":3570},"最終的に作成するフォーム",[11,3572,3573],{},"「アルバム管理」たるものを作成しようと思います。インスタグラム的な物で、機能は以下の通りです。",[3575,3576,3577,3580,3583,3586],"ul",{},[2884,3578,3579],{},"1つのアルバムに複数枚の画像を自由に登録できる。数は基本的に無制限、最低１枚",[2884,3581,3582],{},"画像と一緒にその画像に関する情報をリッチテキストエディタで編集できる。",[2884,3584,3585],{},"画像は順番の並び替え、追加、削除が可能。",[2884,3587,3588],{},"ページ内ではブロックを通じてアルバムの写真を出力できる。",[40,3590,3592],{"id":3591},"ワイヤーフレーム超簡素","ワイヤーフレーム（超簡素）",[1187,3594],{":src":3595,":width":1190},"'_mix\u002Fvueconcrete2-1.jpeg'",[1187,3597],{":src":3598,":width":1190},"'_mix\u002Fslide-2.jpeg'",[24,3600,3602],{"id":3601},"db構造","DB構造",[11,3604,3605],{},"db.xmlを用いて以下のようなテーブルを作成しておきます。",[48,3607,3612],{"className":3608,"code":3609,"filename":3610,"language":3611,"meta":56,"style":56},"language-xml shiki shiki-themes material-theme-ocean","\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cschema\n  xmlns=\"http:\u002F\u002Fwww.concrete5.org\u002Fdoctrine-xml\u002F0.5\"\n  xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n  xsi:schemaLocation=\"http:\u002F\u002Fwww.concrete5.org\u002Fdoctrine-xml\u002F0.5 http:\u002F\u002Fconcrete5.github.io\u002Fdoctrine-xml\u002Fdoctrine-xml-0.5.xsd\">\n\n\u003Ctable name=\"album\">\n    \u003Cfield name=\"id\" type=\"integer\">\n        \u003Cautoincrement\u002F>\n        \u003Ckey\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"title\" type=\"string\" size=\"255\"\u002F>\n    \u003Cfield name=\"created\" type=\"datetime\">\n      \u003Cdefault value=\"1000-01-01 00:00:00\"\u002F>\n      \u003Cnotnull\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"modified\" type=\"timestamp\">\n      \u003Cdeftimestamp\u002F>\n      \u003Cnotnull\u002F>\n    \u003C\u002Ffield>\n\u003C\u002Ftable>\n\n\u003Ctable name=\"albumPics\">\n    \u003Cfield name=\"id\" type=\"integer\">\n        \u003Cautoincrement\u002F>\n        \u003Ckey\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"albumID\" type=\"integer\">\n        \u003Cunsigned\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"fID\" type=\"integer\">\n        \u003Cunsigned\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"html\" type=\"text\" size=\"65535\"\u002F>\n    \u003Cfield name=\"created\" type=\"datetime\">\n      \u003Cdefault value=\"1000-01-01 00:00:00\"\u002F>\n      \u003Cnotnull\u002F>\n    \u003C\u002Ffield>\n    \u003Cfield name=\"modified\" type=\"timestamp\">\n      \u003Cdeftimestamp\u002F>\n      \u003Cnotnull\u002F>\n    \u003C\u002Ffield>\n\u003C\u002Ftable>\n\n\u003C\u002Fschema>\n","db.xml","xml",[32,3613,3614,3619,3624,3629,3634,3639,3643,3648,3653,3658,3663,3668,3673,3678,3683,3688,3692,3697,3702,3706,3710,3715,3719,3724,3728,3732,3736,3740,3745,3750,3754,3759,3763,3767,3772,3776,3780,3784,3788,3792,3796,3800,3804,3808,3812],{"__ignoreMap":56},[73,3615,3616],{"class":75,"line":76},[73,3617,3618],{},"\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",[73,3620,3621],{"class":75,"line":82},[73,3622,3623],{},"\u003Cschema\n",[73,3625,3626],{"class":75,"line":88},[73,3627,3628],{},"  xmlns=\"http:\u002F\u002Fwww.concrete5.org\u002Fdoctrine-xml\u002F0.5\"\n",[73,3630,3631],{"class":75,"line":95},[73,3632,3633],{},"  xmlns:xsi=\"http:\u002F\u002Fwww.w3.org\u002F2001\u002FXMLSchema-instance\"\n",[73,3635,3636],{"class":75,"line":101},[73,3637,3638],{},"  xsi:schemaLocation=\"http:\u002F\u002Fwww.concrete5.org\u002Fdoctrine-xml\u002F0.5 http:\u002F\u002Fconcrete5.github.io\u002Fdoctrine-xml\u002Fdoctrine-xml-0.5.xsd\">\n",[73,3640,3641],{"class":75,"line":107},[73,3642,92],{"emptyLinePlaceholder":91},[73,3644,3645],{"class":75,"line":113},[73,3646,3647],{},"\u003Ctable name=\"album\">\n",[73,3649,3650],{"class":75,"line":119},[73,3651,3652],{},"    \u003Cfield name=\"id\" type=\"integer\">\n",[73,3654,3655],{"class":75,"line":125},[73,3656,3657],{},"        \u003Cautoincrement\u002F>\n",[73,3659,3660],{"class":75,"line":131},[73,3661,3662],{},"        \u003Ckey\u002F>\n",[73,3664,3665],{"class":75,"line":137},[73,3666,3667],{},"    \u003C\u002Ffield>\n",[73,3669,3670],{"class":75,"line":142},[73,3671,3672],{},"    \u003Cfield name=\"title\" type=\"string\" size=\"255\"\u002F>\n",[73,3674,3675],{"class":75,"line":148},[73,3676,3677],{},"    \u003Cfield name=\"created\" type=\"datetime\">\n",[73,3679,3680],{"class":75,"line":462},[73,3681,3682],{},"      \u003Cdefault value=\"1000-01-01 00:00:00\"\u002F>\n",[73,3684,3685],{"class":75,"line":478},[73,3686,3687],{},"      \u003Cnotnull\u002F>\n",[73,3689,3690],{"class":75,"line":492},[73,3691,3667],{},[73,3693,3694],{"class":75,"line":511},[73,3695,3696],{},"    \u003Cfield name=\"modified\" type=\"timestamp\">\n",[73,3698,3699],{"class":75,"line":530},[73,3700,3701],{},"      \u003Cdeftimestamp\u002F>\n",[73,3703,3704],{"class":75,"line":549},[73,3705,3687],{},[73,3707,3708],{"class":75,"line":564},[73,3709,3667],{},[73,3711,3712],{"class":75,"line":583},[73,3713,3714],{},"\u003C\u002Ftable>\n",[73,3716,3717],{"class":75,"line":1413},[73,3718,92],{"emptyLinePlaceholder":91},[73,3720,3721],{"class":75,"line":1419},[73,3722,3723],{},"\u003Ctable name=\"albumPics\">\n",[73,3725,3726],{"class":75,"line":1425},[73,3727,3652],{},[73,3729,3730],{"class":75,"line":1431},[73,3731,3657],{},[73,3733,3734],{"class":75,"line":1437},[73,3735,3662],{},[73,3737,3738],{"class":75,"line":1443},[73,3739,3667],{},[73,3741,3742],{"class":75,"line":1449},[73,3743,3744],{},"    \u003Cfield name=\"albumID\" type=\"integer\">\n",[73,3746,3747],{"class":75,"line":1455},[73,3748,3749],{},"        \u003Cunsigned\u002F>\n",[73,3751,3752],{"class":75,"line":1460},[73,3753,3667],{},[73,3755,3756],{"class":75,"line":1466},[73,3757,3758],{},"    \u003Cfield name=\"fID\" type=\"integer\">\n",[73,3760,3761],{"class":75,"line":1471},[73,3762,3749],{},[73,3764,3765],{"class":75,"line":1477},[73,3766,3667],{},[73,3768,3769],{"class":75,"line":1483},[73,3770,3771],{},"    \u003Cfield name=\"html\" type=\"text\" size=\"65535\"\u002F>\n",[73,3773,3774],{"class":75,"line":1488},[73,3775,3677],{},[73,3777,3778],{"class":75,"line":2130},[73,3779,3682],{},[73,3781,3782],{"class":75,"line":2139},[73,3783,3687],{},[73,3785,3786],{"class":75,"line":2148},[73,3787,3667],{},[73,3789,3790],{"class":75,"line":2164},[73,3791,3696],{},[73,3793,3794],{"class":75,"line":2173},[73,3795,3701],{},[73,3797,3798],{"class":75,"line":2181},[73,3799,3687],{},[73,3801,3802],{"class":75,"line":2194},[73,3803,3667],{},[73,3805,3806],{"class":75,"line":2205},[73,3807,3714],{},[73,3809,3810],{"class":75,"line":2210},[73,3811,92],{"emptyLinePlaceholder":91},[73,3813,3814],{"class":75,"line":2216},[73,3815,3816],{},"\u003C\u002Fschema>\n",[11,3818,3819],{},"1アルバムに対して不定数の画像が登録されるので上記の様なDBになっています。",[24,3821,3823],{"id":3822},"パッケージのビューphpとvueのsrc構成","パッケージのビューPHPとvueのSrc構成",[40,3825,3827],{"id":3826},"パッケージ側phpの下準備","パッケージ側（PHP）の下準備",[11,3829,3830],{},"それではアルバムののフォームを作っていきましょう。前回インストールした「vuetest」にてフォーム用のシングルページを作成します。",[48,3832,3834],{"className":3833,"code":52,"language":53},[51],[32,3835,52],{"__ignoreMap":56},[11,3837,3838,3839,3841],{},"そしてシングルページのコントローラーである",[32,3840,68],{},"で以下の様に入力",[48,3843,3845],{"className":66,"code":3844,"filename":68,"language":69,"meta":56,"style":56},"class Vuetest extends DashboardPageController\n{\n    public $packageHandle = 'vuetest';\n\n   \u002F\u002Fvuetest のシングルページでvueのjsファイルを読み込む様にする。\n　　public function on_start() {\n        $this->requireAsset('package-vue-production');\n    }\n\n    public function view() {\n    }\n\n    \u002F\u002F \u002Fdashboard\u002Fvuetest\u002F に \u002Fadd というURLを追加できる\n    public function add(){\n        $this->render('\u002Fdashboard\u002Fvuetest\u002Fadd');\n    }\n}\n",[32,3846,3847,3852,3856,3861,3865,3870,3875,3880,3884,3888,3893,3897,3901,3906,3911,3915,3919],{"__ignoreMap":56},[73,3848,3849],{"class":75,"line":76},[73,3850,3851],{},"class Vuetest extends DashboardPageController\n",[73,3853,3854],{"class":75,"line":82},[73,3855,1030],{},[73,3857,3858],{"class":75,"line":88},[73,3859,3860],{},"    public $packageHandle = 'vuetest';\n",[73,3862,3863],{"class":75,"line":95},[73,3864,92],{"emptyLinePlaceholder":91},[73,3866,3867],{"class":75,"line":101},[73,3868,3869],{},"   \u002F\u002Fvuetest のシングルページでvueのjsファイルを読み込む様にする。\n",[73,3871,3872],{"class":75,"line":107},[73,3873,3874],{},"　　public function on_start() {\n",[73,3876,3877],{"class":75,"line":113},[73,3878,3879],{},"        $this->requireAsset('package-vue-production');\n",[73,3881,3882],{"class":75,"line":119},[73,3883,134],{},[73,3885,3886],{"class":75,"line":125},[73,3887,92],{"emptyLinePlaceholder":91},[73,3889,3890],{"class":75,"line":131},[73,3891,3892],{},"    public function view() {\n",[73,3894,3895],{"class":75,"line":137},[73,3896,134],{},[73,3898,3899],{"class":75,"line":142},[73,3900,92],{"emptyLinePlaceholder":91},[73,3902,3903],{"class":75,"line":148},[73,3904,3905],{},"    \u002F\u002F \u002Fdashboard\u002Fvuetest\u002F に \u002Fadd というURLを追加できる\n",[73,3907,3908],{"class":75,"line":462},[73,3909,3910],{},"    public function add(){\n",[73,3912,3913],{"class":75,"line":478},[73,3914,1480],{},[73,3916,3917],{"class":75,"line":492},[73,3918,134],{},[73,3920,3921],{"class":75,"line":511},[73,3922,151],{},[11,3924,3925],{},"すると\u002Fdashboard\u002Fvuetest\u002Fadd というURLを叩くとadd.phpが表示されます。",[48,3927,3930],{"className":66,"code":3928,"filename":3929,"language":69,"meta":56,"style":56},"\u003C?php\ndefined('C5_EXECUTE') or die('Access Denied.');\n?>\n\u003Cp>add用のページだよ\u003C\u002Fp>\n","add.php",[32,3931,3932,3936,3940,3944],{"__ignoreMap":56},[73,3933,3934],{"class":75,"line":76},[73,3935,718],{},[73,3937,3938],{"class":75,"line":82},[73,3939,723],{},[73,3941,3942],{"class":75,"line":88},[73,3943,728],{},[73,3945,3946],{"class":75,"line":95},[73,3947,3948],{},"\u003Cp>add用のページだよ\u003C\u002Fp>\n",[11,3950,3951,3952],{},"↓\n",[1187,3953],{":src":3954,":width":3955,":center":776},"'_mix\u002Fscsh-2020-08-26-21.34.56-768x436.png'","'600px'",[11,3957,3958],{},"ページの表示が確認できたら、add.phpに以下の様に変更しておきます。",[48,3960,3962],{"className":66,"code":3961,"filename":3929,"language":69,"meta":56,"style":56},"\u003C?php\ndefined('C5_EXECUTE') or die('Access Denied.');\n?>\n\u003Cdiv id=\"add\">\u003C\u002Fdiv>\n",[32,3963,3964,3968,3972,3976],{"__ignoreMap":56},[73,3965,3966],{"class":75,"line":76},[73,3967,718],{},[73,3969,3970],{"class":75,"line":82},[73,3971,723],{},[73,3973,3974],{"class":75,"line":88},[73,3975,728],{},[73,3977,3978],{"class":75,"line":95},[73,3979,3980],{},"\u003Cdiv id=\"add\">\u003C\u002Fdiv>\n",[11,3982,3983,3984,3987],{},"この",[32,3985,3986],{},"\u003Cdiv id=”app>\u003C\u002Fdiv>","としたところがvueコンポーネントを流し込むエントリーになります。フォームのビューファイルであるadd.phpはこれだけでおしまいです。",[24,3989,3990],{"id":3990},"vue側の準備",[11,3992,3993],{},"ではvue側も作っていきましょう。src配下は以下の様に構成します。",[48,3995,3998],{"className":3996,"code":3997,"language":53},[51],"├── src\n   ├── add.vue\n   ├── components\n   │   └── form.vue\n   ├── edit.vue\n   ├── index.vue\n   └── main.js\n",[32,3999,3997],{"__ignoreMap":56},[11,4001,4002],{},"index.vue、add.vue、edit.vueそれぞれが一覧・追加・編集ページのUIを構築します。しかしedit.vueとadd.vueは入力項目が同じで、初期値があるかないかの違いだけです。そのため共通のコンポーネントform.vueを作成します。",[11,4004,4005],{},"form.vueはひとまず以下の様に設定しておきます。",[48,4007,4009],{"className":608,"code":4008,"filename":604,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003Cdiv class=\"ccm-dashboard-content-inner\">\n        \u003Cp>vueレンダリングテスト\u003C\u002Fp>\n        \n        \u003Cdiv class=\"ccm-dashboard-form-actions-wrapper\">\n            \u003Cdiv class=\"ccm-dashboard-form-actions\">\n                \u003Cbutton class=\"pull-left btn btn-primary\">\n                    一覧へ戻る\n                \u003C\u002Fbutton>\n                \u003Ca href=\"#\" class=\"pull-right btn btn-primary\">\n                    登録\n                \u003C\u002Fa>\n            \u003C\u002Fdiv>\n        \u003C\u002Fdiv>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n    name:'albumForm',\n    props:['isEdit']\n}\n\u003C\u002Fscript>\n",[32,4010,4011,4019,4037,4054,4059,4077,4095,4114,4119,4127,4155,4160,4168,4176,4184,4192,4200,4204,4212,4220,4235,4253,4257],{"__ignoreMap":56},[73,4012,4013,4015,4017],{"class":75,"line":76},[73,4014,215],{"class":198},[73,4016,757],{"class":202},[73,4018,210],{"class":198},[73,4020,4021,4023,4025,4027,4029,4031,4033,4035],{"class":75,"line":82},[73,4022,233],{"class":198},[73,4024,178],{"class":202},[73,4026,1544],{"class":206},[73,4028,242],{"class":198},[73,4030,245],{"class":198},[73,4032,1551],{"class":248},[73,4034,245],{"class":198},[73,4036,210],{"class":198},[73,4038,4039,4041,4043,4045,4048,4050,4052],{"class":75,"line":88},[73,4040,1560],{"class":198},[73,4042,11],{"class":202},[73,4044,294],{"class":198},[73,4046,4047],{"class":283},"vueレンダリングテスト",[73,4049,300],{"class":198},[73,4051,11],{"class":202},[73,4053,210],{"class":198},[73,4055,4056],{"class":75,"line":95},[73,4057,4058],{"class":283},"        \n",[73,4060,4061,4063,4065,4067,4069,4071,4073,4075],{"class":75,"line":101},[73,4062,1560],{"class":198},[73,4064,178],{"class":202},[73,4066,1544],{"class":206},[73,4068,242],{"class":198},[73,4070,245],{"class":198},[73,4072,2024],{"class":248},[73,4074,245],{"class":198},[73,4076,210],{"class":198},[73,4078,4079,4081,4083,4085,4087,4089,4091,4093],{"class":75,"line":107},[73,4080,1611],{"class":198},[73,4082,178],{"class":202},[73,4084,1544],{"class":206},[73,4086,242],{"class":198},[73,4088,245],{"class":198},[73,4090,2043],{"class":248},[73,4092,245],{"class":198},[73,4094,210],{"class":198},[73,4096,4097,4099,4101,4103,4105,4107,4110,4112],{"class":75,"line":113},[73,4098,1621],{"class":198},[73,4100,1886],{"class":202},[73,4102,1544],{"class":206},[73,4104,242],{"class":198},[73,4106,245],{"class":198},[73,4108,4109],{"class":248},"pull-left btn btn-primary",[73,4111,245],{"class":198},[73,4113,210],{"class":198},[73,4115,4116],{"class":75,"line":119},[73,4117,4118],{"class":283},"                    一覧へ戻る\n",[73,4120,4121,4123,4125],{"class":75,"line":125},[73,4122,1717],{"class":198},[73,4124,1886],{"class":202},[73,4126,210],{"class":198},[73,4128,4129,4131,4133,4135,4137,4139,4141,4143,4145,4147,4149,4151,4153],{"class":75,"line":131},[73,4130,1621],{"class":198},[73,4132,15],{"class":202},[73,4134,266],{"class":206},[73,4136,242],{"class":198},[73,4138,245],{"class":198},[73,4140,1087],{"class":248},[73,4142,245],{"class":198},[73,4144,1544],{"class":206},[73,4146,242],{"class":198},[73,4148,245],{"class":198},[73,4150,2073],{"class":248},[73,4152,245],{"class":198},[73,4154,210],{"class":198},[73,4156,4157],{"class":75,"line":137},[73,4158,4159],{"class":283},"                    登録\n",[73,4161,4162,4164,4166],{"class":75,"line":142},[73,4163,1717],{"class":198},[73,4165,15],{"class":202},[73,4167,210],{"class":198},[73,4169,4170,4172,4174],{"class":75,"line":148},[73,4171,1726],{"class":198},[73,4173,178],{"class":202},[73,4175,210],{"class":198},[73,4177,4178,4180,4182],{"class":75,"line":462},[73,4179,2001],{"class":198},[73,4181,178],{"class":202},[73,4183,210],{"class":198},[73,4185,4186,4188,4190],{"class":75,"line":478},[73,4187,2111],{"class":198},[73,4189,178],{"class":202},[73,4191,210],{"class":198},[73,4193,4194,4196,4198],{"class":75,"line":492},[73,4195,300],{"class":198},[73,4197,757],{"class":202},[73,4199,210],{"class":198},[73,4201,4202],{"class":75,"line":511},[73,4203,92],{"emptyLinePlaceholder":91},[73,4205,4206,4208,4210],{"class":75,"line":530},[73,4207,215],{"class":198},[73,4209,410],{"class":202},[73,4211,210],{"class":198},[73,4213,4214,4216,4218],{"class":75,"line":549},[73,4215,828],{"class":805},[73,4217,831],{"class":805},[73,4219,834],{"class":198},[73,4221,4222,4224,4226,4228,4231,4233],{"class":75,"line":564},[73,4223,839],{"class":202},[73,4225,842],{"class":198},[73,4227,821],{"class":198},[73,4229,4230],{"class":248},"albumForm",[73,4232,821],{"class":198},[73,4234,852],{"class":198},[73,4236,4237,4240,4242,4245,4247,4249,4251],{"class":75,"line":583},[73,4238,4239],{"class":202},"    props",[73,4241,842],{"class":198},[73,4243,4244],{"class":283},"[",[73,4246,821],{"class":198},[73,4248,693],{"class":248},[73,4250,821],{"class":198},[73,4252,1299],{"class":283},[73,4254,4255],{"class":75,"line":1413},[73,4256,151],{"class":198},[73,4258,4259,4261,4263],{"class":75,"line":1419},[73,4260,300],{"class":198},[73,4262,410],{"class":202},[73,4264,210],{"class":198},[11,4266,4267],{},"そしてadd.vueでこのform.vueを読み込んで",[48,4269,4272],{"className":608,"code":4270,"filename":4271,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003CAlbumForm :isEdit=\"false\"\u002F>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nimport AlbumForm from '.\u002Fcomponents\u002Fform';\nexport default {\n    name:'add',\n    components:{AlbumForm}\n}\n\u003C\u002Fscript>\n","app.vue",[32,4273,4274,4282,4300,4308,4312,4320,4336,4344,4358,4368,4372],{"__ignoreMap":56},[73,4275,4276,4278,4280],{"class":75,"line":76},[73,4277,215],{"class":198},[73,4279,757],{"class":202},[73,4281,210],{"class":198},[73,4283,4284,4286,4288,4290,4292,4294,4296,4298],{"class":75,"line":82},[73,4285,233],{"class":198},[73,4287,766],{"class":202},[73,4289,769],{"class":206},[73,4291,242],{"class":198},[73,4293,245],{"class":198},[73,4295,2356],{"class":248},[73,4297,245],{"class":198},[73,4299,342],{"class":198},[73,4301,4302,4304,4306],{"class":75,"line":88},[73,4303,300],{"class":198},[73,4305,757],{"class":202},[73,4307,210],{"class":198},[73,4309,4310],{"class":75,"line":95},[73,4311,92],{"emptyLinePlaceholder":91},[73,4313,4314,4316,4318],{"class":75,"line":101},[73,4315,215],{"class":198},[73,4317,410],{"class":202},[73,4319,210],{"class":198},[73,4321,4322,4324,4326,4328,4330,4332,4334],{"class":75,"line":107},[73,4323,806],{"class":805},[73,4325,809],{"class":283},[73,4327,812],{"class":805},[73,4329,815],{"class":198},[73,4331,818],{"class":248},[73,4333,821],{"class":198},[73,4335,444],{"class":198},[73,4337,4338,4340,4342],{"class":75,"line":113},[73,4339,828],{"class":805},[73,4341,831],{"class":805},[73,4343,834],{"class":198},[73,4345,4346,4348,4350,4352,4354,4356],{"class":75,"line":119},[73,4347,839],{"class":202},[73,4349,842],{"class":198},[73,4351,821],{"class":198},[73,4353,847],{"class":248},[73,4355,821],{"class":198},[73,4357,852],{"class":198},[73,4359,4360,4362,4364,4366],{"class":75,"line":125},[73,4361,857],{"class":202},[73,4363,860],{"class":198},[73,4365,766],{"class":283},[73,4367,151],{"class":198},[73,4369,4370],{"class":75,"line":131},[73,4371,151],{"class":198},[73,4373,4374,4376,4378],{"class":75,"line":137},[73,4375,300],{"class":198},[73,4377,410],{"class":202},[73,4379,210],{"class":198},[11,4381,4382,4384,4385,4388],{},[32,4383,882],{},"にて",[32,4386,4387],{},"id=\"app\"","の要素にマウントする様にします。",[48,4390,4392],{"className":886,"code":4391,"filename":882,"language":888,"meta":56,"style":56},"import Vue from 'vue'\nimport Add from '.\u002Fadd.vue'\n\nVue.config.productionTip = false\n\nnew Vue({\n  render: h => h(Add),\n}).$mount('#add')\n",[32,4393,4394,4408,4422,4426,4442,4446,4457,4475],{"__ignoreMap":56},[73,4395,4396,4398,4400,4402,4404,4406],{"class":75,"line":76},[73,4397,806],{"class":805},[73,4399,897],{"class":283},[73,4401,812],{"class":805},[73,4403,815],{"class":198},[73,4405,610],{"class":248},[73,4407,906],{"class":198},[73,4409,4410,4412,4414,4416,4418,4420],{"class":75,"line":82},[73,4411,806],{"class":805},[73,4413,913],{"class":283},[73,4415,812],{"class":805},[73,4417,815],{"class":198},[73,4419,920],{"class":248},[73,4421,906],{"class":198},[73,4423,4424],{"class":75,"line":88},[73,4425,92],{"emptyLinePlaceholder":91},[73,4427,4428,4430,4432,4434,4436,4438,4440],{"class":75,"line":95},[73,4429,951],{"class":283},[73,4431,954],{"class":198},[73,4433,957],{"class":283},[73,4435,954],{"class":198},[73,4437,962],{"class":283},[73,4439,242],{"class":198},[73,4441,967],{"class":472},[73,4443,4444],{"class":75,"line":101},[73,4445,92],{"emptyLinePlaceholder":91},[73,4447,4448,4451,4453,4455],{"class":75,"line":107},[73,4449,4450],{"class":198},"new",[73,4452,1041],{"class":979},[73,4454,983],{"class":283},[73,4456,1030],{"class":198},[73,4458,4459,4462,4464,4466,4468,4470,4473],{"class":75,"line":113},[73,4460,4461],{"class":979},"  render",[73,4463,842],{"class":198},[73,4465,1055],{"class":986},[73,4467,1058],{"class":206},[73,4469,1055],{"class":979},[73,4471,4472],{"class":283},"(Add)",[73,4474,852],{"class":198},[73,4476,4477,4480,4482,4484,4486,4488,4490,4493,4495],{"class":75,"line":119},[73,4478,4479],{"class":198},"}",[73,4481,1027],{"class":283},[73,4483,954],{"class":198},[73,4485,1080],{"class":979},[73,4487,983],{"class":283},[73,4489,821],{"class":198},[73,4491,4492],{"class":248},"#add",[73,4494,821],{"class":198},[73,4496,1097],{"class":283},[11,4498,4499,4500,4502],{},"こうしてビルドをしてみましょう。そして",[32,4501,2062],{},"へ移動してみると",[1187,4504],{":src":4505,":width":1190},"'_mix\u002Fsch-2020-08-26-22.48.54-768x529.png'",[11,4507,4508,4509,4511,4512,4514,4515,4517],{},"しっかりと",[32,4510,4387],{},"に",[32,4513,604],{},"がレンダリングされました。ではこの",[32,4516,604],{},"にガシガシとフォームUIを作っていきましょう！",[24,4519,4520],{"id":4520},"まずはタイトルを入力するだけのものを作成",[11,4522,4523],{},"最終的なフォームにはリッチテキストエディタとファイルセレクターなど、concrete5で用いられているフォームをvueで実装したいと思います。しかし、その２つはなかなか曲者で今回の記事で説明すると長くなるので次回に話します。",[11,4525,4526],{},"まずはvueとPHP(concrete5)でどう連携させてDBにデータを挿入するかの全体的な流れについて説明するとともに、タイトル部分（プレーンテキスト）を追加できる様にしていきましょう。",[40,4528,4530],{"id":4529},"postでバックに値を送る","POSTでバックに値を送る",[11,4532,4533,4534,4537,4538,4541,4542,4544],{},"vueで構築したUIで入力された値はどうやってバックに渡すか？簡単です。フォームを作る時の様に",[32,4535,4536],{},"input","を",[32,4539,4540],{},"\u003Cform method=\"post\">\u003C\u002Fform>","で囲んであげて、送信用のsubmitボタンを作るだけです。今回のパッケージではPOSTの値をAjaxとかで送るのでなく、普通にsubmitでサーバーに送信する様にしました。以下の様に",[32,4543,604],{},"を変えます。",[48,4546,4548],{"className":608,"code":4547,"filename":604,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003Cdiv class=\"ccm-dashboard-content-inner\">\n        \u003Ch3>アルバム新規追加\u003C\u002Fh3>\n        \u003Chr>\n        \u003Cform method=\"post\">\n            \u003Clabel for=\"title\" class=\"control-label\">アルバムタイトル\u003C\u002Flabel>\n            \u003Cinput type=\"text\" name=\"title\" class=\"form-control ccm-input-text\" v-model=\"title\">\n\n            \u003Cdiv class=\"ccm-dashboard-form-actions-wrapper\">\n                \u003Cdiv class=\"ccm-dashboard-form-actions\">\n                    \u003Cbutton class=\"pull-left btn btn-primary\">\n                        一覧へ戻る\n                    \u003C\u002Fbutton>\n                    \u003Cinput value=\"登録\" type=\"submit\" class=\"pull-right btn btn-primary\">\n                \u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n        \u003C\u002Fform>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\n\u003Cscript>\nexport default {\n    name:'albumForm',\n    props:['isEdit'],\n    data(){\n        return{\n            title:''\n        }\n    }\n}\n\u003C\u002Fscript>\n",[32,4549,4550,4558,4576,4593,4601,4622,4662,4712,4716,4734,4752,4770,4775,4783,4824,4832,4840,4848,4856,4864,4868,4876,4884,4898,4917,4923,4929,4939,4943,4947,4951],{"__ignoreMap":56},[73,4551,4552,4554,4556],{"class":75,"line":76},[73,4553,215],{"class":198},[73,4555,757],{"class":202},[73,4557,210],{"class":198},[73,4559,4560,4562,4564,4566,4568,4570,4572,4574],{"class":75,"line":82},[73,4561,233],{"class":198},[73,4563,178],{"class":202},[73,4565,1544],{"class":206},[73,4567,242],{"class":198},[73,4569,245],{"class":198},[73,4571,1551],{"class":248},[73,4573,245],{"class":198},[73,4575,210],{"class":198},[73,4577,4578,4580,4582,4584,4587,4589,4591],{"class":75,"line":88},[73,4579,1560],{"class":198},[73,4581,40],{"class":202},[73,4583,294],{"class":198},[73,4585,4586],{"class":283},"アルバム新規追加",[73,4588,300],{"class":198},[73,4590,40],{"class":202},[73,4592,210],{"class":198},[73,4594,4595,4597,4599],{"class":75,"line":95},[73,4596,1560],{"class":198},[73,4598,1580],{"class":202},[73,4600,210],{"class":198},[73,4602,4603,4605,4608,4611,4613,4615,4618,4620],{"class":75,"line":101},[73,4604,1560],{"class":198},[73,4606,4607],{"class":202},"form",[73,4609,4610],{"class":206}," method",[73,4612,242],{"class":198},[73,4614,245],{"class":198},[73,4616,4617],{"class":248},"post",[73,4619,245],{"class":198},[73,4621,210],{"class":198},[73,4623,4624,4626,4629,4632,4634,4636,4638,4640,4642,4644,4646,4649,4651,4653,4656,4658,4660],{"class":75,"line":107},[73,4625,1611],{"class":198},[73,4627,4628],{"class":202},"label",[73,4630,4631],{"class":206}," for",[73,4633,242],{"class":198},[73,4635,245],{"class":198},[73,4637,291],{"class":248},[73,4639,245],{"class":198},[73,4641,1544],{"class":206},[73,4643,242],{"class":198},[73,4645,245],{"class":198},[73,4647,4648],{"class":248},"control-label",[73,4650,245],{"class":198},[73,4652,294],{"class":198},[73,4654,4655],{"class":283},"アルバムタイトル",[73,4657,300],{"class":198},[73,4659,4628],{"class":202},[73,4661,210],{"class":198},[73,4663,4664,4666,4668,4670,4672,4674,4676,4678,4680,4682,4684,4686,4688,4690,4692,4694,4697,4699,4702,4704,4706,4708,4710],{"class":75,"line":113},[73,4665,1611],{"class":198},[73,4667,4536],{"class":202},[73,4669,254],{"class":206},[73,4671,242],{"class":198},[73,4673,245],{"class":198},[73,4675,53],{"class":248},[73,4677,245],{"class":198},[73,4679,351],{"class":206},[73,4681,242],{"class":198},[73,4683,245],{"class":198},[73,4685,291],{"class":248},[73,4687,245],{"class":198},[73,4689,1544],{"class":206},[73,4691,242],{"class":198},[73,4693,245],{"class":198},[73,4695,4696],{"class":248},"form-control ccm-input-text",[73,4698,245],{"class":198},[73,4700,4701],{"class":206}," v-model",[73,4703,242],{"class":198},[73,4705,245],{"class":198},[73,4707,291],{"class":248},[73,4709,245],{"class":198},[73,4711,210],{"class":198},[73,4713,4714],{"class":75,"line":119},[73,4715,92],{"emptyLinePlaceholder":91},[73,4717,4718,4720,4722,4724,4726,4728,4730,4732],{"class":75,"line":125},[73,4719,1611],{"class":198},[73,4721,178],{"class":202},[73,4723,1544],{"class":206},[73,4725,242],{"class":198},[73,4727,245],{"class":198},[73,4729,2024],{"class":248},[73,4731,245],{"class":198},[73,4733,210],{"class":198},[73,4735,4736,4738,4740,4742,4744,4746,4748,4750],{"class":75,"line":131},[73,4737,1621],{"class":198},[73,4739,178],{"class":202},[73,4741,1544],{"class":206},[73,4743,242],{"class":198},[73,4745,245],{"class":198},[73,4747,2043],{"class":248},[73,4749,245],{"class":198},[73,4751,210],{"class":198},[73,4753,4754,4756,4758,4760,4762,4764,4766,4768],{"class":75,"line":137},[73,4755,1631],{"class":198},[73,4757,1886],{"class":202},[73,4759,1544],{"class":206},[73,4761,242],{"class":198},[73,4763,245],{"class":198},[73,4765,4109],{"class":248},[73,4767,245],{"class":198},[73,4769,210],{"class":198},[73,4771,4772],{"class":75,"line":142},[73,4773,4774],{"class":283},"                        一覧へ戻る\n",[73,4776,4777,4779,4781],{"class":75,"line":148},[73,4778,1976],{"class":198},[73,4780,1886],{"class":202},[73,4782,210],{"class":198},[73,4784,4785,4787,4789,4792,4794,4796,4799,4801,4803,4805,4807,4810,4812,4814,4816,4818,4820,4822],{"class":75,"line":462},[73,4786,1631],{"class":198},[73,4788,4536],{"class":202},[73,4790,4791],{"class":206}," value",[73,4793,242],{"class":198},[73,4795,245],{"class":198},[73,4797,4798],{"class":248},"登録",[73,4800,245],{"class":198},[73,4802,254],{"class":206},[73,4804,242],{"class":198},[73,4806,245],{"class":198},[73,4808,4809],{"class":248},"submit",[73,4811,245],{"class":198},[73,4813,1544],{"class":206},[73,4815,242],{"class":198},[73,4817,245],{"class":198},[73,4819,2073],{"class":248},[73,4821,245],{"class":198},[73,4823,210],{"class":198},[73,4825,4826,4828,4830],{"class":75,"line":478},[73,4827,1717],{"class":198},[73,4829,178],{"class":202},[73,4831,210],{"class":198},[73,4833,4834,4836,4838],{"class":75,"line":492},[73,4835,1726],{"class":198},[73,4837,178],{"class":202},[73,4839,210],{"class":198},[73,4841,4842,4844,4846],{"class":75,"line":511},[73,4843,2001],{"class":198},[73,4845,4607],{"class":202},[73,4847,210],{"class":198},[73,4849,4850,4852,4854],{"class":75,"line":530},[73,4851,2111],{"class":198},[73,4853,178],{"class":202},[73,4855,210],{"class":198},[73,4857,4858,4860,4862],{"class":75,"line":549},[73,4859,300],{"class":198},[73,4861,757],{"class":202},[73,4863,210],{"class":198},[73,4865,4866],{"class":75,"line":564},[73,4867,92],{"emptyLinePlaceholder":91},[73,4869,4870,4872,4874],{"class":75,"line":583},[73,4871,215],{"class":198},[73,4873,410],{"class":202},[73,4875,210],{"class":198},[73,4877,4878,4880,4882],{"class":75,"line":1413},[73,4879,828],{"class":805},[73,4881,831],{"class":805},[73,4883,834],{"class":198},[73,4885,4886,4888,4890,4892,4894,4896],{"class":75,"line":1419},[73,4887,839],{"class":202},[73,4889,842],{"class":198},[73,4891,821],{"class":198},[73,4893,4230],{"class":248},[73,4895,821],{"class":198},[73,4897,852],{"class":198},[73,4899,4900,4902,4904,4906,4908,4910,4912,4915],{"class":75,"line":1425},[73,4901,4239],{"class":202},[73,4903,842],{"class":198},[73,4905,4244],{"class":283},[73,4907,821],{"class":198},[73,4909,693],{"class":248},[73,4911,821],{"class":198},[73,4913,4914],{"class":283},"]",[73,4916,852],{"class":198},[73,4918,4919,4921],{"class":75,"line":1431},[73,4920,2167],{"class":202},[73,4922,2170],{"class":198},[73,4924,4925,4927],{"class":75,"line":1437},[73,4926,2176],{"class":805},[73,4928,1030],{"class":198},[73,4930,4931,4934,4936],{"class":75,"line":1443},[73,4932,4933],{"class":202},"            title",[73,4935,842],{"class":198},[73,4937,4938],{"class":198},"''\n",[73,4940,4941],{"class":75,"line":1449},[73,4942,1463],{"class":198},[73,4944,4945],{"class":75,"line":1455},[73,4946,134],{"class":198},[73,4948,4949],{"class":75,"line":1460},[73,4950,151],{"class":198},[73,4952,4953,4955,4957],{"class":75,"line":1466},[73,4954,300],{"class":198},[73,4956,410],{"class":202},[73,4958,210],{"class":198},[40,4960,4961],{"id":4961},"フロントバリデーションを実装",[11,4963,4964],{},"フォームから入力された値をバリデーションチェックします。しかし今回はせっかくvueを使っているのでフロントでバリデーションをしてあげましょう。例えばtitleが空でないかをチェックする場合以下の様にします。",[48,4966,4968],{"className":608,"code":4967,"filename":604,"language":610,"meta":56,"style":56},"\u003Ctemplate>\n    \u003Cdiv class=\"ccm-dashboard-content-inner\">\n        \u003Ch3>アルバム新規追加\u003C\u002Fh3>\n        \u003Chr>\n        \u003Cform method=\"post\" @submit=\"checkForm\">\n            \u003Clabel for=\"title\" class=\"control-label\">アルバムタイトル\u003C\u002Flabel>\n            \u003Cinput type=\"text\" name=\"title\" class=\"form-control ccm-input-text\" v-model=\"title\">\n            \u003Cp class=\"text-danger\" v-if=\"errTitle.length>0\">{{errTitle}}\u003C\u002Fp>\n\n            \u003Cdiv class=\"ccm-dashboard-form-actions-wrapper\">\n                \u003Cdiv class=\"ccm-dashboard-form-actions\">\n                    \u003Cbutton class=\"pull-left btn btn-primary\">\n                        一覧へ戻る\n                    \u003C\u002Fbutton>\n                    \u003Cinput value=\"登録\" type=\"submit\" class=\"pull-right btn btn-primary\">\n                \u003C\u002Fdiv>\n            \u003C\u002Fdiv>\n        \u003C\u002Fform>\n    \u003C\u002Fdiv>\n\u003C\u002Ftemplate>\n\u003Cscript>\nexport default {\n    name:'albumForm',\n    props:['isEdit'],\n    data(){\n        return{\n            title:'',\n            errTitle:''\n        }\n    },\n    methods:{\n        checkForm($event){\n            if(this.title.length >0){\n                return true;\n            }else{\n                $event.preventDefault();\n                ConcreteAlert.error({\n                    title:'入力項目に誤りがあります。',\n                    message:'アルバムタイトルが入力されていません。',\n                    delay:5000\n                })\n                this.errTitle = \"タイトルを入力してください。\"\n            }\n        }\n    }\n}\n\u003C\u002Fscript>\n",[32,4969,4970,4978,4996,5012,5020,5050,5086,5134,5174,5178,5196,5214,5232,5236,5244,5282,5290,5298,5306,5314,5322,5330,5338,5352,5370,5376,5382,5393,5402,5406,5410,5416,5428,5452,5461,5471,5486,5499,5515,5531,5541,5547,5563,5567,5571,5575,5579],{"__ignoreMap":56},[73,4971,4972,4974,4976],{"class":75,"line":76},[73,4973,215],{"class":198},[73,4975,757],{"class":202},[73,4977,210],{"class":198},[73,4979,4980,4982,4984,4986,4988,4990,4992,4994],{"class":75,"line":82},[73,4981,233],{"class":198},[73,4983,178],{"class":202},[73,4985,1544],{"class":206},[73,4987,242],{"class":198},[73,4989,245],{"class":198},[73,4991,1551],{"class":248},[73,4993,245],{"class":198},[73,4995,210],{"class":198},[73,4997,4998,5000,5002,5004,5006,5008,5010],{"class":75,"line":88},[73,4999,1560],{"class":198},[73,5001,40],{"class":202},[73,5003,294],{"class":198},[73,5005,4586],{"class":283},[73,5007,300],{"class":198},[73,5009,40],{"class":202},[73,5011,210],{"class":198},[73,5013,5014,5016,5018],{"class":75,"line":95},[73,5015,1560],{"class":198},[73,5017,1580],{"class":202},[73,5019,210],{"class":198},[73,5021,5022,5024,5026,5028,5030,5032,5034,5036,5039,5041,5043,5046,5048],{"class":75,"line":101},[73,5023,1560],{"class":198},[73,5025,4607],{"class":202},[73,5027,4610],{"class":206},[73,5029,242],{"class":198},[73,5031,245],{"class":198},[73,5033,4617],{"class":248},[73,5035,245],{"class":198},[73,5037,5038],{"class":206}," @submit",[73,5040,242],{"class":198},[73,5042,245],{"class":198},[73,5044,5045],{"class":248},"checkForm",[73,5047,245],{"class":198},[73,5049,210],{"class":198},[73,5051,5052,5054,5056,5058,5060,5062,5064,5066,5068,5070,5072,5074,5076,5078,5080,5082,5084],{"class":75,"line":107},[73,5053,1611],{"class":198},[73,5055,4628],{"class":202},[73,5057,4631],{"class":206},[73,5059,242],{"class":198},[73,5061,245],{"class":198},[73,5063,291],{"class":248},[73,5065,245],{"class":198},[73,5067,1544],{"class":206},[73,5069,242],{"class":198},[73,5071,245],{"class":198},[73,5073,4648],{"class":248},[73,5075,245],{"class":198},[73,5077,294],{"class":198},[73,5079,4655],{"class":283},[73,5081,300],{"class":198},[73,5083,4628],{"class":202},[73,5085,210],{"class":198},[73,5087,5088,5090,5092,5094,5096,5098,5100,5102,5104,5106,5108,5110,5112,5114,5116,5118,5120,5122,5124,5126,5128,5130,5132],{"class":75,"line":113},[73,5089,1611],{"class":198},[73,5091,4536],{"class":202},[73,5093,254],{"class":206},[73,5095,242],{"class":198},[73,5097,245],{"class":198},[73,5099,53],{"class":248},[73,5101,245],{"class":198},[73,5103,351],{"class":206},[73,5105,242],{"class":198},[73,5107,245],{"class":198},[73,5109,291],{"class":248},[73,5111,245],{"class":198},[73,5113,1544],{"class":206},[73,5115,242],{"class":198},[73,5117,245],{"class":198},[73,5119,4696],{"class":248},[73,5121,245],{"class":198},[73,5123,4701],{"class":206},[73,5125,242],{"class":198},[73,5127,245],{"class":198},[73,5129,291],{"class":248},[73,5131,245],{"class":198},[73,5133,210],{"class":198},[73,5135,5136,5138,5140,5142,5144,5146,5149,5151,5154,5156,5158,5161,5163,5165,5168,5170,5172],{"class":75,"line":119},[73,5137,1611],{"class":198},[73,5139,11],{"class":202},[73,5141,1544],{"class":206},[73,5143,242],{"class":198},[73,5145,245],{"class":198},[73,5147,5148],{"class":248},"text-danger",[73,5150,245],{"class":198},[73,5152,5153],{"class":206}," v-if",[73,5155,242],{"class":198},[73,5157,245],{"class":198},[73,5159,5160],{"class":248},"errTitle.length>0",[73,5162,245],{"class":198},[73,5164,294],{"class":198},[73,5166,5167],{"class":283},"{{errTitle}}",[73,5169,300],{"class":198},[73,5171,11],{"class":202},[73,5173,210],{"class":198},[73,5175,5176],{"class":75,"line":125},[73,5177,92],{"emptyLinePlaceholder":91},[73,5179,5180,5182,5184,5186,5188,5190,5192,5194],{"class":75,"line":131},[73,5181,1611],{"class":198},[73,5183,178],{"class":202},[73,5185,1544],{"class":206},[73,5187,242],{"class":198},[73,5189,245],{"class":198},[73,5191,2024],{"class":248},[73,5193,245],{"class":198},[73,5195,210],{"class":198},[73,5197,5198,5200,5202,5204,5206,5208,5210,5212],{"class":75,"line":137},[73,5199,1621],{"class":198},[73,5201,178],{"class":202},[73,5203,1544],{"class":206},[73,5205,242],{"class":198},[73,5207,245],{"class":198},[73,5209,2043],{"class":248},[73,5211,245],{"class":198},[73,5213,210],{"class":198},[73,5215,5216,5218,5220,5222,5224,5226,5228,5230],{"class":75,"line":142},[73,5217,1631],{"class":198},[73,5219,1886],{"class":202},[73,5221,1544],{"class":206},[73,5223,242],{"class":198},[73,5225,245],{"class":198},[73,5227,4109],{"class":248},[73,5229,245],{"class":198},[73,5231,210],{"class":198},[73,5233,5234],{"class":75,"line":148},[73,5235,4774],{"class":283},[73,5237,5238,5240,5242],{"class":75,"line":462},[73,5239,1976],{"class":198},[73,5241,1886],{"class":202},[73,5243,210],{"class":198},[73,5245,5246,5248,5250,5252,5254,5256,5258,5260,5262,5264,5266,5268,5270,5272,5274,5276,5278,5280],{"class":75,"line":478},[73,5247,1631],{"class":198},[73,5249,4536],{"class":202},[73,5251,4791],{"class":206},[73,5253,242],{"class":198},[73,5255,245],{"class":198},[73,5257,4798],{"class":248},[73,5259,245],{"class":198},[73,5261,254],{"class":206},[73,5263,242],{"class":198},[73,5265,245],{"class":198},[73,5267,4809],{"class":248},[73,5269,245],{"class":198},[73,5271,1544],{"class":206},[73,5273,242],{"class":198},[73,5275,245],{"class":198},[73,5277,2073],{"class":248},[73,5279,245],{"class":198},[73,5281,210],{"class":198},[73,5283,5284,5286,5288],{"class":75,"line":492},[73,5285,1717],{"class":198},[73,5287,178],{"class":202},[73,5289,210],{"class":198},[73,5291,5292,5294,5296],{"class":75,"line":511},[73,5293,1726],{"class":198},[73,5295,178],{"class":202},[73,5297,210],{"class":198},[73,5299,5300,5302,5304],{"class":75,"line":530},[73,5301,2001],{"class":198},[73,5303,4607],{"class":202},[73,5305,210],{"class":198},[73,5307,5308,5310,5312],{"class":75,"line":549},[73,5309,2111],{"class":198},[73,5311,178],{"class":202},[73,5313,210],{"class":198},[73,5315,5316,5318,5320],{"class":75,"line":564},[73,5317,300],{"class":198},[73,5319,757],{"class":202},[73,5321,210],{"class":198},[73,5323,5324,5326,5328],{"class":75,"line":583},[73,5325,215],{"class":198},[73,5327,410],{"class":202},[73,5329,210],{"class":198},[73,5331,5332,5334,5336],{"class":75,"line":1413},[73,5333,828],{"class":805},[73,5335,831],{"class":805},[73,5337,834],{"class":198},[73,5339,5340,5342,5344,5346,5348,5350],{"class":75,"line":1419},[73,5341,839],{"class":202},[73,5343,842],{"class":198},[73,5345,821],{"class":198},[73,5347,4230],{"class":248},[73,5349,821],{"class":198},[73,5351,852],{"class":198},[73,5353,5354,5356,5358,5360,5362,5364,5366,5368],{"class":75,"line":1425},[73,5355,4239],{"class":202},[73,5357,842],{"class":198},[73,5359,4244],{"class":283},[73,5361,821],{"class":198},[73,5363,693],{"class":248},[73,5365,821],{"class":198},[73,5367,4914],{"class":283},[73,5369,852],{"class":198},[73,5371,5372,5374],{"class":75,"line":1431},[73,5373,2167],{"class":202},[73,5375,2170],{"class":198},[73,5377,5378,5380],{"class":75,"line":1437},[73,5379,2176],{"class":805},[73,5381,1030],{"class":198},[73,5383,5384,5386,5388,5391],{"class":75,"line":1443},[73,5385,4933],{"class":202},[73,5387,842],{"class":198},[73,5389,5390],{"class":198},"''",[73,5392,852],{"class":198},[73,5394,5395,5398,5400],{"class":75,"line":1449},[73,5396,5397],{"class":202},"            errTitle",[73,5399,842],{"class":198},[73,5401,4938],{"class":198},[73,5403,5404],{"class":75,"line":1455},[73,5405,1463],{"class":198},[73,5407,5408],{"class":75,"line":1460},[73,5409,2213],{"class":198},[73,5411,5412,5414],{"class":75,"line":1466},[73,5413,2219],{"class":202},[73,5415,2222],{"class":198},[73,5417,5418,5421,5423,5426],{"class":75,"line":1471},[73,5419,5420],{"class":202},"        checkForm",[73,5422,983],{"class":198},[73,5424,5425],{"class":986},"$event",[73,5427,996],{"class":198},[73,5429,5430,5432,5434,5436,5438,5440,5443,5446,5448,5450],{"class":75,"line":1477},[73,5431,2291],{"class":805},[73,5433,983],{"class":202},[73,5435,2347],{"class":198},[73,5437,291],{"class":283},[73,5439,954],{"class":198},[73,5441,5442],{"class":283},"length",[73,5444,5445],{"class":198}," >",[73,5447,1779],{"class":456},[73,5449,1027],{"class":202},[73,5451,1030],{"class":198},[73,5453,5454,5457,5459],{"class":75,"line":1483},[73,5455,5456],{"class":805},"                return",[73,5458,2373],{"class":472},[73,5460,444],{"class":198},[73,5462,5463,5466,5469],{"class":75,"line":1488},[73,5464,5465],{"class":198},"            }",[73,5467,5468],{"class":805},"else",[73,5470,1030],{"class":198},[73,5472,5473,5476,5478,5481,5484],{"class":75,"line":2130},[73,5474,5475],{"class":283},"                $event",[73,5477,954],{"class":198},[73,5479,5480],{"class":979},"preventDefault",[73,5482,5483],{"class":202},"()",[73,5485,444],{"class":198},[73,5487,5488,5491,5493,5495,5497],{"class":75,"line":2139},[73,5489,5490],{"class":283},"                ConcreteAlert",[73,5492,954],{"class":198},[73,5494,2818],{"class":979},[73,5496,983],{"class":202},[73,5498,1030],{"class":198},[73,5500,5501,5504,5506,5508,5511,5513],{"class":75,"line":2148},[73,5502,5503],{"class":202},"                    title",[73,5505,842],{"class":198},[73,5507,821],{"class":198},[73,5509,5510],{"class":248},"入力項目に誤りがあります。",[73,5512,821],{"class":198},[73,5514,852],{"class":198},[73,5516,5517,5520,5522,5524,5527,5529],{"class":75,"line":2164},[73,5518,5519],{"class":202},"                    message",[73,5521,842],{"class":198},[73,5523,821],{"class":198},[73,5525,5526],{"class":248},"アルバムタイトルが入力されていません。",[73,5528,821],{"class":198},[73,5530,852],{"class":198},[73,5532,5533,5536,5538],{"class":75,"line":2173},[73,5534,5535],{"class":202},"                    delay",[73,5537,842],{"class":198},[73,5539,5540],{"class":456},"5000\n",[73,5542,5543,5545],{"class":75,"line":2181},[73,5544,2655],{"class":198},[73,5546,1097],{"class":202},[73,5548,5549,5551,5554,5556,5558,5561],{"class":75,"line":2194},[73,5550,2366],{"class":198},[73,5552,5553],{"class":283},"errTitle",[73,5555,2247],{"class":198},[73,5557,436],{"class":198},[73,5559,5560],{"class":248},"タイトルを入力してください。",[73,5562,1290],{"class":198},[73,5564,5565],{"class":75,"line":2205},[73,5566,672],{"class":198},[73,5568,5569],{"class":75,"line":2210},[73,5570,1463],{"class":198},[73,5572,5573],{"class":75,"line":2216},[73,5574,134],{"class":198},[73,5576,5577],{"class":75,"line":2225},[73,5578,151],{"class":198},[73,5580,5581,5583,5585],{"class":75,"line":2238},[73,5582,300],{"class":198},[73,5584,410],{"class":202},[73,5586,210],{"class":198},[11,5588,5589,5591,5592,5595,5596,5598,5599,5601],{},[32,5590,4607],{},"の箇所に",[32,5593,5594],{},"@submit=\"checkForm\"","というイベントを作成。これはこのformがsubmitされた際に",[32,5597,5045],{},"というメソッドを発火させるという意味です。そして",[32,5600,5045],{},"ではtitleの値が空かどうかを判断しています。",[11,5603,5604,5605,5608,5609,5611,5612,5615,5616,5619,5620,5622],{},"もし空でない場合は",[32,5606,5607],{},"return true","となって",[32,5610,4809],{},"が通って、サーバーへ値が送信されます。からの場合は",[32,5613,5614],{},"$event.preventDefault();","が実行されてsubmitされません。そして",[32,5617,5618],{},"ConcreteAlert.error","という8.4系から使用できるconcrete5のフラッシュメッセージのjsを出しています。（",[32,5621,5618],{},"は特に何も読み込まないでも使える）",[11,5624,5625],{},"空で「登録」を押すと以下の様になります。",[1187,5627],{":src":5628,":width":1190},"'_mix\u002Fsch-2020-08-27-0.07.18-768x531.png'",[11,5630,5631,5633],{},[32,5632,5614],{},"によってサーバーにデータは送信されず、ユーザーに対してエラーを表示できました。",[5635,5636,5638],"h4",{"id":5637},"eslintがある時のchips","ESLintがある時のchips",[11,5640,5641,5644],{},[32,5642,5643],{},"ConcreteAlert"," はconcrete5が用意してくれた便利なフラッシュメッセージです。しかし、ESLint付きのvueCLI内で使用ようとすると、ビルド時にこの様に怒られます。",[48,5646,5649],{"className":5647,"code":5648,"language":53},[51],"ERROR  Failed to compile with 1 errors                                                                                                       23:50:16\n\n error  in .\u002Fsrc\u002Fcomponents\u002Fform.vue\n\nModule Error (from .\u002Fnode_modules\u002Feslint-loader\u002Findex.js):\n\n\u002FApplications\u002FMAMP\u002Fhtdocs\u002Fc5test\u002Fpackages\u002Fvuetest\u002Fjs\u002Fpackageui\u002Fsrc\u002Fcomponents\u002Fform.vue\n  40:17  error  'ConcreteAlert' is not defined  no-undef\n\n✖ 1 problem (1 error, 0 warnings)\n",[32,5650,5648],{"__ignoreMap":56},[11,5652,5653,5654,5656,5657,5660],{},"そうです。vueプロジェクト内には",[32,5655,5643],{}," を定義したjsファイルがない、というかconcreteが用意したjsを読み込めないのでこの様に怒られます。これだとビルドできないので",[32,5658,5659],{},"package.json","のeslintの設定に以下の記述をします。",[48,5662,5665],{"className":5663,"code":5664,"language":53},[51]," \"eslintConfig\": {\n　　\"globals\":{\n      \"ConcreteAlert\": true,\n    }\n },\n",[32,5666,5664],{"__ignoreMap":56},[11,5668,5669,5670,5672],{},"こうするとESLintは「ConcreteAlertってのはグローバルな奴なんだな〜。」と認識してくれて、実際にvueプロジェクト外にある",[32,5671,5643],{},"に対して怒らなくなります。",[24,5674,5675],{"id":5675},"バックエンド実装",[11,5677,5678],{},"vueを用いてまずはアルバムのタイトルだけを入力できるフォームを作りました。そしてこのタイトルをDBに挿入するまで行います。と言ってもシングルページコントローラーを以下の様に記述します。",[48,5680,5682],{"className":66,"code":5681,"filename":68,"language":69,"meta":56,"style":56},"\u003C?php\nnamespace Concrete\\Package\\Vuetest\\Controller\\SinglePage\\Dashboard;\ndefined('C5_EXECUTE') or die('Access Denied.');\nuse \\Concrete\\Core\\Page\\Controller\\DashboardPageController;\nuse Concrete\\Core\\Routing\\Redirect;\nuse Concrete\\Core\\Http\\Request;\n\n\nuse Core;\nuse Database;\n\nclass Vuetest extends DashboardPageController\n{\n    public $packageHandle = 'vuetest';\n\n    public function on_start()\n    {\n        $this->requireAsset('package-vue-production');\n    }\n\n    public function view() {\n    }\n\n    public function add(){\n        if(Request::isPost() == true){\n            $title = $this->post('title');\n\n            if(empty($title)==false){\n                $db = Database::connection();\n                $db->executeQuery(\"START TRANSACTION\");\n                $db->executeQuery(\n                    'INSERT album SET `title`=?, `created`=now(), `modified`=now()',\n                    array($title)\n                );\n                $db->executeQuery(\"COMMIT\");\n                Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n            }else{\n                Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n            }\n\n        }else{\n            $this->render('\u002Fdashboard\u002Fvuetest\u002Fadd');\n        }\n    }\n}\n",[32,5683,5684,5688,5693,5697,5702,5707,5712,5716,5720,5725,5730,5734,5738,5742,5746,5750,5755,5759,5763,5767,5771,5775,5779,5783,5787,5792,5797,5801,5806,5811,5816,5821,5826,5831,5836,5841,5846,5851,5855,5859,5863,5867,5872,5876,5880],{"__ignoreMap":56},[73,5685,5686],{"class":75,"line":76},[73,5687,718],{},[73,5689,5690],{"class":75,"line":82},[73,5691,5692],{},"namespace Concrete\\Package\\Vuetest\\Controller\\SinglePage\\Dashboard;\n",[73,5694,5695],{"class":75,"line":88},[73,5696,723],{},[73,5698,5699],{"class":75,"line":95},[73,5700,5701],{},"use \\Concrete\\Core\\Page\\Controller\\DashboardPageController;\n",[73,5703,5704],{"class":75,"line":101},[73,5705,5706],{},"use Concrete\\Core\\Routing\\Redirect;\n",[73,5708,5709],{"class":75,"line":107},[73,5710,5711],{},"use Concrete\\Core\\Http\\Request;\n",[73,5713,5714],{"class":75,"line":113},[73,5715,92],{"emptyLinePlaceholder":91},[73,5717,5718],{"class":75,"line":119},[73,5719,92],{"emptyLinePlaceholder":91},[73,5721,5722],{"class":75,"line":125},[73,5723,5724],{},"use Core;\n",[73,5726,5727],{"class":75,"line":131},[73,5728,5729],{},"use Database;\n",[73,5731,5732],{"class":75,"line":137},[73,5733,92],{"emptyLinePlaceholder":91},[73,5735,5736],{"class":75,"line":142},[73,5737,3851],{},[73,5739,5740],{"class":75,"line":148},[73,5741,1030],{},[73,5743,5744],{"class":75,"line":462},[73,5745,3860],{},[73,5747,5748],{"class":75,"line":478},[73,5749,92],{"emptyLinePlaceholder":91},[73,5751,5752],{"class":75,"line":492},[73,5753,5754],{},"    public function on_start()\n",[73,5756,5757],{"class":75,"line":511},[73,5758,1213],{},[73,5760,5761],{"class":75,"line":530},[73,5762,3879],{},[73,5764,5765],{"class":75,"line":549},[73,5766,134],{},[73,5768,5769],{"class":75,"line":564},[73,5770,92],{"emptyLinePlaceholder":91},[73,5772,5773],{"class":75,"line":583},[73,5774,3892],{},[73,5776,5777],{"class":75,"line":1413},[73,5778,134],{},[73,5780,5781],{"class":75,"line":1419},[73,5782,92],{"emptyLinePlaceholder":91},[73,5784,5785],{"class":75,"line":1425},[73,5786,3910],{},[73,5788,5789],{"class":75,"line":1431},[73,5790,5791],{},"        if(Request::isPost() == true){\n",[73,5793,5794],{"class":75,"line":1437},[73,5795,5796],{},"            $title = $this->post('title');\n",[73,5798,5799],{"class":75,"line":1443},[73,5800,92],{"emptyLinePlaceholder":91},[73,5802,5803],{"class":75,"line":1449},[73,5804,5805],{},"            if(empty($title)==false){\n",[73,5807,5808],{"class":75,"line":1455},[73,5809,5810],{},"                $db = Database::connection();\n",[73,5812,5813],{"class":75,"line":1460},[73,5814,5815],{},"                $db->executeQuery(\"START TRANSACTION\");\n",[73,5817,5818],{"class":75,"line":1466},[73,5819,5820],{},"                $db->executeQuery(\n",[73,5822,5823],{"class":75,"line":1471},[73,5824,5825],{},"                    'INSERT album SET `title`=?, `created`=now(), `modified`=now()',\n",[73,5827,5828],{"class":75,"line":1477},[73,5829,5830],{},"                    array($title)\n",[73,5832,5833],{"class":75,"line":1483},[73,5834,5835],{},"                );\n",[73,5837,5838],{"class":75,"line":1488},[73,5839,5840],{},"                $db->executeQuery(\"COMMIT\");\n",[73,5842,5843],{"class":75,"line":2130},[73,5844,5845],{},"                Redirect::to('\u002Fdashboard\u002Fvuetest')->send();\n",[73,5847,5848],{"class":75,"line":2139},[73,5849,5850],{},"            }else{\n",[73,5852,5853],{"class":75,"line":2148},[73,5854,5845],{},[73,5856,5857],{"class":75,"line":2164},[73,5858,672],{},[73,5860,5861],{"class":75,"line":2173},[73,5862,92],{"emptyLinePlaceholder":91},[73,5864,5865],{"class":75,"line":2181},[73,5866,1452],{},[73,5868,5869],{"class":75,"line":2194},[73,5870,5871],{},"            $this->render('\u002Fdashboard\u002Fvuetest\u002Fadd');\n",[73,5873,5874],{"class":75,"line":2205},[73,5875,1463],{},[73,5877,5878],{"class":75,"line":2210},[73,5879,134],{},[73,5881,5882],{"class":75,"line":2216},[73,5883,151],{},[11,5885,5886,5888,5889,5892,5893,5896],{},[32,5887,2062],{}," でpostを送ると",[32,5890,5891],{},"add()","にて処理が行われます。",[32,5894,5895],{},"Request::isPost()","というメソッドを用いてリクエストがpostかどうかをチェックします。postであれば値をDBへ挿入するスクリプトを実行し、そうでなければ新規追加の画面を表示します。",[11,5898,5899,5902,5903,5906,5907,5910,5911,5914],{},[32,5900,5901],{},"DashboardPageController","配下では",[32,5904,5905],{},"$this->post('name')"," というメソッドで対応するname属性のinputの値を取得することができます！先ほどのフォームではタイトルの値を",[32,5908,5909],{},"name=\"title\"","としていたので",[32,5912,5913],{},"$title = $this->post('title');","で取得します",[40,5916,5918],{"id":5917},"chips-必ずバックエンドでもバリデーションを実装する","chips 必ずバックエンドでもバリデーションを実装する",[11,5920,5921],{},"よくみると下記の様にタイトルの値を検査しています。",[48,5923,5925],{"className":66,"code":5924,"filename":68,"language":69,"meta":56,"style":56},"if(empty($title)==false){\n ...\n}\n",[32,5926,5927,5932,5937],{"__ignoreMap":56},[73,5928,5929],{"class":75,"line":76},[73,5930,5931],{},"if(empty($title)==false){\n",[73,5933,5934],{"class":75,"line":82},[73,5935,5936],{}," ...\n",[73,5938,5939],{"class":75,"line":88},[73,5940,151],{},[178,5942,5944,5945],{"className":5943},[181,593],"\n「フロントエンド でタイトルの値をバリデーションしたから別にやらなくても良くない？」というのは厳禁です。postで来た値は必ずバックエンドで同様にバリデーションをかけます。",[5946,5947,5948],"b",{},"なぜならブラウザのconsoleでフロントでの値は偽造することもでき、フロントエンドのバリデーションを不正にスルーできるからです。",[11,5950,5951],{},"vueで行っているバリデーションはあくまでユーザー補助、UX的な物でありセキュリティの観点からは言えばガバガバです。エンドユーザーが偽造ができないバックエンドであれば確実にバリデーションをすることができます。",[11,5953,5954],{},"dashbord配下は基本的にサイト管理者が触る物なので、不正な値を入れようとする人はいないと思いますが、フロントからpostされた値は基本的に信用しないスタイルを貫いた方が無難です。",[24,5956,5957],{"id":5957},"データを入れてみる",[11,5959,5960,5961,5963],{},"では早速使ってみましょう。",[32,5962,2062],{}," にアクセスするとタイトル入力フォームが出てきました。仮に「テスト」と入力。そして「登録」を押します。",[1187,5965],{":src":5966,":width":1190},"'_mix\u002Fsch-2020-08-27-0.48.59-768x203.png'",[11,5968,5969],{},"一覧のページにリダイレクトされました。ちゃんと挿入されたか、phpmyadminでみてみましょう。",[1187,5971],{":src":5972,":width":3381,":center":776},"'_mix\u002Fsch-2020-08-27-0.51.36-768x340.png'",[11,5974,5975],{},"いましたね。titleが「テスト」となっているので、正しくデータが入力されました。",[24,5977,5978],{"id":3502},"次回は…",[11,5980,5981],{},"以上がvueとバックエンド部分の一通りの実装でした。",[3575,5983,5984,5987,5990],{},[2884,5985,5986],{},"シングルページにvueのエントリーポイントを作る",[2884,5988,5989],{},"エントリポイントにレンダリングされる様にコンポーネントを設定",[2884,5991,5992],{},"jsをシングルページに読み込む",[11,5994,5995],{},"¥以上を意識すればconcrete5のシングルページに自由にvueを用いてUIを構築できます。あとはvueの使い方とバックエンドの設計を頑張るだけです。そして次回は編集画面と一覧画面の作成をしていきます。",[3508,5997,5998],{},"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 .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 .s0W1g, html code.shiki .s0W1g{--shiki-default:#BABED8}html pre.shiki code .s6cf3, html code.shiki .s6cf3{--shiki-default:#89DDFF;--shiki-default-font-style:italic}html pre.shiki code .sbqyR, html code.shiki .sbqyR{--shiki-default:#FF9CAC}html pre.shiki code .sdLwU, html code.shiki .sdLwU{--shiki-default:#82AAFF}html pre.shiki code .s7ZW3, html code.shiki .s7ZW3{--shiki-default:#BABED8;--shiki-default-font-style:italic}html pre.shiki code .sx098, html code.shiki .sx098{--shiki-default:#F78C6C}",{"title":56,"searchDepth":88,"depth":88,"links":6000},[6001,6004,6005,6008,6009,6015,6018,6019],{"id":3570,"depth":82,"text":3570,"children":6002},[6003],{"id":3591,"depth":88,"text":3592},{"id":3601,"depth":82,"text":3602},{"id":3822,"depth":82,"text":3823,"children":6006},[6007],{"id":3826,"depth":88,"text":3827},{"id":3990,"depth":82,"text":3990},{"id":4520,"depth":82,"text":4520,"children":6010},[6011,6012],{"id":4529,"depth":88,"text":4530},{"id":4961,"depth":88,"text":4961,"children":6013},[6014],{"id":5637,"depth":95,"text":5638},{"id":5675,"depth":82,"text":5675,"children":6016},[6017],{"id":5917,"depth":88,"text":5918},{"id":5957,"depth":82,"text":5957},{"id":3502,"depth":82,"text":5978},[3535],"2020-08-27","oncrete5にVueCLIを使ってUIを構築する。データの登録。",{},{"title":3553,"description":6022},"series\u002Fconcrete5vue-2",[3546,3547,610],"s28kXBmZtYl1vPtmgjcP0QiTjdZEL9Zwpvzi-377-0o",1780987144435]