top of page
  • 執筆者の写真T sakurako

VueでWEBアプリ(24)

今回は、投稿・詳細画面を同じ画面に、押したボタンによって表示が切り替わるように修正しました。

詳細表示の時はmode が'show'、新規登録の時はmode が'new'で切り替えるようにしています。


 

Article.vue


一覧表示コンポーネントの方で、clickRow…行クリック時の処理 を修正、

onNew…「新規登録」ボタン押下時の処理 を追加しました。


clickRowでは、ArticleDetail.vueへ渡すデータに、mode:'show'を追加しています。

onNewは、clickRowと同じ方法でmode:'new'を渡すようにしています。

    clickRow (row) {
      this.$router.push({
        path: '/articledetail',
        query :{
          title: row.title,
          author: row.author,
          post_date: row.post_date,
          content: row.content,
          mode: 'show',
        }
      })
    },

    onNew(){
      this.$router.push({
        path: '/articledetail',
        query :{
          mode: 'new',
        },
      })
    },





ArticleDetail.vue


methodsで、詳細表示に使用していたtest()をdisplayForm()として作り直しました。

queryで受け取ったmodeが何かで表示を切り替えるようにしています。


showならフォームのタイトルを「投稿詳細」に・フォームのそれぞれの入力欄にクリックした行のデータが入るように、

newならフォームのタイトルを「投稿フォーム」に、

といった具合にしています。

    displayForm() {
      if (this.$route.query.mode === 'show') {
          this.mode = this.$route.query.mode

          this.formTitle = '投稿詳細'

          this.title = this.$route.query.title
          this.author= this.$route.query.author
          this.post_date= this.$route.query.post_date
          this.content= this.$route.query.content
      
      } else if (this.$route.query.mode === 'new') {
          this.mode = this.$route.query.mode

          this.formTitle = '投稿フォーム'
      }
    },


テンプレートでは、modeがshowの時は入力欄がreadonlyになるようにしています。

日付入力欄については、もともとreadonlyにしてv-menuでカレンダーを表示するようにしていたので、:readonly="mode !== 'new'"としています。

   <div id="app">
    <v-app>
      <v-container>
        <v-card>
        <v-card-title>{{formTitle}}</v-card-title>
          <v-form ref="formref">
            <v-card-text>
              <v-text-field
                v-model="title"
                :rules="titleRules"
                label="タイトル"
                counter="10"
                :readonly="mode === 'show'"
                required
              >
              </v-text-field>
              <v-text-field
                v-model="author"
                :rules="authorRules"
                label="投稿者"
                counter="10"
                :readonly="mode === 'show'"
                required
              >
              </v-text-field>
              <v-menu v-model="menu" max-width="290px" min-width="290px">
                  <template v-slot:activator="{ on }">
                    <v-text-field
                      slot="activator"
                      v-model="post_date"
                      :rules="post_dateRules"
                      label="日付"
                      v-on="on"
                      :readonly="mode !== 'new'"
                      required
                    >
                    </v-text-field>
                  </template>
                <v-date-picker v-model="post_date" />
              </v-menu>
              <v-text-field
                v-model="content"
                :rules="contentRules"
                label="本文"
                counter="100"
                :readonly="mode === 'show'"
                required
              >
              </v-text-field>
            </v-card-text>
          </v-form>
          <v-divider></v-divider>
          <div v-if="this.mode !== 'show'">
          <v-card-actions>
            <v-btn text @click="submit">送信する</v-btn>
            <span v-if="success">
              <v-alert 
                type="success"
                dense
                dismissible
              >
                送信成功!
              </v-alert>
            </span>
            <span v-if="failure">
              <v-alert 
                type="error"
                dense
                dismissible
              >
                送信失敗
              </v-alert>
            </span>
          </v-card-actions>
          </div>
        </v-card>
      </v-container>

      <v-container>
        <v-btn to="/article">一覧へ戻る</v-btn>
      </v-container>

   </v-app>
  </div>




 

この『VueでWEBアプリ』シリーズのコードをgithubで公開しています。参考までに。


記事: Blog2_Post
bottom of page