오늘 만든 폴더 이름은 vue_final
npm install 뭐뭐 왕왕 왈왈
이런 식으로 붙여서 쓸 수 있다.
npm install vue-router axios bootstrap
근데 오타생기니까 하나하나 하는게 낫다.
router npm install vue-router
axios npm install axios
bootstrap npm install bootstrap bootstrap-vue-3
dependencies 확인
"dependencies": {
"axios": "^1.6.8",
"bootstrap": "^5.3.3",
"bootstrap-vue-3": "^0.5.1",
"core-js": "^3.8.3",
"vue": "^3.2.13",
"vue-router": "^4.3.0"
},
src 폴더 하위에 router, views 폴더 생성
components 폴더 하위에 HelloWorld.vue 삭제하고 MenuPage.vue 생성
<template>
<header>
<nav class="nav">
<ul>
<li><router-link to="/">index</router-link></li>
<li><router-link to="/boardList">게시판</router-link></li>
</ul>
</nav>
</header>
</template>
<script>
export default {
name: 'MenuPage'
};
</script>
<style>
header {
height: 50px;
}
nav {
position: fixed;
top: 0;
width: 100%;
height: 30px;
background-color: gray;
}
nav ul {
margin: 0;
padding: 0;
}
nav li {
list-style: none;
float: left;
width: 100px;
height: 30px;
line-height: 30px;
text-align: center;
}
nav li:hover {
font-weight: bold;
}
</style>
router 하위에 index.js 생성
import { createRouter, createWebHistory } from "vue-router";
import IndexPage from "@/views/IndexPage.vue";
import BoardList from "@/views/BoardList.vue";
const routes = [
{ path: "/", component: IndexPage }, // import 먼저
{ path: "/boardList", component: BoardList },
{ path: "/login", component: () => import("../views/LoginPage.vue") }, // 여기서 생성
{ path: "/detail", component: () => import("../views/DetailPage.vue") },
];
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes,
});
export default router;
이걸 보면
임포트 먼저 해주고 부르는 방법과
컴포넌트 생성을 화살표 함수로 하는 방법 두 가지가 있는데
보기 편한 걸로 하나로 통일하는 것이 좋다.
src 하위 main.js 수정
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
const app = createApp(App);
app.use(router);
app.mount("#app");
App.vue 수정
<template>
<MenuPage/>
<router-view/>
</template>
<script>
import MenuPage from './components/MenuPage.vue';
export default {
name: 'App',
components: {
MenuPage
}
}
</script>
<style>
</style>
서버를
백그라운드로 (MobaXTerm 창 닫아도)
리눅스때 했어야했지만~
sudo nohup java -jar vue-board-0.4.jar &
nohup
= no hang up
suo lsof -i : 8080
8080 포트가 사용되고 있는지 보기
main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import BootstrapVue3 from 'bootstrap-vue-3'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue-3/dist/bootstrap-vue-3.css'
const app = createApp(App)
app.use(router)
app.use(BootstrapVue3)
app.mount('#app')
부트스트랩 추가했더니
popper js 오류 Can't resolve '@popperjs/core'
~
npm install --save @popperjs/core
실행하고 해결
실제 데이터를 박아넣어 상품목록을 만들자 (import / export)
BoardList.vue
(여기까지는 한 거)
<template>
<div>
<table class="table table-hover">
<thead>
<tr>
<th>번호</th>
<th>제목</th>
<th>글쓴이</th>
<th>날짜</th>
<th>ip</th>
</tr>
</thead>
<tbody>
<tr v-for="n in list" v-bind:key="n.board_no">
<td>{{ n.board_no }}</td>
<td v-text="n.board_title" v-on:click="detail(n.board_no)"></td>
<td>{{ n.mno }}</td>
<td>{{ n.board_date }}</td>
<td>{{ n.board_ip }}</td>
</tr>
</tbody>
</table>
<button @click="$router.push('/write')">글쓰기</button>
</div>
</template>
<script>
import axios from 'axios'
export default {
name: 'BoardList',
data() {
return {
list: [],
}
},
mounted() {
axios.get('http://172.30.1.59:3000/board')
.then((res) => {this.list = res.data.list})
.catch((err) => {alert('문제가 발생했습니다. 다시 시도해주세요.' + err);});
}
}
</script>
서버가 꺼지면 catch 문장이 실행될 것.
detail(n.board_no) 만들어주자.
<script>
import axios from 'axios'
export default {
name: 'BoardList',
data() {
return {
list: [],
}
},
methods: {
detail(bno) {
alert('글 번호는 ' + bno);
}
},
mounted() {
axios.get('http://172.30.1.59:3000/board')
.then((res) => {this.list = res.data.list})
.catch((err) => {alert('문제가 발생했습니다. 다시 시도해주세요.' + err);});
}
}
</script>
methods에 넣어주면 잘 동작한다.
(pdf에 없다)
<script>
import axios from "axios";
export default {
name: "BoardList",
data() {
return {
list: [],
requestBody: this.$route.query, //route로 보내서 사용하게 추가
bno: this.$route.query.bno //추가
};
},
methods:{
detail(bno){
//alert('글 번호는 ' + bno)
this.requestBody.bno = bno //추가
this.$router.push({path: './detail', query: this.requestBody})// bno도 같이 가져가려고 넣어준 거.
}
},
mounted() {
axios.get("http://172.30.1.59:3000/board")
.then(res => {this.list = res.data.list})
.catch(err => {alert("문제가 발생했습니다. 다시 시도해주세요." + err);});
}
};
</script>
requestBody가 중요하니까 bno는 없어도 된다(..)
query는 db의 쿼리가 아니라,, 그냥 이름이 똑같은 거다.
bno값을 담아서 넣을 박스 같은 거
bno도 같이 나온다.
DetailPage.vue 수정.
v-on:click이랑 @click은 똑같다고 한다.
<template>
<div>
<div class="board-detail">
글번호 : {{ detail.board_no }}번글
<button v-on:click="del()">삭제</button>
<button v-on:click="up(detail.board_no)">수정</button><br />
글제목 : {{ detail.board_title }}<br />
글쓴이 : {{ detail.mno }}<br />
쓴날짜 : {{ detail.board_date }}<br />
내 용 : <span v-html="detail.board_content"></span><br />
</div>
</div>
</template>
<script>
import axios from "axios";
export default {
data() {
//변수생성
return {
requestBody: this.$route.query,
detail: {
board_no: this.$route.query.bno,
board_title: "기본",
mno: "기본",
board_content: "기본",
board_date: "기본"
}
};
},
mounted() {
this.boardDetail();
},
methods: {
boardDetail() {
axios.get("http://172.30.1.59:3000/detail?bno=" + this.$route.query.bno)
.then(res => { this.detail = res.data })
.catch(err => {
alert("문제가 발생했습니다. 잠시 후 다시 시도해주세요." + err);
});
}
}
};
</script>
<style scoped></style>
v-html
은 사진같은 게 본문에 있을 수 있으니까
db랑 통신이 안되면 "기본"
axios url 틀리게 해서 깨뜨리면
2가지 방법
BoardList.vue에서
바로 mounted() {}
안에 실행할 코드 적는 거랑
DetailPage.vue에서
methods에 적은 함수를 mounted() {this.함수명()}
이렇게 하는 거
부트스트랩도 클래스명 쓰면 잘 된다
views에 WritePage.vue
<template>
<div class="write">
<h1>글쓰기</h1>
<input v-model="title" />
<textarea v-model="content"></textarea>
<button @click="write">글쓰기</button>
</div>
</template>
<script>
import axios from 'axios';
export default {
name: "WritePage",
data() {
return {
title: null,
content: null
}
},
methods: {
write() {
let saveData = {}
saveData.title = this.title
saveData.content = this.content
saveData.mno = 1
axios.post('http://172.30.1.59:3000/write', JSON.stringify(saveData), {
headers: { "Content-Type": "application/json" }
}).then((res) => alert("통신결과 : " + res.data.result)
).catch((err) => alert('문제가 발생했습니다' + err))
}
}
};
</script>
<style>
.write {
width: 100%;
height: 500px;
background-color: rgb(114, 255, 255);
padding: 10px;
}
.write input {
width: 100%;
height: 30px;
margin-bottom: 5px;
box-sizing: border-box;
}
.write textarea {
width: 100%;
height: 300px;
box-sizing: border-box;
}
</style>
새 페이지 만들면 라우터에 추가해준다.
router/index.js
const routes = [
{ path: "/", component: IndexPage },
{ path: "/boardList", component: BoardList },
{ path: "/login", component: () => import("../views/LoginPage.vue") },
{ path: "/detail", component: () => import("../views/DetailPage.vue") },
{ path: "/write", component: () => import("../views/WritePage.vue") }
];
DetailPage.vue
버튼 클릭 시 del()
함수 실행할 것.
del() {
//alert(bno)
if (confirm("삭제하시겠습니까?")) {
axios({
url: "http://172.30.1.59:3000/del",
method: "post",
params: { bno: this.detail.board_no }
}).then((res) => {
if (res.data.result == 1) {
this.$router.push({ path: "./boardList", query: this.requestBody, });
} else {
alert('문제가 발생했습니다')
}
}).catch((err) => {
alert(err)
})
}
},
이러면 삭제 완료
수정하기까지 하면 crud 끝
난 왜 글이 안불러와질까요