Blue Chicken - The Legend Of Zelda
본문 바로가기

개인공부

[vuetify3] <script> <script setup> bottom-drawer

https://vuetifyjs.com/en/components/navigation-drawers/#bottom-drawer

<template>
  <v-card>
    <v-layout>
      <v-app-bar
        color="primary"
        prominent
      >
        <v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>

        <v-toolbar-title>My files</v-toolbar-title>

        <v-spacer></v-spacer>

        <template v-if="$vuetify.display.mdAndUp">
          <v-btn icon="mdi-magnify" variant="text"></v-btn>

          <v-btn icon="mdi-filter" variant="text"></v-btn>
        </template>

        <v-btn icon="mdi-dots-vertical" variant="text"></v-btn>
      </v-app-bar>

      <v-navigation-drawer
        v-model="drawer"
        :location="$vuetify.display.mobile ? 'bottom' : undefined"
        temporary
      >
        <v-list
          :items="items"
        ></v-list>
      </v-navigation-drawer>

      <v-main style="height: 500px;">
        <v-card-text>
          The navigation drawer will appear from the bottom on smaller size screens.
        </v-card-text>
      </v-main>
    </v-layout>
  </v-card>
</template>
<script>
  export default {
    data: () => ({
      drawer: false,
      group: null,
      items: [
        {
          title: 'Foo',
          value: 'foo',
        },
        {
          title: 'Bar',
          value: 'bar',
        },
        {
          title: 'Fizz',
          value: 'fizz',
        },
        {
          title: 'Buzz',
          value: 'buzz',
        },
      ],
    }),

    watch: {
      group () {
        this.drawer = false
      },
    },
  }
</script>

<template>
  <v-card>
    <v-layout>
      <v-app-bar
        color="primary"
        prominent
      >
        <v-app-bar-nav-icon variant="text" @click.stop="drawer = !drawer"></v-app-bar-nav-icon>

        <v-toolbar-title>My files</v-toolbar-title>

        <v-spacer></v-spacer>

        <template v-if="$vuetify.display.mdAndUp">
          <v-btn icon="mdi-magnify" variant="text"></v-btn>

          <v-btn icon="mdi-filter" variant="text"></v-btn>
        </template>

        <v-btn icon="mdi-dots-vertical" variant="text"></v-btn>
      </v-app-bar>

      <v-navigation-drawer
        v-model="drawer"
        :location="$vuetify.display.mobile ? 'bottom' : undefined"
        temporary
      >
        <v-list
          :items="items"
        ></v-list>
      </v-navigation-drawer>

      <v-main style="height: 500px;">
        <v-card-text>
          The navigation drawer will appear from the bottom on smaller size screens.
        </v-card-text>
      </v-main>
    </v-layout>
  </v-card>
</template>
<script>
  export default {
    data: () => ({
      drawer: false,
      group: null,
      items: [
        {
          title: 'Foo',
          value: 'foo',
        },
        {
          title: 'Bar',
          value: 'bar',
        },
        {
          title: 'Fizz',
          value: 'fizz',
        },
        {
          title: 'Buzz',
          value: 'buzz',
        },
      ],
    }),

    watch: {
      group () {
        this.drawer = false
      },
    },
  }
</script>

위 형식을 script setup 형식으로

이 코드는 Vuetify 컴포넌트를 사용하여 작성된 Vue 컴포넌트입니다. 기존의 Vue 2/3 스타일인 `export default` 방식을 사용하고 있습니다. 이를 Vue 3의 `<script setup>` 스타일로 변환할 수 있습니다.

### `<script setup>`으로 변환
`<script setup>`은 Vue 3에서 더 간결하고 직관적인 코드를 작성할 수 있는 방식입니다. 이 접근 방식은 `export default` 및 기타 구조적 요소를 제거하고, 간결한 코드 작성을 가능하게 합니다. 다음은 주어진 코드를 `<script setup>`으로 변환하는 예시입니다.

```vue

<template>
  <v-card>
    <v-layout>
      <v-app-bar color="primary" prominent>
        <v-app-bar-nav-icon @click.stop="toggleDrawer"></v-app-bar-nav-icon>
        <v-toolbar-title>My files</v-toolbar-title>
        <v-spacer></v-spacer>
        <template v-if="$vuetify.display.mdAndUp">
          <v-btn icon="mdi-magnify" variant="text"></v-btn>
          <v-btn icon="mdi-filter" variant="text"></v-btn>
        </template>
        <v-btn icon="mdi-dots-vertical" variant="text"></v-btn>
      </v-app-bar>

      <v-navigation-drawer
        v-model="drawer"
        :location="$vuetify.display.mobile ? 'bottom' : undefined"
        temporary
      >
        <v-list :items="items"></v-list>
      </v-navigation-drawer>

      <v-main style="height: 500px;">
        <v-card-text>
          The navigation drawer will appear from the bottom on smaller size screens.
        </v-card-text>
      </v-main>
    </v-layout>
  </v-card>
</template>

<script setup>
import { ref, watch } from 'vue';

const drawer = ref(false); // 반응형 데이터
const items = [
  { title: 'Foo', value: 'foo' },
  { title: 'Bar', value: 'bar' },
  { title: 'Fizz', value: 'fizz' },
  { title: 'Buzz', value: 'buzz' },
]; // 목록 항목 정의

const group = ref(null); // 그룹 데이터

const toggleDrawer = () => {
  drawer.value = !drawer.value; // 드로어 토글
};

watch(group, () => {
  drawer.value = false; // 그룹 변경 시 드로어 닫기
});
</script>


```

### 주요 변경 사항
- **반응형 데이터 선언**: `ref`를 사용하여 반응형 변수를 선언합니다.
- **사용자 정의 함수**: 사용자 정의 함수를 컴포넌트 로직에 직접 작성합니다.
- **라이프사이클 훅 및 워치**: `watch`를 사용하여 `group` 변수의 변경을 감지하고, 드로어를 닫는 로직을 작성합니다.

### 요약
`<script setup>`으로 변환할 때, `export default` 및 `data`, `methods` 등의 구조를 제거하고, 필요한 변수와 함수를 간결하게 작성할 수 있습니다. 이 예시는 기존 코드에서 각 부분을 `ref` 및 사용자 정의 함수로 변환하여, 간결하고 직관적인 코드를 작성하는 방법을 보여줍니다.