상세 컨텐츠

본문 제목

v-model 커스텀 Component 만들기

Vue

by 일단두잇 2023. 1. 22. 14:49

본문

반응형

 

커스텀 Component를 만드는 경우가 종종 생기는데,

그때 props로 전달해도 되지만 v-model로 변경된 값을 사용하고자 하는 경우가 있다.

 

props로 전달했을 경우는

변경된 값을 event로 전달 받아야 하지만, v-model은 바로 변경된 값을 사용할수 있다.

 


예를 들어 input을 가지고 있는 공통 input을 만들어보자.

만드는 절차는 간략히 보면 아래와 같다

.

1. 공통 Component 생성

 

2. v-model로 받을 인자를 props로 설정 :

 

- Vue2에서 v-model 선언

export default {
  model: {
    prop: 'title',
  },
  props: {
    // 다른 목적을 위해 'value' 사용이 가능 합니다, model을 지정하지않을때 'value' 사용
    value: String, 
    // 'value'를 대신하는 사용자 지정 속성으로 'title' 사용 합니다
    title: {
      type: String,
      default: ''
    }
  }
}
 

- Vue3에서 v-model 선언

value: {
  type: String,
  default: '',
  required: false
},
 

 

3. 내부변수로 input의 v-model 선언

<input
 v-model="internalValue"
 

 

4. input의 v-model 값이 변경될때마다 props의 값을 업데이트 해주는 이벤트 발생

this.$emit('update:value', val) // vue3
this.$emit('input', val) // vue2
 

 

5. 사용하고자 하는 쪽에서 v-model 사용

<CommonInput v-model:value="text" />   <!--vue3 -->
<CommonInput v-model="text" />   <!--vue2 -->
 

아래 Sample은 Vue3로 개발되었다.

 

CommonInput 공통컴포넌트 사용

<template>
  <CommonInput v-model:value="text" /> 
</template>

<script>
// 전역으로 등록했기 때문에 import 필요없음
export default {
  data() {
    return {
      text: ''
    }
  },
  watch: {
    text(val) {
      console.log('text', val)
    }
  }
}
</script>
 

CommonInput.vue

<template>
  <div>
    <input
      :id="id !== '' ? id : userId"
      v-model="internalValue"
      :type="type"
      :class="{'error': errorMsg && errorMsg.length > 0}"
      :placeholder="placeholder"
      :disabled="disabled"
      :readonly="readonly"
    >
    <p
      v-if="error"
      class="error-msg"
    >
      {{ errorMsg }}
    </p>
  </div>
</template>

<script>
export default {
  props: {
    type: {
      type: String,
      default: 'text',
      required: false
    },
    placeholder: {
      type: String,
      default: '',
      required: false
    },
    id: {
      type: String,
      default: '',
      required: false
    },
    value: {
      type: String,
      default: '',
      required: false
    },
    disabled: {
      type: Boolean,
      default: false,
      required: false
    },
    readonly: {
      type: Boolean,
      default: false,
      required: false
    },
    errorMsg: {
      type: String,
      default: '',
      required: false
    }
  },
  emits: ['update:value'],
  data() {
    return {
      userId: '',
      internalValue: ''
    }
  },
  computed: {
    error() {
      return this.errorMsg && this.errorMsg.length > 0
    }
  },
  watch: {
    internalValue(val) {
      this.$emit('update:value', val)
    },
    value: {
      immediate: true,
      handler(val) {
        this.internalValue = val
      }
    }
  },
  mounted() {
    this.userId = `field${this._uid}`
  }
}
</script>
 
 

 

 

반응형

'Vue' 카테고리의 다른 글

VSCode 확장 프로그램  (1) 2023.01.22
컴포넌트 import 없이 사용하기 - 전역등록  (0) 2023.01.22
Vue Router v4.x  (0) 2023.01.22
Vuex  (0) 2023.01.22
Vue Application Package 구조  (0) 2023.01.22

관련글 더보기

댓글 영역