0. 목적
-. 커뮤니티 기능을 위해 간단한 게시판 (bbs)을 만든다.
-. 입력된 텍스트 (제목 / 본문)에 유효성 확인(validation)을 적용한다.
-. front-side (vue.js) 와 server-side (flask) 각각 진행함.
1. front-side validation (vue.js: vee-validate)
1) vee-validate 설치 & 임포트
-. vue-cli의 plugin으로 설치할 순 없고, 공식 페이지에 나와있는 대로 npm으로 설치하고 import 해야한다. 나는 vee-validate 중 useField, useForm 두가지만 사용할 예정.
npm install vee-validate --save
import { useField, useForm } from 'vee-validate'
-. 앞 포스팅에서 만든 게시판에서 form에 들어가있는 각 항목의 v-model이 조금 바꼈다.
v-model: article.XXX -> XXX 로 변경
<form class="write-form" @submit.prevent="submit">
<label class="writer-label">writer</label>
<input v-model="writer"
type="text"
placeholder="writer"
class="writer">
<label class="password-label">password</label>
<input v-model="password"
type="password"
placeholder="password"
class="password">
<div class="category">
<select class="select-box" v-model="category">
<option>잡담</option>
<option>정보</option>
<option>질문</option>
<option>요청</option>
</select>
</div>
<label class="title-label">Title</label>
<div class="title">
<input v-model="title"
type="text"
placeholder="Title"
class="inputfield">
</div>
<label class="description-label">Description</label>
<div class="description">
<textarea v-model="description"
placeholder="description"
class="inputfield"/>
</div>
<button class="submit" type="submit">submit</button>
</form>
2) vee-validate 적용
-. vee-validate는 useField로 v-model의 값을 불러오고, useForm으로 form 전체에 대한 검증을 관리한다.
-. useField로 호출된 각 값에 대해 정해진 if 구문에 따른 참/거짓을 판단하고 거짓일 경우 (true가 아닐 경우) return 값으로 error message를 뿜어내게 된다.
setup () {
const required = value => {
const requiredMessage = '빈 칸을 채워주세요.'
if (value === undefined || value === null) return requiredMessage
if (!String(value).length) return requiredMessage
return true
}
const minLength = (number, value) => {
if (String(value).length < number) return '최소 ' + number + ' 글자를 입력해주세요.'
return true
}
const maxLength = (number, value) => {
if (String(value).length > number) return '최대 ' + number + ' 글자까지 입력할 수 있습니다.'
return true
}
const anything = () => {
return true
}
const validationSchema = {
writer: value => {
const req = required(value)
if (req !== true) return req
const min = minLength(2, value)
if (min !== true) return min
const max = maxLength(10, value)
if (max !== true) return max
return true
},
password: value => {
const req = required(value)
if (req !== true) return req
const min = minLength(3, value)
if (min !== true) return min
const max = maxLength(100, value)
if (max !== true) return max
return true
},
category: required,
title: value => {
const req = required(value)
if (req !== true) return req
const min = minLength(3, value)
if (min !== true) return min
const max = maxLength(30, value)
if (max !== true) return max
return true
},
description: value => {
const req = required(value)
if (req !== true) return req
const min = minLength(20, value)
if (min !== true) return min
return true
}
}
const { handleSubmit, errors } = useForm({
validationSchema,
initialValues: {
category: '잡담'
}
})
const { value: category } = useField('category')
const { value: writer } = useField('writer')
const { value: password } = useField('password')
const { value: title } = useField('title')
const { value: description } = useField('description')
const submit = handleSubmit(values => {
console.log('submit', values)
})
return {
category,
writer,
password,
title,
description,
submit,
errors
}
},
3) error message 출력
-. 각 field에 대해 errors.field 형태로 에러메시지를 출력할 수 있고, 난 그것을 툴팁 형태로 화면에 띄워주기 위한 form 수정을 했다.
<form class="write-form" @submit.prevent="submit">
<label class="writer-label">writer</label>
<input v-model="writer"
type="text"
placeholder="writer"
class="writer">
<div v-if="errors.writer" class="writer tooltip">{{errors.writer}}</div>
<label class="password-label">password</label>
<input v-model="password"
type="password"
placeholder="password"
class="password">
<div v-if="errors.password" class="password tooltip">{{errors.password}}</div>
<div class="category">
<select class="select-box" v-model="category">
<option>잡담</option>
<option>정보</option>
<option>질문</option>
<option>요청</option>
</select>
</div>
<label class="title-label">Title</label>
<div class="title">
<input v-model="title"
type="text"
placeholder="Title"
class="inputfield">
</div>
<div v-if="errors.title" class="title tooltip">{{errors.title}}</div>
<label class="description-label">Description</label>
<div class="description">
<textarea v-model="description"
placeholder="description"
class="inputfield"/>
</div>
<div v-if="errors.description" class="description tooltip">{{errors.description}}</div>
<button class="submit" type="submit">submit</button>
</form>
/* CSS */
.tooltip {
z-index: 2;
position: relative;
left: 3rem;
height: 1.2rem;
width: fit-content;
block-size: fit-content;
align-items: center;
font-size: 0.7rem;
color: red;
pointer-events: none;
background-color: yellow;
}
4) front-side validation 결과
-. 이것으로 front-side validation은 끝.
2. server-side validation (python, flask)
-. vue의 validation은 결국 웹페이지를 통해 정상적으로 입력하는 경우에만 적용되는 것이고, 브라우저에 노출되는 api 단말을 통해 직접 입력을 하는 경우 validation 과정을 전혀 거치지 않기 때문에 서버단에서도 간단하게 validation을 해줘야 한다. 아래 구문을 추가하는 것으로 간단하게 완료.
items = ['writer', 'password', 'category', 'title', 'description']
for each in items:
if params.get(each) is None:
return 'invalid', 201
writer = params.get('writer')
if (len(writer) < 2) or (len(writer) > 10):
return 'invalid', 201
password = params.get('password')
if (len(password) < 3) or (len(password) > 100):
return 'invalid', 201
category = params.get('category')
if category not in ['잡담', '정보', '질문', '요청']:
return 'invalid', 201
title = params.get('title')
if (len(title) < 3) or (len(title) > 30):
return 'invalid', 201
description = params.get('description')
if (len(description) < 3) or (len(description) > 30):
return 'invalid', 201
'Web' 카테고리의 다른 글
[vue.js + Flask + dynamodb] 게시판 만들기 (1) - 글 작성/출력기능 (0) | 2022.02.09 |
---|---|
[NGINX] proxy_pass 사용 시 클라이언트 아이피 전달 및 확인 (0) | 2021.12.12 |
KAKAO API - 카카오 인증 (KAKAO auth) (0) | 2021.03.30 |
[web] 반응형 테이블 만들기 - css grid (0) | 2021.03.19 |
[Web] 네이버 주식시세 가져오기 시도중 (1) | 2021.03.05 |
최근댓글