node 2022/02/04

무간·2022년 2월 4일

package 있는 폴더에서 CMD실행후 npm install 해야 깃에서 받을걸로 사용할 수 있음

================================================

파일명 src/components/boardcontent.vue

<template>
    <div>
        <h3>src/components/boardcontent.vue</h3>
        
        <div v-if="state.item">
            제목   : {{state.item.title}} <br />
            내용   : {{state.item.content}} <br />
            작성자 : {{state.item.writer}} <br />
            조회수 : {{state.item.hit}} <br />
            이미지 : <img :src="state.item.imageurl" style="width:100px; height:100px"/>
            <hr />

            <router-link to="/board"><button>목록으로</button></router-link>
            <button @click="handleDelete">삭제</button>
            <button @click="handleUpdate">수정</button>
            <button v-if="state.item.prev > 0" @click="handleData(1)">이전글</button>
            <button v-if="state.item.next > 0" @click="handleData(2)">다음글</button>

            <hr />            

            <table border="1">            
                <thead>
                    <tr>
                        <th>no</th>
                        <th>writer</th>                    
                        <th>content</th>
                        <th>date</th>
                        <th>delete</th>
                    </tr>                
                </thead>
                <tbody>
                    <tr v-for="item in state.reply" :key="item">
                        <td> {{ item._id}} </td>
                        <td> {{ item.writer }} </td>                    
                        <td> {{ item.content }} </td>
                        <td> {{ item.regdate }} </td>
                        <button @click="handleReplyDelete(item._id)">삭제</button>
                    </tr>
                </tbody>            
            </table>

            {{state.reply1}}

            <hr />            
            <textarea v-model="state.reply1.content" rows="6" placeholder="댓글내용"></textarea>  <br />
            <input v-model="state.reply1.writer" type="text" placeholder="댓글작성자" />
            <button @click="handleReplyAction">댓글저장</button>


        </div>
    </div>
</template>

<script>
import axios from 'axios';  //벡엔드연동
import { reactive, onMounted } from 'vue'; //state변수, 
import { useRoute } from 'vue-router'; // 페이지 이동후route.query
import { useRouter } from 'vue-router'; // 페이지 이동시킴

export default {
    setup () {
        const route = useRoute();
        const router = useRouter();

        // state변수 생성
        const state = reactive({
            no : route.query.no,
            reply1 : {
                content:'',
                writer:'',
            }
        });

        // 수정하기
        const handleUpdate = () => {
            router.push({ name:"BoardUpdate", query:{no:state.no} });
        }

        // 댓글 작성
        const handleReplyAction = async() =>{
            const url = `/board/insertreply`;
            const headers = {"Content-type":"application/json"};
            const body = {
                content : state.reply1.content,
                writer : state.reply1.writer,
                boardno : state.no
            }
            const response = await axios.post(url,body,{headers: headers}); 
            console.log(response.data);
            if(response.data.status === 200){
                await handleReplyMound(state.no)
            }
        }

        // 댓글 삭제
        const handleReplyDelete = async(no) => {
            console.log(no);
            const url =`/board/deletereply?no=${no}`;
            const headers = {"Content-Type":"application/json"};
            const response = await axios.delete(url, {headers:headers, data:{}});
            console.log(response.data);
            if(response.data.status === 200){
                alert('삭제 되었습니다.');
                await handleReplyMound(state.no);
            }
        }


        // 삭제하기 메소드 생성
        const handleDelete = async() => {
            if(confirm('삭제하시겠습니까?')) {
                const url = `/board/delete?no=${state.no}`;
                const headers = {"Content-Type":"application/json"};
                const response = await axios.delete(url, {headers:headers, data:{}});
                console.log(response.data);
                if(response.data.status === 200){
                    router.push({ name:"Board", query:{page:1,text:''} })
                }
            }
        }

        const handleMount = async(no) => {                        
            const url = `/board/selectone?no=${no}`;
            const headers = {"Content-Type":"application/json"};

            const response = await axios.get(url, {headers});
            console.log(response.data);
            if(response.data.status === 200){
                console.log(response.data.result);
                state.item = response.data.result;
            }
        };

        const handleReplyMound = async(no) => {
            const url = `/board/selectreply?no=${no}`;
            const headers = {"Content-Type":"application/json"}; 

            const response = await axios.get(url,{headers});
            if(response.data.status === 200 ){
                state.reply = response.data.result;
            }
        }

        onMounted(async() => {
            await handleMount(state.no);
            await handleReplyMound(state.no);
        });

        const handleData = async(idx) =>{
            if(idx === 1) { // 이전글
            // 주소창 변경
            // 게시판 상세화면 -> 게시판 상세화면 onMounted()가 실행이 안됨 그래서 한번더 수동으로 사용함            
            router.push({name:"BoardContent",query:{no:state.item.prev}})
                state.no = state.item.prev;
                await handleMount(state.no);                
                await handleReplyMound(state.no);
            }
            else if(idx ===2 ){
                router.push({name:"BoardContent",query:{no:state.item.next}})
                state.no = state.item.next;
                await handleMount(state.no);
                await handleReplyMound(state.no);
            }
        }



        return {state, handleDelete, handleData, handleReplyMound, handleUpdate, handleReplyAction, handleReplyDelete}
    },

}
</script>

<style lang="scss" scoped>

</style>

================================================

파일명 src/components/BoardUpdate.vue

<template>
    <div>
        <h3>src/components/BoardUpdate.vue</h3>
        {{ state }} <br />        

        <div v-if="state.item">
            제목 : <input type="text" v-model="state.item.title"/> <br />
            내용 : <textarea rows="6" v-model="state.item.content"></textarea> <br />
            작성자 : <input type="text" v-model="state.item.writer"/> <br />
            <input type="button" value="수정" @click="handleUpdateAction"/> <br />
        </div>

    </div>
</template>

<script>

import axios from 'axios';
import { reactive, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useRouter } from 'vue-router';

export default {
    setup () {
        const route = useRoute();
        const router = useRouter();

        const state = reactive({
            no   : route.query.no             
        });

        const handleData = async(no) => {
            const url = `/board/selectone?no=${no}`;
            const headers = {"Content-Type":"application/json"};

            const response = await axios.get(url, {headers});
            console.log(response.data);
            if(response.data.status === 200){
                console.log(response.data.result);
                state.item = response.data.result;
            }
        }

        const handleUpdateAction = async() => {
            const url = `/board/update?no=${state.no}`;
            const headers = {"Content-Type":"application/json"};
            const body ={
                title   : state.item.title,
                content : state.item.content,
                writer  : state.item.writer,
            };
            const response = await axios.put(url, body, {headers:headers});
            console.log(response.data);

            if(response.data.status === 200 ){
                alert('수정 되었습니다.');
                // 상세화면으로 이동시키기
                router.push({ name:"BoardContent", query:{no:state.no} });
            }
        }

        onMounted( async() => {
            await handleData(state.no)
           
        });
        

        return {state, handleUpdateAction}
    }
}
</script>

<style lang="scss" scoped>

</style>

================================================

파일명 routes/board.js

// 댁글 삭제
// localhost:3000/board/deletereply?no=17
router.delete('/deletereply', async function(req,res,next){
    try{
         // 1. 전달되는 값 받기
         const no = Number(req.query.no);

         // 2. DB연결, DB선택 및 컬렉션 선택
         const dbconn = await db.connect(dburl);        
         const collection = dbconn.db(dbname).collection('boardreply1');
 
         //3. 삭제 수행
         const result = await collection.deleteOne(
             { _id : no }
         );
 
         // 4. 결과 반환
         if(result.deletedCount === 1 ){
             return res.send({status : 200});
         }
         return res.send({status : 0});
    }
    catch(e){
        console.error(e); // 개발자가 확인하는 용도
        res.send({status : -1, message:e}); // 프론트로 전달함
    }
});
profile
당신을 한 줄로 소개해보세요

0개의 댓글