[Vue.js] 변수 초기화 시 주의할 점

이맑음·2021년 11월 26일
0
post-thumbnail

Bootstrap invalid-feedback 적용 중 발견한 오류

  • 전에 서버에서 axios로 데이터를 가져와서, item이라는 변수에 담아 테이블(계정 정보 리스트)에 보여주고, 모달(선택한 계정 정보)로 보여주는 기능까지 완료하였다.
  • 모달은 계정 정보를 수정하는 페이지로 bootstrap의 b-form-group을 사용하여 페이지를 그렸는데, 공식문서에 따르면 유효성 검사를 지원해준다고 한다.

    Form group
    The component is the easiest way to add some structure to forms. Its purpose is to pair form controls with a legend or label, and to provide help text and invalid/valid feedback text, as well as visual (color) contextual state feedback.

  • b-form-group에 state, invalid/valid-feedback을 사용하면 input에 유효하지 않은 값을 입력시 바로 아래에 경고 문구를 보여주는 기능이다.

작성한 코드

<b-form-group
    id="nameGroup"
    label-cols-sm="3"
    label="이름"
    label-for="AccountNmGroup"
    :state="nameState"
    :invalid-feedback="nameInvalidFeedback"
    >
         <b-form-input
              id="AccountNmGroup"
              v-model="userInfo.accountNm"
              :state="nameState"
         >
         </b-form-input>
</b-form-group>
...생략...
computed: {
  nameState() {
    this.testconsoleLog();
    return this.userInfo.accountNm.length >= 2;
  },
  nameInvalidFeedback() {
    if (this.userInfo.accountNm.length > 0) {
      return "최소 2글자 이상 입력해야 합니다.";
    }
    return "이름을 정확히 입력해 주세요.";
  },

코드를 작성하고 실행

  • 콘솔창 : 한 글자씩 지울때마다 nameState()의 testconsoleLog()에 걸려 콘솔에 찍힌다.
  • 모달 : nameState()에서 false를 리턴했으므로 당연히 nameInvalidFeedback이 실행된다.
  • pr보내기 전에 확인할 겸, 사진처럼 계속 첫번째 행(홍길동)으로 확인하다가 아무생각 없이 세번째 행(이맑음)으로 확인하니
  • 콘솔창 :
  • 모달 :
  • 처음 이름에 대해서는 nameState()가 동작하지만, 이후 변화에 대해서는 동작하지 않았다.

서버에서 가져온 데이터를 저장할 때 문제 발생

for (var i = 0; i < this.account.length; i++) {
    this.item.accountNm = this.account[i].accountNm;
    this.items.push(this.item);
    this.item = {};
}

items 확인

  • 전체 리스트 : 클릭해서 보기 전에도 이미 0번과 1,2번의 형태가 달랐다.
  • 0번(홍길동) 클릭 시 get, set 메서드가 있지만, 1,2번은 내가 정의한 item 속성 뿐이다.
  • 반복문 마지막마다 item={};을 해서 item을 초기화 시켜줬다고 생각했는데, 형태가 자유로운 js 특성상 문제가 된 것 같다.----->추후에 보강 필요

해결 방법

  • 반복문 안에서 전역변수 item을 사용하는 것이 아닌, 지역변수 let으로 선언하여 사용하면 된다.

나름의 보강

Observer

  • 뷰에서 데이터가 변경되면 자동으로 웹페이지를 업데이트한다.
  • 뷰 공식문서에 따르면 뷰는 자바스크립트 객체를 data옵션으로 전달하면, 모든 속성에 Object.defineProperty를 사용하여 getter/setter로 변환한다고 한다.

    How Changes Are Tracked
    When you pass a plain JavaScript object to a Vue instance as its data option, Vue will walk through all of its properties and convert them to getter/setters using Object.defineProperty. This is an ES5-only and un-shimmable feature, which is why Vue doesn’t support IE8 and below.

  • (내가 이해한 선에서) 간단히 말하자면 observer의 getter/setter가 있어야 뷰에서 데이터 변경을 감지할 수 있다는 이야기이다.
  • 다시 콘솔창의 결과를 보면, 1번째 객체는 observer 밑에 속성이 들어가 getter/setter가 정상적으로 생성되었는데, 2번째 객체는 observer와 동일한 선상에 속성이 들어가 getter/setter가 생성되지 않았다. 즉 observer가 데이터 변경을 감지할 수 없는 객체로 생성되었다는 것이다.
  • 위에처럼 let을 사용한 지역변수로 선언해도 되지만, this.item.id로 속성값을 주는 것이 아닌 아래와 같이 json 형식으로 값을 주어도 내가 의도한대로 실행시킬 수 있다.
  methods: {
    test() {
      this.item = {
        id: "1",
        name: "one",
      };
      console.log(this.item);

      this.item = {
        id: "2",
        name: "two",
      };
      console.log(this.item);
    },
  },

결론

  • 뷰에서 속성값을 줄때 this.item.id="" 형태가 아닌, this.item={id:""} 형태로 주어야 제대로 된 객체를 만들 수 있다.
  • js도 잘모르고, 뷰도 잘모르는 상태라 한 삽질이다.ㅠ
profile
하삐

0개의 댓글