우리는 한다, 개발을.

VUE3를 사용한다면 VUEUSE

⌛ 8 mins

패널허브 V3 프로젝트 작업에서 패스워드 입력 작업 시 Caps Lock 키의 활성화 여부를 사용자에게 알려주기 위해 Vue3에서 키동작에 관한 라이브러리를 찾아보고 있었습니다.

보통 자바스크립트에서 지원하는 getModifierState(’CapsLock’) 함수를 사용하여 키 활성화 여부를 확인합니다.

<template>
  <h1>Not Vueuse</h1>
  <input class="input-item" @keydown="checkCapsLock" v-model="inputMessage"/>
  <div> </div>
</template>

<script lang="ts" setup>
import {ref} from "vue";

const message = ref('');
const inputMessage = ref('');

const checkCapsLock = (event) => {
  const capslock = event.getModifierState('CapsLock');
  if(capslock) message.value = 'Caps Lock 활성화';
  else message.value = '';
}
</script>

그런데 어느 블로그 글에서 VueUse 라는 라이브러리를 사용한 방법을 제시한 것을 보고 VueUse 문서를 찾아보게 되었습니다.

https://vueuse.org/

VueUse는 Vue.js 애플리케이션을 개발할 때 사용할 수 있는 유틸리티 함수 및 컴포지션 API의 커뮤니티 기반 라이브러리입니다. VueUse는 여러 종류의 플러그인을 제공하여 Vue.js 애플리케이션을 개발하는 과정을 훨씬 더 쉽고 효율적으로 만들어줍니다.

Vue2, Vue3에서 둘 다 지원을 하고 있는데 저는 Vue3로 작업을 하면서 처음 써본 거 같습니다. 공식 문서를 확인하면 아주 다양한 기능을 지원하고 있는데 그 중 제가 구현할 기능을 위해서는 useKeyModifier() 함수를 사용하게 되었습니다.

<template>
  <h1>Vueuse</h1>
  <input class="input-item" @keydown="checkCapsLock" v-model="inputMessage"/>
  <div> </div>
</template>

<script lang="ts" setup>
import {ref} from "vue";
import {useKeyModifier} from "@vueuse/core";

const message = useKeyModifier('CapsLock');
const inputMessage = ref('');

</script>

VueUse 라이브러리를 사용하여 코드 길이가 줄어든 것을 확인할 수 있습니다.

이 외에 VueUse는 CSS애니메이션, 브라우저, 컴포넌트 등의 유용한 헬퍼를 Use함수로 제공하고 간단한 유틸리티 뿐만 아니라, 파이어베이스, Axios, 쿠키, QR, 로컬 스토리지, 브라우저, RxJS, 애니메이션, 지리 위치, 표준 Vue 훅을 위한 익스텐션, 미디어 플레이어 등처럼 다양한 기능과의 복잡한 연계 또한 지원합니다.

이런 다양한 기능의 VueUse함수를 몇 가지 소개해드리려고 합니다.

useStorage / createGlobalState

useStorage함수는 window.localStorage에 데이터를 저장합니다. 글로벌 스토리지를 생성하는 createGlobalState와 함께 사용하면 데이터는 자동으로 저장, 업데이트, 삭제되고 페이지를 새로고침 해도 사라지지 않습니다.

<template>
  <h1>Vueuse</h1>
	<div>
    <input v-model="state.name" type="text">
    <input v-model="state.color" type="text">
    <input v-model="state.size" type="text">

    <pre lang="yaml"></pre>
  </div>
</template>

<script lang="ts" setup>
import {useStorage, createGlobalState} from "@vueuse/core";

const useState = createGlobalState(() =>
    useStorage('vue-use-locale-storage', {
      name: 'Banana',
      color: 'Yellow',
      size: 'Medium',
    }))
const state = useState()

</script>

useDraggable

useDraggable함수는 html요소를 드래그 하고 드래그 한 좌표를 반환합니다. 좌표는 창 크기 기준입니다.

<template>
  <div ref="el" :style="style" style="position: fixed;" class="drag-div">
    <p>Drag me! I am at , </p>
    <p>👣</p>
  </div>
</template>

<script lang="ts" setup>
import { ref } from 'vue'
import { useDraggable } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)

// `style` will be a helper computed for `left: ?px; top: ?px;`
const { x, y, style } = useDraggable(el, {
  initialValue: { x: 40, y: 40, },
})
</script>

<style scoped>
.drag-div {
  border: 1px solid #e81099;
  width: 200px;
  padding: 10px;
  border-radius: 5px;
}
</style>

useTitle

useTitle 함수는 브라우저 타이틀을 동적으로 바꿀 수 있습니다.

<template>
  <h3>Vueuse-useTitle</h3>
  <div>
    <input v-model="title" />
  </div>
</template>

<script setup lang="ts">
import { useTitle } from '@vueuse/core'

const title = useTitle()
console.log(title.value) // print current title
title.value = 'Hello'
</script>

useShare

useShare 함수는 현재 브라우저 페이지의 주소를 공유할 수 있습니다.

<template>
  <h3>Vueuse-useShare</h3>
  <div>
    <input
        v-if="isSupported"
        v-model="options.text"
        type="text"
        placeholder="Note"
    >
    <button :disabled="!isSupported" @click="startShare">
      
    </button>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useShare } from '@vueuse/core'

const options = ref({
  title: 'VueUse',
  text: 'VueUse Share!',
  url: location.href,
})

const { share, isSupported } = useShare(options)

const startShare = () => {
  return share().catch(err => err)
}
</script>

useCssVar

useCssVar 함수는 css style 태그를 적용할 수 있습니다.

<template>
  <h3>Vueuse-useCssVar</h3>
  <div class="demo wide">
    <div>
      Edit CSS:
      <textarea v-model="css" type="text" rows="10" class="w-full" />
    </div>
    <button :disabled="isLoaded" @click="load">
      Load
    </button>
    <button class="orange" :disabled="!isLoaded" @click="unload">
      Unload
    </button>
    <div class="usestyle-demo">
      <p>ID: <code></code></p>
      <p>Loaded: <code></code></p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { useStyleTag } from '@vueuse/core'

const customCSS = `.demo { background: #ad4c2e50; }.demo textarea { background: lightyellow; }`;

const { id, css, load, unload, isLoaded } = useStyleTag(customCSS)
</script>

<style scoped>
.demo {
  width: 40%;
  margin: auto;
  transition: background-color .5s;
}

.demo textarea {
  display: block;
  min-width: 20rem;
  font-size: 1.05rem;
  padding: 0.5em 1em 0.4em;
  border-radius: 4px;
  box-shadow: var(--vp-c-divider) 0 0 0 1px;
  margin: auto;
  outline: none;
  color: var(--vp-c-text);
  transition: background-color .5s;
}
</style>

이외에도 공식 사이트에 수많은 기능을 제공하는 함수가 있습니다. 기능에 따라서 추가 설치가 필요한 것도 있습니다. 라이브러리와 문서가 지속적으로 업데이트 되고 있기 때문에 Vue3로 개발을 하게 될 경우 아주 유용하게 사용할 수 있을 것 같습니다.


출처

VueUse - All Functions

https://vueuse.org/functions.html

Vue 프로젝트의 단짝, VueUse

https://dev.to/composite/vue-vueuse-jal

VueUse as must-have library for Vue 3

https://dev.to/garmideroman/vueuse-as-must-have-library-for-vue-3-5o2