[Vue3] NativeScript 에서 Side 메뉴(Drawer) 만들기 (23년 9월 기준)

2023. 9. 27. 13:30IT/Vue

반응형

NativeScript + Vue3 는 현재 베타가 진행중이며, 베타 버전은 9로 확인되고 있다.

 

NativeScript + Vue3 프로젝트 생성은 아래 링크를 확인하기 바란다.

2023.09.18 - [IT/Vue] - [NativeScript+Vue3] 하이브리드 앱 신규 프로젝트 생성 방법

 

[NativeScript+Vue3] 하이브리드 앱 신규 프로젝트 생성 방법

현재 NativeScript 에서 공식적으로 지원하는 것은 Vue2 이다. 물론 다른 언어들도 공식 지원하지만, 여기서는 Vue 만으로 얘기한다. 뷰2 기반으로 만들어도 다양한 하이브리드 앱을 만드는 것에는 문

suncastlefafa.tistory.com

 

프로젝트 생성 후 기존에 사용하던 RadSideDrawer 플러그인을 이용하여 사이드 메뉴를 만들어보려고 했으나, 아직 NativeScript + Vue3(TypeScript 형식) 에서 제대로 동작하지 않고 있다. 컴파일까지는 정상적으로 되게 하였으나, 실행 중 레퍼런스를 못찾는 오류가 지속 발생하여 제대로 동작되지 않는 것으로 결론 내렸다. 

 

Vue2에서 Vue3로 업그레이드 되면서 많은 변화가 있었기 때문에, RadSideDrawer 플러그인도 내부적으로 리팩토링이 필요할 것으로 보인다. 

 

어떻게든 동작 시키려고 3일간 노력해보았으나, RadSideDrawer 플러그인의 업데이트가 필요한 것으로 보인다.

 

결국 새로운 라이브러리를 찾다가, Vue3에서 호환되는 Drawer 최신의 플러그인을 찾아냈다.

릴리스 날짜는 2023/9/12 로 최신이 맞았다.

 

결론. NativeScript+Vue3(TypeScript 기반) 에 쓸만한 Navigation Drawer 가 없어서 조금 고민이었는데, 이번엔 제대로 동작하는 플러그인을 찾아내 다행이다. 지속적으로 플러그인을 찾아낼 예정이다.

 

출처 : https://www.npmjs.com/package/@nativescript-community/ui-drawer

 

일단 만들기를 시작하자. 플러그인 추가 및 셋팅을 진행하도록 한다.

출처 : https://www.npmjs.com/package/@nativescript-community/ui-drawer

 

@nativescript-community/ui-drawer

Easily add a side drawer (side menu) to your projects.. Latest version: 0.1.23, last published: 16 days ago. Start using @nativescript-community/ui-drawer in your project by running `npm i @nativescript-community/ui-drawer`. There is 1 other project in the

www.npmjs.com

 

1. 프로젝트 셋팅 

vscode 터미널을 열고, 프로젝트 폴더에 가서 플러그인 추가 명령어 실행.

ns plugin add @nativescript-community/ui-drawer

 

2. 프로젝트 메인 app.ts 에 다음의 코드 추가

import { createApp } from 'nativescript-vue';
import DrawerPlugin from '@nativescript-community/ui-drawer/vue3';
import Home from './components/Home.vue';

createApp(Home)
.use(DrawerPlugin)
.start();

 

3. BasicDrawer.vue 파일 생성 및 코딩

    코드를 보면 출처와 다른 내용들을 볼 수 있는데, 출처의 코드를 그대로 따라하면 버그가 있어서 제대로 실행이 되지 않아 해당 부분의 버그를 수정하였다. 출처의 코드는 onOpenDrawer, onCloseDrawer 메서드 부분에 버그가 있었다.

<template>
    <Page>
        <ActionBar>
            <NavigationButton text="Back" @tap="$navigateBack" />
            <Label text="Basic Drawer" />
        </ActionBar>

        <Drawer
            ref="drawer"
            :gestureHandlerOptions="{
                failOffsetYStart: -10,
                failOffsetYEnd: 10,
            }"
        >
            <GridLayout
                ~leftDrawer
                class="drawer"
                width="80%"
                backgroundColor="white"
                rows="auto, *"
            >
                <StackLayout backgroundColor="#eeeeee" padding="25">
                    <GridLayout columns="80, *" height="100">
                        <StackLayout col="0" class="avatar">
                            <Label text="JS" />
                        </StackLayout>
                    </GridLayout>
                    <StackLayout>
                        <Label text="John Smith" fontWeight="bold" />
                        <Label text="john.smith@example.com" />
                    </StackLayout>
                </StackLayout>
                <ScrollView row="1">
                    <StackLayout>
                        <Label
                            v-for="(item, index) in items"
                            :key="index"
                            :text="item.title"
                            @tap="onCloseDrawer"
                        />
                    </StackLayout>
                </ScrollView>
            </GridLayout>

            <StackLayout ~mainContent backgroundColor="white">
                <Button
                    @tap="onOpenDrawer('left')"
                    text="Open Drawer"
                    width="250"
                    marginTop="25"
                />
            </StackLayout>
        </Drawer>
    </Page>
</template>

<script lang="ts">
import { ref, $navigateBack, $navigateTo, onMounted } from "nativescript-vue";

export default {
    setup() {
        const drawer = ref<any>(null);
        const side = ref("left");

        const onOpenDrawer = () => {
            const drawerInstance = drawer.value;
            drawerInstance.nativeView.open(side.value);
        };

        const onCloseDrawer = () => {
            const drawerInstance = drawer.value;
            drawerInstance.nativeView.close();
        };

        return {
            $navigateBack,
            drawer,
            side,
            onOpenDrawer,
            onCloseDrawer,
        };
    },
    data() {
        return {
            items: new Array(100).fill({ title: "My profile" }),
        };
    },
};
</script>

<style scoped lang="scss">
ActionBar {
    background-color: #42b883;
    color: white;
}

Button {
    background-color: #42b883;
    color: white;
}

.avatar {
    background-color: #42b883;
    border-radius: 40;
    height: 80;
    vertical-align: middle;

    Label {
        vertical-align: middle;
        horizontal-align: center;
        font-size: 30;
        color: white;
    }
}

.drawer {
    Button {
        background-color: transparent;
        margin: 0;
        padding: 0;
        border-color: #ccc;
        z-index: 0;
        border-width: 0 0 0.5 0;
        color: #222222;
        text-align: left;
        padding-left: 25;
        height: 50;
        font-size: 14;
    }

    Button:highlighted {
        background-color: #eeeeee;
        color: #222222;
    }
}
</style>

 

4. 실행 및 적당한 커스텀

    포스팅한 내용은 Home.vue 에서 BasicDrawer.vue를 호출하는 적당한 코드 등을 넣어서 호출하면 되고, 해당 화면에 가면 버튼을 누르면 사이드 드로워가 나오고 들어가는 모습을 볼 수 있는 코드이다.

    드로워의 아이템 클릭 등의 내용을 추가로 커스텀 해서 사용하면 되겠다.

반응형