質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

0回答

434閲覧

【GAS + Vue.js】子コンポーネントの内容が画面に表示されない

退会済みユーザー

退会済みユーザー

総合スコア0

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

1クリップ

投稿2023/04/09 03:18

編集2023/04/09 05:19

実現したいこと

子コンポーネントの内容を画面に表示したい

前提

プログラミング初心者です。
GAS + Vue.jsでWebシステムを作成中です。
親コンポーネントから子コンポーネントを呼び出し、子コンポーネントの内容を画面に表示したいのですが
正常に表示されません。

発生している問題・エラーメッセージ

エラーは特に表示されていません。
子コンポーネントの<div v-for="(item, index) of reactiveArray">配下にあるタグが正常に画面に表示されていません。

該当のソースコード

※1 gasのソースコードは本件と関係ないと思いますので、省略します。
※2 文字数の関係上、一部省略します。

index.html

1<!DOCTYPE html> 2<html style="overflow-y:hidden"> 3<head> 4 <base target="_top"> 5 <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bulma@0.9.3/css/bulma.min.css"> 6 <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet"> 7 <style> 8 ::-webkit-scrollbar { 9 background: transparent; 10 height: 10px; 11 width: 8px; 12 } 13 ::-webkit-scrollbar-thumb { 14 border: none; 15 background: #bbb; 16 -webkit-border-radius: 8px; 17 border-radius: 8px; 18 min-height: 40px; 19 } 20 (略) 21 </style> 22</head> 23<body> 24 <div id="app"> 25 <div style="display: flex;"> 26 <!-- フィルタエリア --> 27 <div style=" 28 width: 230px; 29 height: 100vh; 30 background-color: #fafafa; 31 padding: 0 30px; 32 overflow: auto; 33 "> 34 <!-- タイトル1 --> 35 <h3 class="title is-4" style="margin-top: 50px;"> 36 <span class="material-icons">filter_list</span> 基本情報 37 </h3> 38 <!-- フォーム ★★★関数にしたい範囲(2回目以降indexにスタート列追加の為注意!)--> 39 <sample :message="keysContent1" /> 40 <!-- フィルタクリアボタン --> 41 <div @click="initConditions()" class="btn" style="bottom: 30px; left: 50px; background-color: #e85a5a;"> 42 <span class="material-icons">filter_alt_off</span> 43 </div> 44 </div> 45 <!-- 編集履歴ボタン --> 46 <div @click="help()" style="user-select: none;"> 47 <span class="material-icons">history</span> 48 </div> 49 <!-- データエリア --> 50 <div style=" 51 max-width: calc(100% - 230px); 52 height: 100vh; 53 padding: 0 50px; 54 overflow: auto; 55 "> 56 <!-- タイトル --> 57 <h1 class="title is-4" style="margin-top: 50px;"> 58 <span class="material-icons">description</span> 59 <?= title ?> 60 </h1> 61 <h6 id="memo"> 62 テスト用データ... 63 </h6> 64 <!-- テーブル --> 65 <table class="table is-bordered" style="white-space: nowrap; position: relative;"> 66 <col span="2">            67 <!--何もしない列(1~2列) --> 68 <col span="1" class="example"> <!-- 表の非表示列(3列) --> 69 <thead> 70 <tr> 71 <td colspan="5" id="hed1"  align=center>基本情報</td> 72 <td colspan="2" id="hed1"  align=center>ネジ棚在庫一覧</td> 73 <td colspan="3" id="hed1"  align=center>詳細情報</td> 74 </tr> 75 <tr> 76 <th v-for="key in keys">{{ key.replace(/:.*$/,"") }}</th> 77 </tr> 78 </thead> 79 <tbody> 80 <template v-for="record in records"> 81 <tr v-if="checkCondition(record)"  onclick="Click_Sub(this);"> 82 <template v-for="(item,index) in record"> 83 <td> {{ item }}</td> 84 </template> 85 </template> 86 </tr> 87 </template> 88 </tbody> 89 </table> 90 </div> 91 </div> 92 </div> 93 <!-- Vue.js --> 94 <script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> 95 <script src="https://unpkg.com/http-vue-loader"></script> 96 <script> 97 const sample = httpVueLoader( 98 'data:text/plain,' + 99 '<?!= encodeURIComponent(HtmlService.createTemplateFromFile('app.vue').evaluate().getContent()).replace(/[\'']/g,"\\'") ?>' 100 ); 101 var app = new Vue({ 102 el: '#app', 103 data () { 104 return { 105 keys: [], // シートの1行目 106 records: [], // シートの2行目以降 107 conditions: [], // 入力した絞込条件 108 } 109 }, 110 components:{ // 追加 111 sample 112 }, 113 computed:{ 114 keysContent1(){ 115 console.log('index.html computed keysContent:' + this.keys.slice(0,4)) 116 return this.keys.slice(0,4) 117 }, 118 }, 119 mounted: function(){ 120 google.script.run.withSuccessHandler(function(text) { 121 const response = JSON.parse(text) 122 app.keys = response[0]; 123 app.records = response.slice(1);               //3行目の取り出し 124 app.records.splice();                       125 app.initConditions(); //チェックボックスのみを抜き出す[] 126 }).getSheetData(); 127 }, 128 methods: { 129 // フィルタ条件を初期化する 130 initConditions: function(){ 131 this.conditions = app.keys.map((key) => { 132 return app.isCheckbox(key) 133 ? [] 134 : "" 135 }) 136 }, 137 // レコードが全ての絞込条件に合致するかチェックする 138 checkCondition: function(record){ 139 for (let i = 0; i < this.keys.length; i++){ 140 if ( this.isCheckbox(this.keys[i]) ){ 141 if (this.conditions[i].length && !this.conditions[i].includes(record[i])) return false; 142 } else { 143 if(this.conditions[i].length && !this.conditions[i].includes(record[i])) return false; //チェックボックスと同じ条件にした(完全一致用) 144 } 145 } 146 return true; 147 }, 148 // フォームタイプをチェックする 149 isHidden: function(key){ return /^.*:hidden/.test(key) }, 150 isSelect: function(key){ return /^.*:select\[.*\]$/.test(key) }, 151 isRadio: function(key){ return /^.*:radio\[.*\]$/.test(key) }, 152 isCheckbox: function(key){ return /^.*:checkbox\[.*\]$/.test(key) }, 153 // シートの項目名末尾に付与した選択肢の配列を返す 154 getOptions: function(key){ 155 const param = /:(select|radio|checkbox)\[.*\]$/.exec(key) // param[0] => ':select["A","B","C"]' 156 const optionsString = /\[.*\]/.exec(param[0]) // optionsString[0] => '["A","B","C"]' 157 return JSON.parse(optionsString[0]) // return => ["A","B","C"] 158 } 159 } 160 }) 161 // 背景色を設定 162 function Click_Sub(obj) { 163 var bg_color_tmp = "rgb(192, 192, 192)"; 164 if(obj.style.backgroundColor==bg_color_tmp) { 165 // 背景色が上記の場合は白色にする 166 obj.style.backgroundColor='#ffffff'; 167 } else { 168 // 背景色が上記以外の場合(白色)は黄色にする 169 obj.style.backgroundColor=bg_color_tmp; 170 } 171} 172 </script> 173</body> 174</html>

app.vue.html

1<template> 2 <div>reactiveArray:{{reactiveArray.length}}</div> 3 <div v-for="(item, index) of reactiveArray"> 4 <div v-if="!isHidden(item)" style="margin-bottom: 1em;"> 5 <!-- 項目名 --> 6 <label class="label is-small">{{ item.replace(/:.*$/,"") }}</label> 7 <!-- プルダウン(:select["A","B"...] が項目名末尾に付与されていた場合) --> 8 <template v-if="isSelect(item)"> 9 <select v-model="conditions[index]" class="select is-small"> 10 <option value="">選択なし</option> 11 <option v-for="option in getOptions(item)" :value="option">{{ option }}</option> 12 </select> 13 </template> 14 <!-- ラジオボタン(:radio["A","B"...] が項目名末尾に付与されていた場合) --> 15 <template v-else-if="isRadio(item)"> 16 <label for="radio-none"> 17 <input type="radio" id="radio-none" value="" v-model="conditions[index]" /> 18 選択なし 19 </label> 20 <label v-for="(option, radioIndex) in getOptions(item)" :for="'radio-' + radioIndex"> 21 <input type="radio" :id="'radio-' + radioIndex" :value="option" v-model="conditions[index]" /> 22 {{ option }} 23 </label> 24 </template> 25 <!-- チェックボックス(:checkbox["A","B"...] が項目名末尾に付与されていた場合) --> 26 <template v-else-if="isCheckbox(item)"> 27 <label v-for="(option, checkboxIndex) in getOptions(item)" :for="'checkbox-' + checkboxIndex"> 28 <input type="checkbox" :id="'checkbox-' + checkboxIndex" :value="option" v-model="conditions[index]" /> 29 {{ option }} 30 </label> 31 </template> 32 <!-- テキストボックス(指定なしの場合) --> 33 <input v-else v-model="conditions[index]" type="text" class="input is-small" /> 34 </div> 35 </div> 36</template> 37<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14"></script> 38<script> 39 module.exports = { 40 props: { 41 message: { 42 type: Array, 43 } 44 }, 45 data() { 46 return { 47 conditions: [], 48 // 入力した絞込条件 49 contents: [], 50 } 51 }, 52 watch: { 53 message: function(newValue, oldValue) { 54 console.log('message items changed:', newValue, oldValue) 55 this.contents = newValue 56 }, 57 contents: function(newValue, oldValue) { 58 console.log('contents items changed:', newValue, oldValue) 59 } 60 }, 61 computed: { 62 reactiveArray() { 63 console.log('reactiveArray item:' + this.contents) 64 return this.contents; 65 } 66 }, 67 methods: { 68 isHidden: function(item){ 69 console.log('isHidden item:' + item) 70 console.log('isHidden:' + /^.*:hidden/.test(item)) 71 return /^.*:hidden/.test(item) 72 }, 73 isSelect: function(item){ 74 console.log('isSelect item:' + item) 75 console.log('isSelect:' + /^.*:select\[.*\]$/.test(item)) 76 return /^.*:select\[.*\]$/.test(item) 77 }, 78 isRadio: function(item){ 79 console.log('isRadio item:' + item) 80 console.log('isRadio:' + /^.*:radio\[.*\]$/.test(item)) 81 return /^.*:radio\[.*\]$/.test(item) 82 }, 83 isCheckbox: function(item){ 84 console.log('isCheckbox item:' + item) 85 console.log('isCheckbox:' + /^.*:checkbox\[.*\]$/.test(item)) 86 return /^.*:checkbox\[.*\]$/.test(item) 87 }, 88 // シートの項目名末尾に付与した選択肢の配列を返す 89 getOptions: function(item){ 90 const param = /:(select|radio|checkbox)\[.*\]$/.exec(item) // param[0] => ':select["A","B","C"]' 91 const optionsString = /\[.*\]/.exec(param[0]) // optionsString[0] => '["A","B","C"]' 92 console.log('getOptions:' + JSON.parse(optionsString[0])) 93 94 return JSON.parse(optionsString[0]) // return => ["A","B","C"] 95 } 96 } 97} 98</script>

試したこと

<div v-for="(item, index) of state.reactiveArray">配下にあるisHiddenメソッドなどが正常に動作しているのは確認済みです。

以上です、ご教授いただけると幸いです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yukihide1188

2023/04/10 10:29

- ソースコードが見にくいので、拡張子のみを記載してください(```html) - 現在どのような状態で、何がどうなれば正常なのかがわかりません。 - isHiddenメソッドは正常に動作しているとのことですが、何をもって正常と判断したのでしょうか? - Vue.jsのバージョンなど、環境も記載された方が良いかと思います。
FKM

2023/04/20 06:59

子コンポーネントのどこからもreactiveArrayを受け取っていない気がしますが…。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問