반응형

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

 

 

728x90
반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기