- BackEnd API 통신 모듈에 대한 설계 작업이다.
- BackEnd API 응답 형태에 따라 공통 처리 작업을 한다.
- HTTP Status를 항상 200으로 응답한다면, 200일 경우 정상 플로우로 흐르게하고 200이 아닌 경우는 장애 상황 임으로 에러 페이지로 이동시킨다.
- 경우에 따라 레이어 설계가 가능하다.
- 오픈 소스 사용 예:
[사용측]-[BackEnd API 통신 모듈]-[오픈소스]
- fetch API 사용 예:
[사용측]-[BackEnd API 통신 모듈]-[fetch wrapper]-[fetch api]
export default function ({ $axios, redirect }, inject) {
// Create a custom axios instance
const api = $axios.create({
headers: {
common: {
Accept: 'text/plain, */*'
}
}
})
// Set baseURL to something different
api.setBaseURL('https://my_api.com')
$axios.onError(() => {
redirect('/error')
})
// Inject to context as $commonApi
inject('commonApi', {
get: (url, options) => {},
post: (url, options) => {},
delete: (url, options) => {},
put: (url, options) => {}
})
}
export const actions = {
fetchData () {
this.$commonApi
.get(url, options)
.then(() => console.log('Done'))
.catch(() => console.error('Error'))
}
}
- 요구사항에 표현된 HTML Form 엘리먼트 역할, 모달, 토스트 등에 대한 설계 작업이다.
- HTML과 CSS가 변경 예정이라도 요구사항에 맞게 컴포넌트의 Props와 Emit에 대한 설계 가능하다.
- 특히 HTML Form 엘리먼트는 HTML을 사용하는 듯한 사용성을 제공하기 위해 어트리뷰트와 이벤트명을 되도록 똑같이 사용한다.
Vue로 작성한 input[type=text]
예
<common-input :value="subject" @change="onChange" placeholder="제목을 입력해주세요." />
<common-input v-model="subject" placeholder="제목을 입력해주세요." />
기존 문제점: Options API는 이름있는 컴포넌트를 만들지 못함
- 사용측에서 컴포넌트명을 강제적으로 통일하기 힘듬
- IDE상으로 자동 import 기능(Add import statement)을 활용할 수 없음
- IDE 상으로
.vue
를 추가해주지 않으므로 수동으로 추가해야함
-
.vue
확장자는 Vue SFC(Single File Component) 임을 인식하는 규칙
/components/form/index.ts
import BaseCalendar from './calendar.vue';
import BaseCheckbox from './checkbox.vue';
import BaseImage from './image.vue';
import BaseInput from './input.vue';
import BaseRadio from './radio.vue';
import BaseSelect from './select.vue';
import BaseTextarea from './textarea.vue';
export {
BaseCalendar,
BaseCheckbox,
BaseImage,
BaseInput,
BaseRadio,
BaseSelect,
BaseTextarea
};
import {defineComponent} from '@vue/composition-api';
import {BaseImage} from '~/components/form';
export default defineComponent({
components: {
BaseImage,
},
});
- IDE상으로 자동 import 기능(Add import statement)을 활용 가능
- 컴포넌트 import 시,
.vue
확장자 누락 방지
-
<template>
에서 props와 state의 구분이 필요
- ref와 reactive 같이 사용 시 혼란.
- 컴포지션 함수(
useXXX
)를 여러개 사용 시, state 명 대응 방안.
-
<template>
에서 props와 state의 구분이 필요
- ref와 reactive 같이 사용 시 혼란.
-
ref
와 reactive
의 타입 변환없이, reactive
만 사용
-
reactive
의 변수명은 state
로 통일
export default defineComponent({
props: {
value: null,
item: null,
disabled: Boolean,
name: String,
id: String,
},
setup (props, context) {
const state = reactive({
checked: computed(() => props.value === props.item),
});
const onChange = () => {
context.emit('input', props.item);
};
return {state, onChange};
},
});
<template>
<div>
<input
:id="id"
:name="name"
type="radio"
:checked="state.checked"
:disabled="disabled"
@change="onChange"
>
</div>
</template>
export const useCommonInputForm = (props: CommonInputFormProps, context: SetupContext) => {
const state = reactive({
input: props.value || '',
length: computed(() => state.input.length),
});
const emitInput = () => {
context.emit('input', state.input);
context.emit('change', state.input);
};
return {state, emitInput};
};
- 컴포지션 함수(
useXXX
)를 여러개 사용 시, state 명 대응 방안.
- 네이밍 고민은 스트레스임
- 그러므로
useXXX
의 네이밍 기반으로 state
네이밍 변경
-
useCommonInput
=> commonInputState
-
useModal
=> modalState
const {
state: commonInputFormState,
emitInput
} = useCommonInputForm(props, context);
-
reactive
사용 시, TemplateRef 미동작
-
ref
사용 시, TemplateRef 동작
- TemplateRef 사용은
ref
로만 처리