코딩/Javascript

22.09.17 WIL - Api 연동 시 default값 설정 & 체크박스 설정

AMD만세 2022. 9. 17. 15:30

1. Vue

 

 

1. 이번주 배운 내용

1) api 연동할 때 특정 부분에서는 default값 지정이 필요하다.

2) 체크박스 로직 구현.(수신동의 & 수신거부)

 

2. Trouble Shooting

 

1-1) 발단

- Api 연동 시 fetchItem 써서 데이터를 가져왔음.

   콘솔 노출도 해보고 절대 undefined 하지 않은데 페이지 로딩 때 자꾸 undefined 하다고 나옴.

- mounted 디렉티브로 데이터 가져왔는데 페이지가 그려질 때 데이터가 없다보니 undefined라고 뜨는 거임.

- created 디렉티브로 해봤으나 역시 안됨.

- 총 2번 읽는데 처음 읽을 때 'undefined error' 발생하고 그 다음 Get error, 404 error 발생. 

1-2) 해결

- 라이프사이클 훅 참고.

- 데이터에 default 값 아무거나 넣어주니 해결됨.

1-3) Plus

- 부모요소에서 props로 데이터 받아준다.

- 1-2 해결방법으로도 되긴하는데 페이지를 2번 읽어야 함.

----------------------------------------------------

2) 복습 - 체크박스 로직 구현

PageProfile.vue

<!-- PageProfile.vue -->
<template>

<!-- 수신동의 알람 체크박스 -->
<input type="checkbox" name="term"
                 :id="term.id" v-model="formData.isAgreeForAlarm"
                 @click="onClickAgreeForAlarm">
<label class="check-box" :for="term.id" ></label>


<!-- 서비스 및 이벤트 알림 수신 동의 팝업(Quasar Framework 활용) -->
    <q-dialog class="popup-wrapper" v-model="showAgreeForAlarm">
      <q-card>
        <q-card-section class="q-pa-xl text-center" style="min-width: 85vw;">
          <div class="info">{{ currentDate() }} 에 수신 {{ formData.isAgreeForAlarm ? '동의':'거부' }}하셨습니다.</div>
        </q-card-section>

        <q-card-actions
          class="btn-box" align="center">
          <button v-close-popup>
            확인
          </button>
        </q-card-actions>
      </q-card>
    </q-dialog>
    
</template>

<script>
import { defineComponent } from 'vue'
import { useProfileStore } from 'stores/profile'

export default defineComponent({
  name: 'PageProfile',
  components: { HeaderMenu },
  data () {
    return {
      store: useProfileStore(),
      formData: {
        isAgreeForAlarm: false
      },
      showAgreeeForAlarm: false
     }
   },
    async mounted () {
    this.formData = Object.assign(this.formData, {
      ...this.store.$state
    })
    console.log(this.formData)
   },
   methods: {
   onClickAgreeForAlarm () {
      this.formData.isAgreeForAlarm = !this.formData.isAgreeForAlarm
      this.showAgreeForAlarm = true
    }
   }
</script>
<style lang="scss" scoped>
@import "src/css/app.scss";

.input-box {
  @include font-noto-bold;
  @include pd-sm;
  height: 12vw;
  width: 89.3vw;
  margin: 5vw 0;
  padding-top: 0;
  padding-bottom: 0;
  border-top: none;
  border-left: none;
  border-right: none;
  background: transparent;
  border-bottom: 2px solid #EAEAEA;
}

input[type="checkbox"] {
  display: none;
}

input[type="checkbox"] + .check-box {
  display: inline-block;
  width: 20px;
  height: 20px;
  border: 1px solid #727272;
  border-radius: 3px;
  position: relative;
}

input[type="checkbox"]:checked + .check-box::after {
  content: '✔';
  font-size: 14px;
  width: 20px;
  height: 20px;
  text-align: center;
  background: #0dc9ba;
  border: 1px solid #0dc9ba;
  border-radius: 3px;
  color: #fff;
  position: absolute;
  left: -1px;
  top: -1px;
}

.popup-wrapper {
  .info {
    @include font-gmarket;
    @include h4;
    color: #666666;
    letter-spacing: -0.45px;
  }

  .btn-box {
    background-color: #0FC9BB;

    button {
      @include font-gmarket;
      background-color: #0FC9BB;
      width: 100%;
      border: 0;
      color: white;
    }
  }
}

</style>

profile.js

import { defineStore } from 'pinia'
import { account, update, remove } from '../api/auth'

const getDefaultState = () => {
  return {
    cellphone: '',
    username: '',
    passwd: '',
    birthDay: '',
    sex: '',
    isAgreeForAlarm: false,
    accountKey: ''
  }
}

export const useProfileStore = defineStore('profile', {
  state: () => getDefaultState(),

  getters: {},

  actions: {
    initItem () {
      this.$state = getDefaultState()
      return this.$state
    },

    async account (accountKey) {
      const { entity } = await account(accountKey)
      this.$state = entity
      return entity
    },

    async update () {
      const state = this.$state
      const { code, message } = await update(state)
      if (code !== '1') {
        return {
          isCompleted: false,
          message
        }
      } else {
        return {
          isCompleted: true,
          message
        }
      }
    },

    async remove () {
      const state = this.$state
      const { code, message } = await remove(state.accountKey)
      if (code !== '1') {
        return {
          isCompleted: false,
          message
        }
      } else {
        return {
          isCompleted: true,
          message
        }
      }
    }
  },

  persist: true
})

auth.js

import { api } from 'boot/axios'

class AuthApi {
  //
  // 로그인
  //
  login = async (id, pw) => {
    return api({
      url: '/auths',
      method: 'post',
      params: {
        id, pw
      }
    })
  }

  /**
   * @desc 핸드폰 Device 정보 수정
   * @returns object
   * @param data
   */
  info = (data) => {
    return api({
      url: '/auths/info',
      method: 'post',
      data
    })
  }

  //
  // 회원
  //

  // 회원 > 회원정보조회
  account = (accountKey) => {
    return api({
      url: '/accounts/' + accountKey,
      method: 'get'
    })
  }

  // 회원 > 회원정보수정
  update = (data) => {
    return api({
      url: '/accounts/update',
      method: 'post',
      data
    })
  }

  // 회원 > 탈퇴
  remove = (accountKey) => {
    return api({
      url: '/accounts/remove',
      method: 'post',
      data: {
        accountKey
      }
    })
  }
}

const authApi = new AuthApi()
const { login, account, info, update, remove } = authApi

export {
  authApi,
  login, account, info, update, remove
}