본문 바로가기

카테고리 없음

[Nuxt] (mixins 사용법) vue 페이지나 컴포넌트에서 분리된 공통 함수에서 this 사용하기

[Nuxt] Vue 페이지나 컴포넌트에서 분리된 공통 함수 사용하기

 

[Nuxt] Vue 페이지나 컴포넌트에서 분리된 공통 함수 사용하기

제목을 어떻게 지어야할 지 고민이었다. 물론 방법을 찾는 과정에서도 검색어를 뭐라고 해야할지도 고민이었다. 일단 하고싶은건, 로컬 변수를 쓰는 페이지나 컴포넌트 내부에 공통으로 자주

tacit.tistory.com

 

지난번에 작성한 글에서 별도의 파일로 분리한 함수를 사용할 때 컴포넌트나 페이지 내에서 사용되는 지역 변수들을 변경시켜주기 위해서 화살표 함수도 시도해보고, this를 bind도 해보고, plugins 도 사용해보고, localThis로 아예 인자를 통째로 넘겨주기도 해보았다.

 

저번에 했던걸 요약하자면

pages/index.vue

페이지 안에서 사용되는

 

this.phone

this.email

this.name

 

등과 같은 지역 변수들을 정규식 등의 validate (유효성) 검사를 공통함수로 빼서 쓰고 싶었던 것이었다

 

phoneValidate()

emailValidate()

nameValidate()

 

form 에서 자주 쓰이는 항목들(phone, email 등)의 유효성 검증 함수를 vue 파일 내부에서 매번 methods 로 정의해서 사용하면 코드중복이 너무 많았기 때문이다.

 

 

결론적으로 채택하여 사용하는 방법은 mixins 이다

 

Vue에서 mixins은 여러 컴포넌트 간에 공통으로 사용하고 있는 로직, 기능들을 재사용하는 방법이다.

믹스인 안에 정의할 수 있는 재사용 로직은 data, methods, created 등과 같은 컴포넌트 옵션과 동일하다

 

지난번에 정리했던 plugins 방식은 사실상 부적절한 방식이라고 할 수 있겠다.

공통으로 사용되는 스크립트이기는 하지만, 공통 함수를 위한 스크립트는 아니었다.

plugins은 주로 광고 추적용 스크립트를 head에 실어야 할 때 등에 사용하는게 적합한 것 같다.

 

 

mixins 사용예시(1)

- 홈페이지 전체에서 사용되는 공통 모달이 있다.

- 공통 모달을 열기, 닫기 로직을 필요한 페이지마다 각각 method를 정의하는 것이 아니라

- mixins에 한번만 정의를 하고 바로바로 가져다 쓰는 것이다.

 

/mixins/modalMixin.js

export const ModalMixin = {
	data(){
    	return {
        	isModalShow: false
        }
    },
    methods : {
    	showModal(){
        	this.isModalShow = true
        },
        closeModal(){
        	this.isModalShow = false
        }
    }
}

/pages/index.vue

<template>
	<div>
    	<div>안녕하세요</div>
        <ModalComponent v-if="isModalShow"/>
	</div>
</template>

<script>
import { ModalMixin } from '../mixins/modalMixin.js';

export default {
  // ..
  mixins: [ ModalMixin ]
  ...
  }
}
</script>

 


mixins 적용예시

- 잦은 form 페이지 & form 내부 공통적으로 사용되는 validate 함수 공통화

 

 

👉 mixins 파일

📍기능별로 분리도 가능 form-validate 용 함수 모음/ file-service 용 함수 모음 등

📍data에 phone, email 등 데이터도 빼도 되지만, 개취로 vue 파일 내부에서 사용되는 지역 data들은 vue 파일 내부에 data로 있는게 나중에 헷갈리지 않을 것같아서 mixin으로 따로 빼지는 않았다

 

// mixins/form-validate.js

export const formValidate = {
  data() {
    return {}
  },
  methods: {
    emailValidate() {
      this.email = this.email.replace(/[^a-zA-Z0-9@._]*$/gi, '')
      // 이메일 정규식
      const emailRegex = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/
      // 이메일 정규식 부적합
      if (!emailRegex.test(this.email)) {
        this.emailValidation = false
      } else {
        this.emailValidation = true
      }
    },
    phoneValidate() {
      this.phone = this.phoneFormat(this.phone)
      // 휴대폰 정규식
      const phoneRegex = /^\d{2,3}-\d{3,4}-\d{4}$/
      // 휴대폰 정규식 부적합
      if (!phoneRegex.test(this.phone)) {
        this.phoneValidation = false
      } else {
        this.phoneValidation = true
      }
    },
    // 휴대폰 번호 자동 포맷
    phoneFormat(_x) {
      const number = _x.replace(/-/gi, '')
      let tel = ''

      if (number.replace(/[ 0-9 | \- ]/g, '').length) {
        return number.substr(0, number.length - 1)
      }

      // 서울 지역번호(02)가 들어오는 경우
      if (number.substring(0, 2).indexOf('02') === 0) {
        if (number.length < 3) {
          return number
        } else if (number.length < 6) {
          tel += number.substr(0, 2)
          tel += '-'
          tel += number.substr(2)
        } else if (number.length < 10) {
          tel += number.substr(0, 2)
          tel += '-'
          tel += number.substr(2, 3)
          tel += '-'
          tel += number.substr(5)
        } else {
          tel += number.substr(0, 2)
          tel += '-'
          tel += number.substr(2, 4)
          tel += '-'
          tel += number.substr(6)
        }
        // 서울 지역번호(02)가 아닌경우
      } else if (number.length < 4) {
        return number
      } else if (number.length < 7) {
        tel += number.substr(0, 3)
        tel += '-'
        tel += number.substr(3)
      } else if (number.length < 11) {
        tel += number.substr(0, 3)
        tel += '-'
        tel += number.substr(3, 3)
        tel += '-'
        tel += number.substr(6)
      } else {
        tel += number.substr(0, 3)
        tel += '-'
        tel += number.substr(3, 4)
        tel += '-'
        tel += number.substr(7)
      }
      return tel
    }
  }
}

 

👉 vue 파일

📍mixins으로 사용할 파일 import

📍mixins : [] 어레이 안에 사용할 mixin 추가

📍mixins js 안에 정의 되어있는 emailValidate / phoneValidate 함수를 @input 이벤트 호출에서 바로 사용가능!

 

// pages/start.vue

<template>
    <form>
        <div class="email-wrapper">
          <label for="email" class="font-15b form-label">담당자 이메일</label>
          <input
            v-model="email"
            type="text"
            class="form-input"
            :class="{'input-error': !emailValidation}"
            placeholder="example@domain.com"
            maxlength="100"
            required
            @input="emailValidate"
          />
          <p v-if="!emailValidation" class="font-15r warning">올바르지 않은 이메일 형식입니다</p>
        </div>

        <div class="phone-wrapper">
          <label for="phone" class="font-15b form-label">담당자 연락처</label>
          <input
            v-model="phone"
            class="form-input"
            :class="{'input-error': !phoneValidation}"
            type="text"
            placeholder="010-1234-5678"
            maxlength="20"
            required
            @input="phoneValidate"
          />
          <p v-if="!phoneValidation" class="font-15r warning">올바르지 않은 전화번호 형식입니다</p>
        </div>
    </form>
</template>

<script>
import {formValidate} from '~/mixins/form-validate.js'

export default {
  name: 'Start',
  mixins: [formValidate]
  data() {
    return {
      email: '',
      phone: '',
      emailValidation: true,
      phoneValidation: true,
    }
  },
}
</script>