뷰(Vue)

Vue3에서 i18n(다국어) 적용하기..!

뭘하지 2024. 1. 15. 16:41
반응형

I18n이란?

그저 국제화란 뜻입니다. 국제화와 현지화는 출판물이나 하드웨어 또는 소프트웨어 등의 제품을 언어 및 문화권 등이 다른 여러 환경에 대해 사용할 수 있도록 지원하는 것을 의미한다.

 

다음과 같이 I18n을 설치 및 적용하는 것에 대해서 정리하였다.

vue-i18n 를 설치하면 Vue 2버전을 기준으로 동작한다.

 

Vue3의 경우에는..?

공식문서주소

Vue I18n | Vue I18n

 

Vue I18n

Vue I18n Internationalization plugin for Vue.js Easy, powerful, and component-oriented for Vue.js

vue-i18n.intlify.dev

공식홈페이지에서의 기준은 9버전인듯함.

 

설치

npm install vue-i18n@9

main.js

사용을 위한 기본 세팅.

import { createApp } from 'vue'
import { createI18n } from 'vue-i18n'

const i18n = createI18n({
  // something vue-i18n options here ...
})

const app = createApp({
  // something vue options here ...
})

app.use(i18n)
app.mount('#app')

간단 사용법 블로그 참고(또는 공식홈페이지)

[vue] 다국어 처리 (vue-i18n)

 

[vue] 다국어 처리 (vue-i18n)

개요 이전에 진행했던 vue 프로젝트에 다국어 처리가 필요해졌다. 다국어 처리는 웹 브라우저를 사용하는 국가에 따라 다양한 언어 등을 지원하게 만드는 것이다. 찾아보니 vue에서는 vue-i18n 라이

velog.io

 

실질적으로 내가 테스트하는 사이트에 적용한 방법은 다음과 같았다.

ko.json과 en.json파일을 생성하였다.

{
  "button": {
    "search": "조회",
    "new": "추가",
    "save": "수정",
    "delete": "삭제",
    "excel": "엑셀",
    "print": "인쇄"
  },
  "validation":{
    "string": "{field} 항목에는 글자를 입력해야합니다.",
    "alpha": "{field} 항목에는 영문자만 사용할 수 있습니다",
    "alpha_dash": "{field} 항목에는 영문자, 숫자, 대시(-)와 언더스코어(_)만 사용할 수 있습니다",
    "alpha_num": "{field} 항목에는 영문자와 숫자만 사용할 수 있습니다",
    "alpha_spaces": "{field} 항목에는 영문자와 공백만 사용할 수 있습니다",
    "between": "{field} 항목의 값은 {min}에서 {max} 사이여야 합니다",
    "confirmed": "{field} 항목의 값이 일치하지 않습니다",
    "digits": "{field} 항목의 값은 {length}자리의 숫자여야 합니다",
    "dimensions": "{field} 항목의 크기는 가로 {width}픽셀, 세로 {height}픽셀이어야 합니다",
    "email": "{field} 항목의 값은 유효한 이메일 형식이어야 합니다",
    "ext": "{field} 항목은 유효한 파일이 아닙니다",
    "image": "{field} 항목은 이미지 파일이어야 합니다",
    "integer": "{field} 항목의 값은 정수여야 합니다",
    "length": "{field} 항목의 길이는 {length}글자여야 합니다",
    "max_value": "{field} 항목의 값은 {max} 이하여야 합니다",
    "max": "{field} 항목은 최대 {length}글자 이하여야 합니다",
    "mimes": "{field} 항목은 유효한 파일 형식이 아닙니다",
    "min_value": "{field} 항목의 값은 {min} 이상이어야 합니다",
    "min": "{field} 항목은 최소 {length}글자 이상이어야 합니다",
    "numeric": "{field} 항목에는 숫자만 사용할 수 있습니다",
    "regex": "{field} 항목은 형식에 맞지 않습니다",
    "required": "{field} 항목은 필수 입력 항목입니다",
    "size": "{field} 항목의 크기는 {size}KB보다 작아야 합니다",
    "url": "{field} 항목은 유효한 URL이 아닙니다"
  },
  "label": {
    "common": {
      "all": "전체",
      "select": "선택"
    }
  }
}

en.json

{
  "button": {
    "search": "search",
    "new": "new",
    "save": "save",
    "delete": "delete",
    "excel": "excel",
    "print": "print"
  },
  "validation": {
    "string":"The {filed} is required a string",
    "alpha": "The {field} field may only contain alphabetic characters",
    "alpha_num": "The {field} field may only contain alpha-numeric characters",
    "alpha_dash": "The {field} field may contain alpha-numeric characters as well as dashes and underscores",
    "alpha_spaces": "The {field} field may only contain alphabetic characters as well as spaces",
    "between": "The {field} field must be between {min} and {max}",
    "confirmed": "The {field} field confirmation does not match",
    "digits": "The {field} field must be numeric and exactly contain {length} digits",
    "dimensions": "The {field} field must be {width} pixels by {height} pixels",
    "email": "The {field} field must be a valid email",
    "ext": "The {field} field is not a valid file",
    "image": "The {field} field must be an image",
    "integer": "The {field} field must be an integer",
    "length": "The {field} field must be {length} long",
    "max_value": "The {field} field must be {max} or less",
    "max": "The {field} field may not be greater than {length} characters",
    "mimes": "The {field} field must have a valid file type",
    "min_value": "The {field} field must be {min} or more",
    "min": "The {field} field must be at least {length} characters",
    "numeric": "The {field} field may only contain numeric characters",
    "regex": "The {field} field format is invalid",
    "required": "The {field} field is required",
    "size": "The {field} field size must be less than {size}KB",
    "url": "The {field} field is not a valid URL"
  },
  "label": {
    "common": {
      "all": "all",
      "select": "select"
    }
  }
}

 

그리고 그걸 사용할 i18n.js 파일 생성

import { createI18n } from 'vue-i18n';
import en from '@/locales/en.json';
import ko from '@/locales/ko.json';

export const i18n = createI18n({
    locale: 'ko',
    fallbackLocale: 'en', // 기본 언어 표시에 문제가 있을 경우 대체할 언어
    legacy: false, // script에서 사용하려면 해당 옵션값 false
    messages: { en, ko },
});

main.js파일 내용

// vue-i18n plugin
import { i18n } from '@/plugin/i18n';

const app = createApp(App);
app.use(i18n);
app.mount('#app');

 

언어 선택의 경우 primeVue에서 제공하는 기본 dropdown에 해당값을 그냥 연동하여 선택 할 수 있도록 했다.

<Dropdown v-model="$i18n.locale" :options="$i18n.availableLocales" :showClear="false"></Dropdown>

이제 i18n값에 따라 아래와 같이 $t변수에 매칭된 값을 가져와서 볼 수 있게된다.

$t('button.delete')

 

만약 script에서 t변수를 사용하고 싶다면 다음과 같이 써야한다.(이후 포스팅할 검증과 함께 사용하는 모습)

//validation
import { useForm } from 'vee-validate';
import * as yup from 'yup';
import { useI18n } from 'vue-i18n';
const { t } = useI18n();
const searchInfoField = '검색';
const { handleSubmit } = useForm({
    validationSchema: yup.object({
        searchInfo: yup
            .string(() => t('validation.string', { field: searchInfoField }))
            .max(5, ({ max }) => t('validation.max', { field: searchInfoField, length: max })), //임시조건
    }),
});

 

반응형