IT/development

[Vue.js] 기존 thymeleaf에 Vue.js 적용하는 방법

알 수 없는 사용자 2023. 8. 10. 20:38
반응형

2가지 방법 존재

  • node.js 환경으로 구동(node.js 런타임 환경 필요, 서비스 구동 시 서버와 port 다르게 구성)
  • 기존 thyemeleaf파일에 script만 추가(thyemelaf 렌더링 이후 조작하는 방식이라 node.js 불필요)

여기선 2번 째 방법 채택

기존 html의 body 태그안에 Vue.js 관련 script import(실제 배포 시엔 js파일 직접 import 권장)

<!DOCTYPE html>
<html lang="ko"
	xmlns:th="http://www.thymeleaf.org"
	xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

	<!-- head -->
	<th:block th:replace="fragments/head :: headFragment"></th:block>

	<body>
	<div class="wrap">

		<main class="main">
		<!-- Content -->
		<th:block layout:fragment="content"></th:block>
		</main>

	</div>

		<script src="/js/ui.js"></script>

		<!-- vue.js import(운영에서는 lib 직접 참조할 것) -->
		<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js"></script>
		<!-- Axios import(운영에서는 lib 직접 참조할 것) -->
		<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

		<!-- 공통 js 추가 -->
		<script src="/js/cmmn.js"></script>
		<!-- Content script -->
		<th:block layout:fragment="script"></th:block>

	</body>

</html>

vue.js를 입힐 div root id 설정(예시)

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/popup.html}">

<!-- Script -->
<script layout:fragment="script" th:inline="javascript" type="text/javascript">
</script>
<th:block layout:fragment="content">
<!--  <div class="contents">-->
  <div class="contents" id="app"> <!-- vue.js를 적용하기 위해 id를 "app"으로 설정 -->
    <h2 class="tit">주소록</h2>

    <form id="searchForm">
      <div class="search-box">
      <!-- 검색조건 -->
      <ul>
          <li class="full">
         <label>사원명</label>
         <div class="form-row w100">
             <div class="col-9">
                <input type="text" class="input-default" id="name" v-model="empNm" name="empNm" th:value="${param.empNm}"/>
             </div>
           <div class="form-inline">
             <button class="btn btn-normal" type="button" @click="searchByName">검색</button>
<!--             <button class="btn btn-normal" type="button" id="searchBtn">검색</button>-->
             <button class="btn btn-gray" type="button" id="formResetBtn">초기화</button>
           </div>
         </div>
          </li>
      </ul>
      </div>
    </form>
    <div class="tbl scroll-x" id="searchlist">
      <div class="flex-box justify">
    <p class="section-tit">사원 목록</p>
  </div>
  <!-- 가로 스크롤의 경우 scroll-x 클래스 추가 -->
    <div class="tbl scroll-x">
      <table>
        <caption>사원승인 신청</caption>
        <colgroup>
          <col width="60px">
          <col width="100px">
          <col width="150px">
          <col width="200px">
          <col width="100px">
          <col width="120px">
        </colgroup>
        <thead>
        <tr>
          <th scope="row">순번</th>
          <th scope="row">사원명</th>
          <th scope="row">직급</th>
          <th scope="row">직책</th>
          <th scope="row">전화번호</th>
          <th scope="row">이메일</th>
        </tr>
        </thead>
<!--        <tbody class="center" id="addressbookBody">-->
        <tbody class="center">
          <tr v-for="item in displayedItems" :key="item.empId">
            <td>{{ item.no }}</td>
            <td>{{ item.empNm }}</td>
            <td>{{ item.positionCd }}</td>
            <td>{{ item.roleCd }}</td>
            <td>{{ item.empHp }}</td>
            <td>{{ item.empEmail }}</td>
          </tr>
        </tbody>
      </table>

      <!-- pagination -->
      <div class="paging tbl-paging">
        <ul class='pagination'>
          <li class='paginate_button page-item first'>
            <button type='button' class='page-link' style='cursor: pointer;'>
              <span class='hidden'>first page</span>
            </button>
          </li>
        </ul>
      </div>
    </div>
    </div>
    <div class="popup" id="pop_man">
      <a href="#" class="pop-close" id="close" onclick="return false;">
        <span class="hidden">팝업 닫기</span>
      </a>
      <div class="pop-header">
        사원 정보
      </div>
      <form id="updateform">

      </form>
    </div>
  </div>

Vue.js를 적용할 thyemeleaf파일에 Vue.js 코드 추가(예시)

<!--vue.js start-->
  <script>
    new Vue({
         el: '#app',
         data: {
           items: [],
           currentPage: 1,
           totalPageCount: 0,
           empNm: '',
         },
          //데이터를 기반으로 변경할 속성
         computed: {
            displayedItems() {
              return this.items;
            }
         },
         mounted() {
            this.fetchData();
         },
         methods: {
           //데이터 조회
           fetchData() {
             const url = '/api/user/addressbook';
             //2번 째 parameter(queryString)
             const params = { params:
                              { currentPage: this.currentPage,
                                empNm: this.empNm
                              }
                           };
             axios.get(url, params)
               .then(function(response) {
                 this.items = response.data.list;
                 this.totalPageCount = response.data.paging.totalPageCount;
                 console.log(response);
               }.bind(this))
               .catch(function(error) {
                 // 에러 처리
                 console.log(error);
               });
           },
           //검색
           searchByName() {
             this.currentPage = 1;
             this.fetchData();
           }
        }
       });
  </script>
  <!--vue.js end-->
반응형