Vue.js. v-viewer 라이브러리 소개 와 삽질.

CianJS
13 min readSep 25, 2018

--

이 글은 vue.js의 기초적인 설명(디렉티브, 라이프사이클 등)이 존재하지 않으므로 공부를 조금만 하고 오신다면, 해당 글의 내용을 이해하는데 도움이 되리라 생각합니다.

v-viewer..
이 라이브러리는 대체 뭐고 어디에 쓰이나??
그건 바로..

말 그대로 image viewer인데 vue의 특성을 이용할뿐이다.

내가 이 라이브러리를 소개하는 이유는 사실 소개하려고 적은게 아니라 회사에서 개발도중에 상당히 삽질을 했던 구현방식이 있었다.
이 글에서는 v-viewer 라이브러리의 간단한 사용법과 마지막으로 삽질한 내용에 관해 설명할 것이다.

V-Viewer

v-viewer는 vue 전용의 이미지 뷰어이다.
기능으로는 이미지 확대, 축소, 회전 등을 제공한다.

바로 위의 사진에서 아래에 동그라미들이 보이는가? 저 기능들을 활용할 수 있다.

추가로, viewer.js 기반인데.. 링크를 참조하자.

V-Viewer로 갤러리 만들기!

v-viewer가 무엇인지 간단히 설명하였다.

그럼 이제 v-viewer로 간단한 갤러리를 만들어볼 것이다.

최종 결과물은 아래 사진과 같은데.. 생각한 것과 다르다면, 실망하지말고 사용법 습득에 집중하자.. 디자인과 내용 구성의 부족함에 먼저 사죄를..ㅠㅠ

이미지는 여기서 받아왔다.

자, 여기까지 읽고 나서 이 글을 나가지 않은분들을 위해 이제 슬슬 vue.js 개발을 시작하도록 하겠다

> npm i vue-cli
> vue create vuejs_viewer

vue-cli의 기능을 이용하기 위해서는 사용하려는 것은 아니지만, 프로젝트의 기분(?)을 내기 위함뿐아니라 게속해서 만들어나가며 규모를 불리기 좋으므로 사용한다.

> cd vuejs_viewer
> npm run serve or dev

프로젝트를 실행시켜보면 모두가 익숙한 vuejs 화면이 보일 것 입니다.

그럼 이제 여러분은 개발할 준비가 완료된 것이다!
우리가 이 프로젝트에서 사용할 라이브러리는 v-viewer다.
vue-cli에는 v-viewer 라이브러리가 포함되어 있는 것이 아니므로 설치한다.

> npm i v-viewer
> npm ls v-viewer
vuejs_viewer@0.1.0 /Users/Erwinousy/git/vuejs_viewer
└── v-viewer@1.2.1

자, 1.2.1버전으로 v-viewer가 설치되었다.

그 다음으로 우리가 할 것은 vuejs를 공부해오며 무지하게 많이 보아왔던 HelloWorld.vue를 HelloViwer.vue로 대체하는 일입니다. ㅎㅎ

아, 그전에 src/main.js에서 설치한 v-viewer먼저 사용할 수 있게 만들도록하자.

src/main.js

import Vue from 'vue'
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css' # 1
Vue.use(Viewer)

여기서 #1이 어찌보면 제일 중요합니다.

Viewer라는 이름으로 가져온 v-viewer는 우리가 v-viewer를 사용하기 위해 불러온것이지만 이미지 뷰어의 화면이 (#1)에 들어있습니다.

필자는 사실 저것을 안불러왔다가 이미지가 아니라 list를 표시하는 동그라미들만 보았다..

App.vue

<div id="app">
<HelloViewer />
</div>
<script>
import HelloViewer from './components/HelloViewer.vue'
...
components: {
HelloViewer
}
</script>

HelloViewer.vue

<template>
<div class="hello">
<!-- img tag를 이용한 일반적인 Image 생성. -->
<header class="logo">
<img src="../assets/welcome_logo.gif"/>
</header>
<!-- v-viewer를 이용한 Image 생성. -->
<viewer :images="this.images">
<img class="gallary_image" v-for="image in this.images" :src="image" :key="image" />
</viewer>
<footer>This is a Footer.</footer>
</div>
</template>
...
name:'HelloViewer',
data() {
return {
images: [
'https://images.pexels.com/photos/67636/rose-blue-flower-rose-blooms-67636.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260',
'https://images.pexels.com/photos/93684/pexels-photo-93684.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260', 'https://images.pexels.com/photos/414612/pexels-photo-414612.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260', 'https://images.pexels.com/photos/1073567/pexels-photo-1073567.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260', 'https://images.pexels.com/photos/35884/amazing-beautiful-beauty-blue.jpg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260'
]
}
}
...

자, 여기까지 왔다면 화면에서 대략적인 화면이 만들어졌으리라 예상합니다.

이렇게 되었나?

자, 이제 그림들을 눌러보도록하자.

어떻게 되었나? 다 만들었다. ㅎㅎ

사실 v-viewer의 사용법은 순서대로 말하본다면 이렇습니다.

v-viewer 사용(Vue.use()) -> viewer 컴포넌트에 이미지 배열을 집어넣고, img for문을 돌린다.

별 내용이 없어서 실망했을지도 모르지만, 생각보다 간단합니다.

그래도 여기서 그냥 끝내버리면 재미가 없으니 v-viewer의 option과 method를 한번씩 끝내고 필자가 삽질했던 부분을 잠시 살펴보고 끝내도록하겠습니다.
(저는 긴 내용을 싫어하기때문에.. ㅎㅎ)

v-viewer의 Option들

우선 출처부터 남겨놓도록 하겠습니다. 그 이유는 이 글에서 소개할 option은 4개 밖에 없으니..
하지만 v-viewer를 사용하려는 분들 중에서 반드시 사용할 것같은 option들로 추려놓았습니다.

출처 : https://github.com/fengyuanchen/viewerjs#options

만약 출처를 읽으신 분들은 패스하셔도 무방합니다. ㅎ

HelloViewer.vue

options

option: Title

위 options들에서 title을 먼저 설명하겠습니다.

title은 viewer. vue의 이미지 뷰어에서 이미지의 제목을 의미합니다.
위 코드처럼 function함수로 작성할 수 있고, 0(false), 1(true)로 제목이 있고, 없고를 정할 수 있습니다.

default는 1(true)입니다.

title이 0 또는 false로 설정해두었을때.

option: movable

movable은 이미지를 마우스로 이동시키면서 볼 수 있습니다.

건들지 않으면 화면의 중앙에 이미지가 나타나지만 이미지를 누르고 이동시켜주면 이미지 또한 같이 움직여줍니다.

default는 true이므로 움직이는 것을 원하지않으면 false로 맞춰둬야합니다.

우측 아래로 이미지를 끌어당겨놓은 모습.

option: loop

loop는 viewer의 image를 클릭해서 이미지뷰어 모드로 전환했을때에 좌,우 버튼이나 방향키를 눌렀을때 가장 첫번째에서 마지막 위치로 마지막 위치에서 첫번째로 도는 것을 허가하느냐 못하느냐입니다.

이것은 직접 해보시기를 권장합니다.

initialViewIndex 옵션은 메서드와 함께 설명하겠습니다.

Methods

마찬가지로 출처입니다.

만약에 저처럼 Viewer 컴포넌트를 이용하시는 분들께 주의하셔야할 메서드 inited을 간략히 설명합니다.

<viewer :images="images" :options="options" @inited="inited">
<img v-for="image in images" :src="image" :key="image"
class="gallary_image" />
</viewer>
...
inited(viewer) {
this.$viewer = viewer;
}

위 코드는 viewer에 inited=”inited”을 추가한 것과 this.$viewe에 할당한 것밖에 없지만, 위 viewer 컴포넌트에서 메서드를 사용하려면 이렇게 해주어야한다고 한다..

저는 이 사실을 전혀 모르고 view()를 구현했다가 바로 삽질행 기차를 타고 가버려서…

역시 문서를 자세히 읽어봐야겠다는 생각을 하게 되었다.

view()

<input type="text" v-model="idx" @keyup.enter="view(idx)"/>
...
view(idx) {
this.$viewer.view(idx);
}

view 메서드는 image들의 index를 넘겨주면 그 위치에 해당하는 image가 뷰어로 전환이 된다.

show()

show 메서드는 view와 매우 비슷한데, 다른 점은 이전에 눌렀던 image가 viewer로 전환이 된다는 점이다.

만약 페이지를 불러오고 가장먼저 show() 메서드를 불러오게 된다면 가장 첫번째 이미지가 뷰어로 전환이 되는데 이는 initialViewIndex 옵션으로 바꿀 수있다.

initialViewIndex는 defalut가 0으로 설정되어있어서 첫번째 이미지가 불러와지는 것이다.

initialViewIndex를 1이나 2로 하면 두번째, 세번째로 바뀐다.

Front에서 보여지는 그림을 3개만하자! (삽질…)

위의 소제목이 내가 한 삽질의 목표였다.

그 삽질에는 위에 적어놓았지만 inited을 해주지 않았던 내용도 이 삽질에 포함되었다.

삽질 완성본 링크: https://github.com/Elgashia/vuejs_v-viewer/commit/73db51cae2fd2bd95a3e26f792c97b73c434ec8a

우선 결론부터 말하자면, 문서를 잘 읽자. 가 이번 삽질을 통해 얻은 깨달음이다.

내가 정확히 어떤 삽질을 했느냐?

가장 먼저한 삽질은 images 배열을 viewer에 넘기고 viewer 컴포넌트 밑의 img 태그에 이미지를 3개만 넘겨주면 되겠지? ㅎㅎ 라고 생각하여

images: [전체 이미지를 가지고 있는 배열],
images2: [이미지 3개가 든 배열]

위처럼 구성하여 images2를 아래처럼 하였다.

<viewer :images="images" :options="options" @inited="inited">
<img v-for="img in images2" :src="img" :key="img"
class="gallary_image" />
</viewer>

viewer의 :images에 전체 이미지를 넣고 img에만 3개만 든 이미지 배열을 넘겨주면 화면에 3개만 보여지고 눌렀을때에는 전부다 볼 수 있을거라고 생각했다.

갤러리 프로젝트라는 이름으로 만든 작은 프로젝트에 저렇게 코드를 작성한다면, 의도한대로 나온다.
그러나 어째서인지 회사의 프로젝트 코드 내에서는 전혀 되질않는다.

그래서 생각해낸 방법이 ‘더미’를 만드는 것이다.

여기서 더미란 무엇이느냐하면 전체 이미지를 담은 viewer 컴포넌트의 style을 display:none;으로 안보이게 해놓고 3개만 출력해주는 img태그를 따로 만들어 두는 것이다.(v-if:false로 한다면 viewer가 렌더링되지 않는다는 사실을 깨달아서 포기..)

그렇게 생각한대로 코딩을 시작했으나 어째서인지

Uncaught TypeError: Cannot read property ‘view’ of undefined

위 에러가 발생하여 왜 view 메서드를 읽을 수 없는지 뒤지다 뒤지다가 발견한것이

viewer의 view()메서드를 사용하기 위해서 위 코드의 inited을 사용하는 것이다.

그 후에 성공한 더미 코드는 바로 아래와 같다.

<img class="gallary_image" @click="view(idx)" v-for="(image, idx) in images2" :src="image" :key="image" />
<viewer :images="images" :options="options" @inited="inited">
<img v-for="image in images" :src="image" :key="image"
class="hide" />
</viewer>
...
.hide {
display:none;
}

이렇게 더미 image에 view 메서드를 이용해서 클릭한 이미지의 index로 원본 viewer에 접근시켜놓으니 의도한대로 코드가 작성이 되었다.

거의 하루를 날리고서 작성한 코드다..

사실 뭔가 조금 더 구조를 파악하고 코딩을 했어야했다는 생각이 든다.
가장 처음에 의도했던 viewer에 전체 image 배열, img 태그에 보여줄 image 배열을 넣는 방법에서 왜 안되는 것인지 파악을 좀 더 했다면 조금 더 깔끔했으리라 생각하지만..

마무리는 어설펐다는 생각이 들지만 아무튼 여러 아쉬움과 시야가 부족함을 깨닫는 나름대로 귀중한 시간이었다고 생각한다..

머릿속이 뒤죽박죽이라서.. 나중에 보면 분명 빈틈이 많은 글이라 생각하지만
해당 글의 수정은 하지 않으려한다.
그 이유는 과거의 잔재를 보면서 내가 부족했던 것들이 무엇이었는지를 돌이켜볼 수 있는 귀중한 자료로서 남겨두려하기 때문이다.

대신 부족함많은 이 글을 읽어주시는 분들께서 제가 무엇이 부족한것 같은지 등등 제게 도움이 될만한 조언들을 적어주시면 감사하겠다는 말을 끝으로 이 글을 마치도록 하겠습니다.

해당 글의 github: https://github.com/Elgashia/vuejs_v-viewer

--

--

CianJS
CianJS

Written by CianJS

영어랑 영문서 자유롭게 듣고 읽고 싶다..

No responses yet