본문 바로가기
Programming/Vue

[실습] 뷰(Vue.js)로 관리자/직원 전용 Web Application 개발하기 - 메뉴에 공지사항/게시판 연동하기

by 돌방로그 2023. 1. 6.

제목의 글을 설명하기에 앞서 정보전달의 목적도 있지만, 

제가 잊지않기 위해서 공부 및 정리하며 쓰는 글이라는 사실을 미리 고지합니다.

 

혹시라도 오입력된 정보가 있다면, 댓글 남겨주세요!


오늘의 Vue.js 실습 목표는 "웹 어플리케이션 (Web Application) 만들어보기!" 입니다.

본 게시글에서 다루는 사항은 관리자/직원 전용 웹 어플리케이션의 메뉴 중에서 Notice 선택시 보여지는 화면을 구현하는 과정입니다.

 


웹 어플리케이션(Web Application) 구현하기 - 공지사항/게시판

사전 준비

아래 사항에 대해서 사전 준비가 완료되지 않으신 분들은 아래 링크를 참조하여 사전 준비를 진행합니다.

혹시라도 아래 개념이 잘 기억나지 않으시는 분들은 관련 링크를 참조하시기 바랍니다.

 


파일 구조

관리자/직원 전용 Web Application의 메뉴 중 공지사항/게시판(Notice) 기능을 구현하고 난 뒤, 파일/디렉터리 구조와 호출 흐름도입니다.

좌: 파일/폴더 트리 우: 호출/상속 흐름도

 

Web Application 메뉴에 공지사항/게시판(Notice)를 구현/연동하기 위해 작업할 파일은 총 3개입니다.

  • src\App.vue:
  • src\router\index.js:
  • src\views\user-web\notice\BaseNotice.vue:

 


결과 이미지

구현하기에 앞서 본 글에서 소스코드를 따라하시면 아래와 같이 웹 어플리케이션의 메뉴(사이드바, 네비게이션 바)에 공지사항/게시판(Notice) 기능을 연동/구현하실 수 있습니다.

 


소스 코드

본 게시글에서는 메뉴(네비게이션 바, 사이드 바)에 공지사항/게시판 연동하는 기능을 구현합니다.

 

src\App.vue

기존에 Web Application의 메뉴를 구성하는 코드에 라우팅 경로를 연결하는 코드를 추가 구현합니다.

아래 코드는 새롭게 경로/라우팅 기능에 대한 코드로 인해 변경/추가된 코드만 발췌하여 기록합니다.

기존 코드는 링크를 참조해주세요.

 

<template>

<template>
  <v-app>
    <v-navigation-drawer v-model="drawer" app>
      <v-list dense>
        ...
        
        <v-list-item-group v-model="selectedItem" color="primary">
          <v-list-item
            v-for="(item, i) in navBasicItems"
            :key="i"
            :to="item.to" <!-- 추가된 코드 -->
          >
          ...  
          </v-list-item>
          ...
          
          <v-list-item
            v-for="(item, i) in navUserWebItems"
            :key="i"
            :to="item.to" <!-- 추가된 코드 -->
          >
          ...
          </v-list-item>
          ...
          
          <v-list-item
            v-for="(item, i) in navAdminWebItems"
            :key="i"
            :to="item.to" <!-- 추가된 코드 -->
          >
          ...
          </v-list-item>
          ...
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>
    ...
  </v-app>
</template>
  • <v-list-item> 태그에서 'v-for'를 통해 각 항목별 라우팅 경로를 지정하는 ':to' 속성을 사용하여 경로 지정하도록 코드 추가

 

<script>

<script>
export default {
    ...
    
    navUserWebItems: [
      {
        text: "Notice",
        icon: "mdi-file-outline",
        to: "/page/user-web/notice", // 추가된 코드
      },
      ...
    ],
    ...
  }),
};
</script>
  • data 영역
    • Notice가 속한 변수인 navUserWebItems에 Notice에 'to'로 라우팅될 경로를 정의
      • 다른 변수와 변수에 속한 객체에 대한 'to' 값은 향후 해당 콘텐츠가 구현이 완료될 때마다 추가할 예정

 

해당 파일에 전체 코드를 보고 싶으신 경우 아래 더보기를 참고해주세요.

더보기
<template>
  <v-app>
    <v-navigation-drawer v-model="drawer" app>
      <v-list dense>
        <!-- User(Employee) information -->
        <v-list-item>
          <v-list-item-avatar>
            <v-img src="https://cdn.vuetifyjs.com/images/john.png"></v-img>
          </v-list-item-avatar>
        </v-list-item>
        <v-list-item link>
          <v-list-item-content>
            <v-list-item-title class="text-h6">Sylvia Park</v-list-item-title>
            <v-list-item-subtitle>ardiums@gmail.com</v-list-item-subtitle>
          </v-list-item-content>
        </v-list-item>
        <v-divider></v-divider>

        <!-- Menu/Navigation Bar list -->
        <v-list-item-group v-model="selectedItem" color="primary">
          <!-- TODO: key 중복 문제 해결 필요 -->
          <v-list-item
            v-for="(item, i) in navBasicItems"
            :key="i"
            :to="item.to"
          >
            <v-list-item-icon>
              <v-icon v-text="item.icon"></v-icon>
            </v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>

          <v-divider></v-divider>

          <v-subheader>User Web</v-subheader>
          <v-list-item
            v-for="(item, i) in navUserWebItems"
            :key="i"
            :to="item.to"
          >
            <v-list-item-icon>
              <v-icon v-text="item.icon"></v-icon>
            </v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>

          <v-divider></v-divider>

          <v-subheader>Admin Web</v-subheader>
          <v-list-item
            v-for="(item, i) in navAdminWebItems"
            :key="i"
            :to="item.to"
          >
            <v-list-item-icon>
              <v-icon v-text="item.icon"></v-icon>
            </v-list-item-icon>
            <v-list-item-content>
              <v-list-item-title v-text="item.text"></v-list-item-title>
            </v-list-item-content>
          </v-list-item>
        </v-list-item-group>
      </v-list>
    </v-navigation-drawer>

    <v-app-bar app>
      <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>

      <v-toolbar-title>Application</v-toolbar-title>
    </v-app-bar>

    <v-main>
      <v-container fluid>
        <router-view></router-view>
      </v-container>
    </v-main>

    <v-footer app>
      <!-- -->
    </v-footer>
  </v-app>
</template>

<script>
export default {
  name: "App",

  data: () => ({
    drawer: null,

    // For Menu/Navigation Bar
    selectedItem: 0,

    navBasicItems: [
      {
        text: "Dashboard",
        icon: "mdi-view-dashboard"
      },
      {
        text: "Setting",
        icon: "mdi-cog-outline"
      },
    ],
    navUserWebItems: [
      {
        text: "Notice",
        icon: "mdi-file-outline",
        to: "/page/user-web/notice"
      },
      {
        text: "User Management",
        icon: "mdi-account"
      },
      {
        text: "Menu Management",
        icon: "mdi-lan-check"
      },
    ],
    navAdminWebItems: [
      {
        text: "User Management",
        icon: "mdi-account-supervisor-circle"
      },
      {
        text: "Rights Management",
        icon: "mdi-lock-open"
      },
    ],
  }),
};
</script>

 

src\router\index.js

Web Application의 메뉴를 통해 라우팅될 컴포넌트 및 경로를 관리하는 코드를 구현합니다.

Notice에 대한 라우팅 경로 및 컴포넌트만 정의하였으며, 다른 메뉴 아이템에 대한 경로 및 컴포넌트는 각각의 기능이 구현이 완료될 때 추가할 예정입니다.

...
Vue.use(VueRouter);

// For User Web
import NoticePage from "./../views/user-web/notice/BaseNotice.vue";

const routes = [
  // For User Web
  {
    name: "UserWebNoticeList",
    path: "/page/user-web/notice",
    component: NoticePage,
  },
];

...

 

해당 파일에 전체 코드를 보고 싶으신 경우 아래 더보기를 참고해주세요.

더보기
import Vue from "vue";
import VueRouter from "vue-router";

Vue.use(VueRouter);

// For User Web
import NoticePage from "./../views/user-web/notice/BaseNotice.vue";

const routes = [
  // For User Web
  {
    name: "UserWebNoticeList",
    path: "/page/user-web/notice",
    component: NoticePage,
  },
];

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes,
});

export default router;

 

src\views\user-web\notice\BaseNotice.vue

BaseNotice는 메뉴에서 Notice가 클릭되는 경우 보여질 콘텐츠 영역의 최상위 컴포넌트 파일입니다.

 

<template>

BaseNotice는 크게 3가지 영역으로 구분됩니다.

타이틀이 표시되는 헤더 영역과 공지사항/게시글이 테이블/리스트 형태로 표시되는 기본 영역과 게시글/공지사항에 대한 수정 등의 조작이 추가로 진행되는 상세 영역이 하나의 콘텐츠 영역으로서 제공됩니다.

한 콘텐츠 영역에서 8:4, 즉 전체 너비에 2:1의 비율로 기본 화면과 상세 화면이 분할되어 표시됩니다.

<template>
  <v-container>
    <div class="text-h4 font-weight-medium ma-2">NOTICE</div>

    <v-divider></v-divider>

    <v-row>
      <v-col cols="8">
        <NoticeList></NoticeList>
      </v-col>
      <v-col cols="4">
        <NoticeDetail></NoticeDetail>
      </v-col>
    </v-row>
  </v-container>
</template>

 

<script>

BaseNotice를 구성하는 하위 컴포넌트로 사용될 NoticeList와 NoticeDetail에 대한 컴포넌트 import 및 정의하는 코드를 구현합니다.

<script>
import NoticeList from "./../../../components/user-web/notice/NoticeList.vue";
import NoticeDetail from "./../../../components/user-web/notice/NoticeDetail.vue";

export default {
  components: {
    NoticeList,
    NoticeDetail,
  },
};
</script>

 

해당 파일에 전체 코드를 보고 싶으신 경우 아래 더보기를 참고해주세요.

더보기
<template>
  <v-container>
    <div class="text-h4 font-weight-medium ma-2">NOTICE</div>

    <v-divider></v-divider>

    <v-row>
      <v-col cols="8">
        <NoticeList></NoticeList>
      </v-col>
      <v-col cols="4">
        <NoticeDetail></NoticeDetail>
      </v-col>
    </v-row>
  </v-container>
</template>

<script>
import NoticeList from "./../../../components/user-web/notice/NoticeList.vue";
import NoticeDetail from "./../../../components/user-web/notice/NoticeDetail.vue";

export default {
  components: {
    NoticeList,
    NoticeDetail,
  },
};
</script>

<style></style>

 


References

 

댓글