본문 바로가기

Web Programming

Vue 학습하기 ④ - bootstrap-vue로 입력창 만들기와 이미지 미리보기

336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

 

 대강 있는 것들을 복붙하면서 만든 페이지 이므로 디자인 같은건 Bootstrap 이 대애충 해주고 있습니다. 이번에 bootstrap-vue를 추가로 사용하면서 연습을 하고 있는데, 본격적으로 wepack 을 통한 vue 파일 빌드와 컴포넌트의 구조화를 적극 활용하기 위해서 다음과 같은 형태로 파일을 구성했습니다. 뭐 꼭 이렇게 까지 해야하나 싶지만...

main.js (시작)
└ App.vue (기본 vue)
 └ VuePetList (사진 목록)
  └ VuePetForm (사진 등록)

 일단 사진 목록에 대한 표현의 방법은 굉장히 쉬웠습니다. 거기에 bootstrap 을 사용하는 방법이 함께 녹아져 있어서 신경써야 할 것들이 많기는 하지만 데이터를 바인딩하는 방법 자체가 굉장히 간단했습니다. 새로운 것들에 대한 배움에 대한 시간이 소비되는 것이지 구현하고자 하는 작업 자체는 굉장히 단순합니다.

 업로드 이미지 Preview 기능을 만들면서 Vue의 장점(?)을 알게 되었는데 그건 바로 값의 업데이트가 이루어지면 즉시 반영되어 렌더링 된다는 점이다. 이런걸 문서에서는 Reactive 라고 표현이 되었는데 일일이 값들의 변경에 따라서 무언가를 만들어주지 않아도 된다는게 큰 장점인 것 같다. 여러 다른 장점들은 아직까지는 체감하기는 어렵고 이게 진짜 괜찮은 점 중에 하나인 것 같다.

      <b-form-group id="input-group-3" label="Choose buddy's picture:" label-for="input-3">
        <b-form-file
          v-model="form.file"
          :state="Boolean(form.file)"
          placeholder="Choose a file..."
          drop-placeholder="Drop file here..."
          required
          accept=".jpg, .png, .gif"
          @change="previewImage"
        ></b-form-file>
        <div class="mt-3">Selected file: {{ form.file ? form.file.name : '' }}</div>
        <div>
          <b-img :src="previewImageData"></b-img>
        </div>
      </b-form-group>
export default {
  data() {
    return {
      form: {
        petName: "",
        file: "",
        desc: ""
      },
      show: true,
      previewImageData: null
    };
  },
  methods: {
    onSubmit(evt) {
      evt.preventDefault();
      alert(JSON.stringify(this.form));
    },
    onReset(evt) {
      evt.preventDefault();
      // Reset
      this.form.petName = "";
      this.form.file = "";
      this.form.desc = "";
      this.show = false;
      this.$nextTick(() => {
        this.show = true;
      });
    },
    previewImage(evt) {
      var input = event.target;

      if (input.files && input.files[0]) {
        var reader = new FileReader();
        reader.onload = e => {
          this.previewImageData = e.target.result;
        };
        reader.readAsDataURL(input.files[0]);
      } else {
          this.previewImageData = null;
      }
    }
  }
};

 previewImageData 라는 항목은 이미 img 태그에 바인딩 되어있다. 평소에는 표시되고 있지 않다가, method에 정의된 previewImage 라는 함수가 실행되면 조건에 따라서 해당 값이 주어지도록 되어있다. 해당 함수는 파일이 추가되거나 바뀌면 수행히 되도록 되어있다. 기존 jQuery를 이용하여 작업했다면 previewImage 쪽에 이미 img 태그를 수정하는 항목이 추가 되었어야 했지만 그렇게 하지 않아도 된다.

이렇게 완성된 버전은 이렇게 동작한다.