찌읏 홈페이지 프로젝트 후기

조연정·2020년 12월 15일
0

찌읏 홈페이지 프로젝트 후기를 작성해보자.

찌읏 자사 홈페이지 만들기

한 달동안 현업에서 생활해보니 위코드에서 공부했을 때와는 많이 달랐다. 위코드에서 프로젝트를 했을 때에는 딱딱 정해진대로 물흐르듯이 흘러가는 느낌이었다면, 스타트업은 정해진게 없고, 언제든지 계획이 바뀌는구나를 느꼈다. 정해진 계획이 없고, 이것저것 바껴서 처음에는 당황스러웠지만 이게 스타트업이 돌아가는 모습이겠구나 적응해야겠다는 생각이 들었다.

내가 맡은 곳은 자사홈페이지 '서비스 소개'부분이었다. 뷰를 사용해보지 않았다고 해서 그런지 회사에서는 단순한 페이지 하나를 맡기셨다. 뷰를 사용하기 위한 구성이나 뷰에 익숙해지는 시간을 가졌다. 따로 페이지를 더 만들라고 하시지는 않았지만, 뷰를 이용해서 다른 페이지도 만들어보고싶어서 로그인,회원가입을 페이지를 만들었다.
우연히 LoginCritter라는 프로젝트를 알게되었는데 그 기능을 로그인페이지에 꼭 적용해보고싶었다.
LoginCritter란 로그인 정보를 인풋창에 입력하는 동안 캐릭터가 커서를 따라 눈길을 주는 것을 말한다.

서비스소개 페이지


현업에서는 대부분의 데이터를 api통신을 받아온다고 한다. 리액트에서는 fetch함수를 이용해서 데이터를 받아왔었는데 뷰에서는 axios함수를 통해 데이터를 받아온다고 한다.

로그인 페이지

  • LoginCritter
    앞에서 말했듯이 로그인페이지에는 인풋창에 로그인정보를 입력하면 캐릭터의 눈이 커서를 따라가는 loginCritter를 사용해봤다. 내가 직접 디자인을 해야해서 최대한 단순한 캐릭터를 만들었는데 나중에 기회가 된다면 공부해서 좀 더 형태가 갖춰진 캐릭터를 만들어보고싶다.
    캐릭터는 svg를 이용해서 얼굴,몸통, 왼쪽 눈, 오른쪽 눈 각 각 다 만들어줬다. 위치를 조정하는게 은근 노가다(?)여서 오래걸렸던 것 같다.
    크게 글자 수에 따라서 왼쪽 눈의 x,y축 오른쪽 눈의 x,y축을 조정해주는 로직, 글자수가 35자 이상이면 더이상 움직이지 않고, 특정 위치에 고정되는 로직, 비밀번호인풋창을 클릭하거나 탭키로 넘어가면 눈의 위치가 위를 올려다보는 로직이 필요했다.
// Login.vue
<template>
    <form class="loginForm">
        <svg id="figure" viewBox="0 0 120 120">
            <path
                d="M0,150 C0,65 120,65 120,150"
                fill="
                #FAF4E8"
                stroke="black"
                stroke-width="2"
            />
            <circle
                cx="60"
                cy="60"
                r="40"
                fill="#FAF4E8"
                stroke="#000"
                stroke-width="2"
            />
            <g class="eyes">
                <circle :cx="leftEye.x" :cy="leftEye.y" r="5" fill="#000" />
                <circle :cx="rightEye.x" :cy="rightEye.y" r="5" fill="#000" />
            </g>
        </svg>
        <input
            v-model="email"
            type="text"
            placeholder="email"
            @input="adjustLocation"
            @keydown.tab="checkClicked"
        />
        <span class="errorMsg">{{ emailErrMsg }}</span>
        <input
            v-model="password"
            type="password"
            placeholder="Password"
            @click="[checkClicked(), stopEvent()]"
        />
        <span class="errorMsg">{{ passwordErrMsg }}</span>
        <span class="forgetPW">비밀번호를 잊으셨나요?</span>
        <button>로그인</button>
    </form>
</template>
<script>
export default {
    props: ["propsData"],
    data() {
        return {
            email: "",
            emailErrMsg: "",
            password: "",
            passwordErrMsg: "",
            leftEye: { x: 44, y: 55 },
            rightEye: { x: 76, y: 55 },
            isClicked: false
        };
    },
    watch: {
        email: function() {
            const isMail = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
            if (!isMail.test(this.email) && this.email.length) {
                this.emailErrMsg = "올바른 이메일이 아닙니다.";
            } else if (!this.email.length) {
                this.emailErrMsg = "이메일을 입력해주세요.";
            } else {
                this.emailErrMsg = "";
            }
        },
        password: function() {
            if (!this.password.length) {
                this.passwordErrMsg = "비밀번호를 입력해주세요.";
            } else if (this.password.length < 8) {
                this.passwordErrMsg = "8자이상 입력해주세요.";
            } else {
                this.passwordErrMsg = "";
            }
        }
    },
    methods: {
        adjustLocation() {
            const { length } = this.email;
            if (length === 0) {
                this.leftEye.x = 44;
                this.rightEye.x = 76;
                this.leftEye.y = 55;
                this.rightEye.y = 55;
            } else if (length < 20) {
                this.leftEye.x = 34 + length / 2;
                this.rightEye.x = 66 + length / 2;
                this.leftEye.y = 60 + length / 2;
                this.rightEye.y = 60 + length / 2;
            } else if (19 < length && 34 >= length) {
                console.log(length);
                this.leftEye.x = 36 + length / 2;
                this.rightEye.x = 68 + length / 2;
                this.leftEye.y = 80 - length / 2;
                this.rightEye.y = 80 - length / 2;
            } else if (length > 34) {
                this.leftEye.x = 53;
                this.rightEye.x = 85;
                this.leftEye.y = 63;
                this.rightEye.y = 63;
            }
        },
        checkClicked() {
            this.isClicked = true;
            this.leftEye.x = 44;
            this.rightEye.x = 76;
            this.leftEye.y = 38;
            this.rightEye.y = 38;
        },
        resetLocation() {
            this.leftEye.x = 44;
            this.rightEye.x = 76;
            this.leftEye.y = 55;
            this.rightEye.y = 55;
        },
        stopEvent(event) {
            event.stopPropagation();
        }
    }
};
</script>

//Register.vue
export default {
    components: { Login, Signup },
    data() {
        return {
            activeId: 1
        };
    },
    methods: {
        clickTab(id) {
            this.activeId = id;
        },
        detectOutsideClicked() {
            this.$refs.login.resetLocation(); //자식 컴포넌트의 함수를 호출
        },
        
    }
};
  • ref속성: 자식 컴포넌트(Login.vue)의 resetLocation함수를 부모컴포넌트의 전체를 감싸주는 div에 호출하기 위해서 ref를 사용했다. ref속성을 이용해 자식 요소에 레퍼렌스 ID를 할당하여 연결해주어 사용한다.

  • event.stopPropagation 함수: 이벤트의 전파를 막기 위해 사용하는 함수이다. 상위태그에 정의한 detectOutsideClicked함수가 버블링의 영향으로 하위태그에도 영향을 미치게 된다. 비밀번호 인풋창에는 이 함수의 이벤트를 막아야하기때문에 input에 stopPropagation을 사용해주었다.

  • 유효성검사
    리액트에서 한번 구현한 기능이기때문에 비슷할거라고 생각했는데 은근 오래걸린 것 같다. 변하는 값을 캐치해야기때문에 computed와 watch 중 어느 것을 사용해야하나 고민이 들었다.
    watch가 특정 프로퍼티의 변경시점에 특정 액션을 취하고자 할때 적합하다고 해서 watch를 사용했다.

profile
Lv.1🌷

0개의 댓글