LoginSignup
1
0

More than 3 years have passed since last update.

Vue.jsでtextareaをコンポーネントにする際の注意

Posted at

問題

textarea(inputも同様)をコンポーネント化する際
値をv-modelすることができない

解決

以下のような記述をする。

コンポーネント側

BaseTextarea.vue
<template>
  <textarea
          ref="adjust_textarea"
          @input="updateValue" //★ここ
          class="c-input-textarea"
          :placeholder="placeholder"
          @keydown="adjustHeight"
  >
  </textarea>
</template>
<script>
  export default {
    name: 'BaseTextarea',
    data() {
      return {
        textareaVal: '',
      }
    },
    props: {
      placeholder: {
        type: String,
        required: true,
      },
      text: {
        type: String,
        required: false,
        default: () => '',
      },
      value: {
        type: String,
        required: false,
        default: () => '',
      }
    },
    methods: {
      adjustHeight() {
        const textarea = this.$refs.adjust_textarea
        const resetHeight = new Promise(function(resolve) {
          resolve((textarea.style.height = 'auto'))
        })
        resetHeight.then(function() {
          textarea.style.height = textarea.scrollHeight + 'px'
        })
      },
      updateValue(e) { //★ここ
        this.$emit("input", e.target.value);
      }
    },
  }
</script>
<style lang="scss" scoped>
  @import '../../../assets/scss/object/component/_textarea.scss';
</style>

表示する側

Form.vue

<template>
  <div class="client_footer">
    <div class="client_footer__inner">
      <the-stamp-window v-if="stamp_window" @close="closeModal" />
      <div class="msg_input__form">
        <div class="msg_input__wrap">
          <div class="msg_input">
            <base-textarea v-model="inputComment"
                    :placeholder="'メッセージを入れてください'" /> //★ここ
            <base-link class="msg_stamp__button" @click="openModal">
              
            </base-link>
          </div>
          <p class="msg_typing">
            ○○さんがtyping...
          </p>
        </div>
        <base-btn @click="addComment"
                :text="'送信'"/>
      </div>
    </div>
  </div>
</template>

<script>
import BaseBtn from '../component/BaseButton'
import BaseTextarea from '../component/BaseTextarea'
import BaseLink from '../component/BaseLink'
import TheStampWindow from '@/components/object/project/TheStampWindow'
import {db} from '../../../libs/firebase-app';

export default {
  name: 'TheClientFooter',
  components: { TheStampWindow, BaseLink, BaseTextarea, BaseBtn },
  data() {
    return {
      stamp_window: false,
      // form入力データ
      inputComment: "", //★ここ
      // バリデーション
      commentRules: [
        v => !!v || 'コメントは必須項目です',
      ],
      // Formダイアログの表示可否
      displayForm: false,
    }
  },
  methods: {
    // モーダル
    openModal() {
      this.stamp_window = true
    },
    closeModal() {
      this.stamp_window = false
    },
    // コメント追加
    addComment() {
      const now = new Date()
      // コメントをFirestoreへ登録
      db.collection('comments').add({
        content: this.inputComment,
        avatar: 'https://picsum.photos/50?image=' + (Math.floor(Math.random() * 400) + 1),
        createdAt: now
      })
    },
  },
}
</script>

<style lang="scss" scoped>
@import '../../../assets/scss/object/project/clientFooter.scss';
</style>
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0