본문 바로가기

국비과정/Vue

20230920 _[78일차]_01. Vue (4차)_게시판만들기2

구동하고 postman에서 확인

 

어제 만든 게시판 테이블 아래쪽에 button 추가해준다.

<template>
  <div>
    <h1>board</h1>
    <table>
      <thead>
        <tr>
          <th>번호</th>
          <th>제목</th>
          <th>글쓴이</th>
          <th>날짜</th>
          <th>조회수</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="n in list" v-bind:key="n.bno">
          <td>{{ n.bno }}</td>
          <td class="title">
            <a v-on:click="viewDetail(`${n.bno}`)">{{ n.btitle }}</a>
          </td>
          <td>{{ n.m_name }}</td>
          <td>{{ n.bdate }}</td>
          <td>{{ n.blike }}</td>
        </tr>
      </tbody>
    </table>
    <button>글쓰기</button>
  </div>
</template>

 

클릭기능 넣어주고 아래쪽에서 write 메소드 만들어주나보다.

    <button @click="write">글쓰기</button>

method 에 write 추가해준다.

  methods:{
    viewDetail(bno){
        //alert(bno+'번을 눌렀습니다');
        this.requestBody.bno = bno;
        this.$router.push({
          path: './detail',
          query: this.requestBody
        });
    },
    write(){
      this.$router.push("write");
    }
  }

 

views 폴더 아래에 WritePage.vue 파일 만들어주고 index.js에서 연결해준다.

글쓰기 페이지 잘 뜨는지 확인

 

input창은 title로 쓸거고, textarea 부분은 content로 쓸거라고 script 부분에 지정해줬다. (v-model로 연결예)

<template>
    <div class="write">
        <h1>글쓰기</h1>
        <input >
        <textarea></textarea>
        <button>글쓰기</button>
    </div>
</template>

<script>
export default {
    data(){
        return{
            title:null,
            content:null,
           
        }
    }
}
</script>

 

title의 입력값 (input창의 입력값)을 잡아와서 팝업으로 띄워줄거다

<template>
    <div class="write">
        <h1>글쓰기</h1>
        <input v-model="title">
        <textarea v-model="content"></textarea>
        <button @click="write">글쓰기</button>
    </div>
</template>

이때 method영역에서는 this.title로 가져온다.

<script>
export default {
    data(){
        return{
            title:null,
            content:null,

        }
    },
    method:{
        write(){
            alert(this.title);
        }
    }
}
</script>

제목을 쓰고 글쓰기 버튼을 눌러보면 아래처럼 title의 값을 잘 잡아와 팝업으로 띄운다.


component v-model : 양방향(two-way) 데이터 바인딩 구현 ( form요소와 함께 쓰임 )

 

https://engineer-mole.tistory.com/333

 

[Vue.js] v-model 이란?

※ 일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 직역. 의역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다. v-model이란 공식 사이트를 인용하면 다음과 같다. form의 input 요

engineer-mole.tistory.com


textarea도 content로 연결해주고 

<template>
    <div class="write">
        <h1>글쓰기</h1>
        <input v-model="title">
        <textarea v-model="content"></textarea>
        <button @click="write">글쓰기</button>
    </div>
</template>

두 데이터를 saveDate 라는 하나의 변수(객체)에 넣은 후에

saveDate에서 title을 뽑아내 팝업을 띄워보자

<script>
export default {
    data(){
        return{
            title:null,
            content:null,

        }
    },
    methods:{
        write(){
            let saveData = {};
            saveData.title = this.title;
            saveData.content = this.content;
            alert(saveData.title);
        }
    }
}
</script>

saveDate 데이터 객체는 key값으로는 'title'을, value값으로 '(내가입력한 제목값)'을 가지는가보다.


스크립트 상단에 axios 임포트해준다.

import axios from "axios";

get => 게시판형태에서 사용 (select로 데이터를 불러올때)

post => 저장할때 사용 (Insert로 데이터를 저장할때)

 

지금은 글쓰기 저장할거니까 axios.post() 로 사용할거다.

saveData를 json형태로 변환해서 내보낸다.

 * JSON.stringify() : 주어진 객체를 문자열로 변환하며(직렬화), 변환된 문자열은 JSON 형식을 따른다.

    methods:{
        write(){
            let saveData = {};
            saveData.title = this.title;
            saveData.content = this.content;
            //alert(saveData.title);
            axios.post('http://localhost:3000/write', JSON.stringify(saveData))
            .then()
            .catch();
        }
    }

headers에 json타입이라고 포함시켜준다. (이 요청이 JSON 형식의 데이터를 전송한다는 것을 서버에 알려주는 역할)

    methods:{
        write(){
            let saveData = {};
            saveData.title = this.title;
            saveData.content = this.content;
            //alert(saveData.title);
            axios.post('http://localhost:3000/write', JSON.stringify(saveData), {
                headers: {"Content-Type" : "application/json"}
            })
            .then()
            .catch((err) => {
                alert("문제가 발생했습니다." + err);
            });
        }
    }

 

정리하자면 

saveData 객체를 JSON 문자열로 변환하고, 이 JSON 문자열을 HTTP POST 요청의 본문에 포함시킨 다음, 이 요청을 보낼 때 Content-Type 헤더를 설정하여 요청이 JSON 데이터를 포함하고 있음을 명시적으로 지정한거다.

 

스타일 지정해주면 

<style>
   .write{
    margin: 0 auto;
    padding: 5px;
    width: 800px;
    height: 500px;
    background-color: bisque;
   }

   .write textarea{
    width: 90%;
    height: 80%;
    margin: 10px;
   }

    .write input{
        width: 90%;
        margin: 10px;
    }

</style>

아래의 글쓰기 페이지 완성


이클립스에서 write로직 만들어준다.

값들은 Map으로 받는다.

 

글을쓰고 글쓰기 버튼을 누르면 서버에서 잘 받아서 map값이 뜬다.

이제 이 값을 wrtie 메소드로 db까지 보내자. 

결과값은 result 로 받아 다시 json으로 리턴한다.

서비스에서도 map을 받아서 보낼건데

db로 값을 보내기 전에 필수로 넣어줘야 하는 값들이 또 있다.

기본값 설정되어 있는 필드 외에는 m_no, bip 만 넣어주면 된다. 

map 에 bip, m_id값을 넣어서 DAO로 보낸다.

mapper에서는 board 테이블에 데이터 추가해줄건데 

서브쿼리문으로 m_id와 일치하는 m_no를 뽑아내서 넣어준다.

 

m_id 앞에 # 표시 대신에 $ 표시를 넣어줘서 오류가 났었다. **주의**

 

 

이제 글을 써보면

 

db에 잘 들어간다.

 

게시판에도 잘 뜬다.

 

데이터가 잘 들어가니 성공했을 때 알람을 띄워준다.

result가 1인경우 글저장 팝업 띄우고 boardList로 이동한다.

    methods:{
        write(){
            let saveData = {};
            saveData.title = this.title;
            saveData.content = this.content;
            //alert(saveData.title);
            axios.post('http://localhost:3000/write', JSON.stringify(saveData), {
                headers: {"Content-Type" : "application/json"}
            })
            .then((res) => {
                if(res.data.result == 1){
                    alert("데이터베이스에 글을 저장했습니다.");
                    location.href="/boardList";
                } else {
                    alert("ooops! 문제가 발생했습니다.");
                }
            })
            .catch((err) => {
                alert("문제가 발생했습니다." + err);
            });
        }
    }

글을써보면 잘 저장되면서 글저장 팝업이 뜨고 boardList 페이지로 이동한다.

//location.href="/boardList";
 this.$router.push("/boardList");

경로설정은 위처럼 해줘도 된다.

 

 


이제 detail (글내용) 부분 만들자

로직이 없어서 에러가 뜬다. 스프링에서 만들자.

위의 detail페이지 url의 bno를 잡아서 처리하는 로직 만들자. (BoardController에)

bno는 필수값이니 처리해준다 (name 또는 value 둘다 사용가능)

글 하나만 가져올거라 List가 아니라 Map으로만 가져온다.

url에서 잡은 bno와 일치하는 글내용을 가져오는 쿼리문 작성.

 

아래의 725번 글을 클릭해보면

bno 725번에 해당하는 게시글 내용을 잘 가져온다.

 

 

이제 이 글내용을 vue로 브라우저에 띄워줄건데

DetailPage.vue에서 url부분 살짝 수정해준다.

 

method부분에서 글내용 띄우는 함수인 boardDetail부분 아래처럼 해준다.

 axios.get('http://localhost:3000/detail?bno=' + this.$route.query.bno)

this.detail = res.data.detail 로 

    methods:{
        board(){
            this.$router.push({path : '/boardList'});
        },
        boardDetail(){
            //alert('페이지가 구동되면 바로 호출됩니다.');
            axios.get('http://localhost:3000/detail?bno='+this.$route.query.bno)
            .then((res) => {
                this.detail = res.data.detail;
            })
            .catch((err) => {
                alert('오류가 발생했습니다.' + err);
            });
        }
    }
}

이제 글내용 잘 불러온다.