cmd> vue create vue_20220124 // 새 프로잭트 생성 3버전
생성된폴더(vue_20220124)로 이동후
-- router 사용
CMD> npm install vue-router@next --save
-- store 사용
CMD> npm install vuex@next --save
-- axios 사용
CMD> npm install axios --save
-- element-plus ui 사용
CMD> npm remove element-plus --save <= 필요시
CMD> npm install element-plus@1.2.0-beta.6 --save
-- 서버구동
CMD> npm run serve
====================================================
파일명 src/routes/insex.js
// npm install vue-router@next --save
import { createWebHashHistory, createRouter } from "vue-router";
// 라우터 설정하기
import Home from '@/components/Home.vue';
import Board from '@/components/Board.vue';
import Login from '@/components/Login.vue';
import Admin from '@/components/Admin.vue';
const routes = [
{ path : '/', name: "Home", component:Home },
{ path : '/login', name: "Login", component:Login },
{ path : '/board', name: "Board", component:Board },
{ path : '/admin', name: "Admin", component:Admin },
]
// localhost : 8080/#/
// 127.0.0.1:8080/#/login
// 127.0.0.1:8080/#/board
// 라우터 생성 (주소표기방식, 라우터 설정 변수)
const router = createRouter({
history : createWebHashHistory(), // 127.0.0.1:8080/#/login
routes : routes
})
// 라우터 이동 경로 확인 (이동하는 페이지, 이동전 페이지, 다음페이지로 이동)
router.beforeEach((to, from, next) => {
console.log('이동하는 페이지:', to);
console.log('이동전 페이지:', from);
next(); // 다음페이지로 이동
})
export default router;
====================================================
파일명 src/main.js
import { createApp } from 'vue'
import App from './App.vue'
// router 설정
import routes from './routes/index.js';
// stores 설정
import stores from './stores/index.js';
// element-plus 설정
import ElemtntPlus from 'element-plus';
import 'element-plus/theme-chalk/index.css'
// 1. 객체 생성
const app = createApp(App);
// 2. 여기에 필요한 라이브러리 설정하기
app.use(routes);
app.use(stores);
app.use(ElemtntPlus);
// 3. 마운트
app.mount('#app');
====================================================
파일명 src/App.vue
<template>
<div>
<!-- ElMenu.vue -->
<!-- props로 default-active숫자값을 전달 -->
<!-- props로 router TRUE값을 전달 -->
<!-- 자식컴포넌트 emit 를 통해서 select이벤트 -->
<el-menu :default-active="state.activeIndex"
class="el-menu-demo"
mode="horizontal"
:router="true"
@select="handleSelect">
<el-menu-item index="/">Home</el-menu-item>
<el-menu-item index="/login">Login</el-menu-item>
<el-menu-item index="/board">Board</el-menu-item>
<el-menu-item index="/admin">Admin</el-menu-item>
</el-menu>
{{menu}},{{logged}}
<hr />
<router-view></router-view>
</div>
</template>
<script>
import {useStore} from 'vuex';
import {computed, reactive} from 'vue';
export default {
setup () {
const store = useStore();
// store값 가져오기
// 마지막으로 방문한 페이지를 session저장소에 보관후에 변환
const menu = computed(()=>{
return store.getters.getMenu
});
const logged = computed(()=>{
return store.getters.getLogged
});
// store에서 읽은 메뉴값으로 초기값으로 세팅
const state = reactive({
activeIndex : menu
})
// store값 변경하기
const handleSelect = (idx) =>{
console.log(idx);
// 메소드명,value 값
store.commit("setMenu", idx);
}
// store의 state 변수가 변경되는 시점을 바로 알 수 있음.
store.subscribe((mutation, state) => {
console.log('store.subscribe',mutation,state);
})
return {state, menu, logged, handleSelect}
}
}
</script>
<style lang="scss" scoped>
</style>
====================================================
파일명 src/component/Login.vue
<template>
<div>
<h3>src/component/Login.vue</h3>
{{state}}
<hr />
<input type="text" v-model="state.userid"/>
<input type="password" v-model="state.userpw"/>
<input type="button" value="로그인" @click="handleLogin"/>
</div>
</template>
<script>
import { reactive } from 'vue'
export default {
// ver 3.0
setup () { // this를 사용할 수 없음
const state = reactive({
userid : 'aaa',
userpw : 'bbb',
});
const handleLogin = () => {
console.log('로그인 버튼 클릭됨',state.userid,state.userpw);
};
return {state, handleLogin}
},
/*
// state변수 ver 2.0
data(){
return{
state:{
userid:'aaa',
userpw:'bbb'
}
}
},
methods:{
handleLogin(){
// 벡엔드 연동
}
}
*/
}
</script>
<style lang="scss" scoped>
</style>
====================================================
파일명 src/component/Board.vue
<template>
<div>
<h3>src/component/Board.vue</h3>
<table border="1">
<thead>
<tr>
<th>no</th>
<th>title</th>
<th>writer</th>
<th>hit</th>
</tr>
</thead>
<tbody>
<tr v-for="tmp in state.items.result" :key="tmp">
<td>{{tmp.no}}</td>
<td>{{tmp.title}}</td>
<td>{{tmp.writer}}</td>
<td>{{tmp.hit}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import {onMounted, reactive} from 'vue';
export default {
setup () {
const state = reactive({
items : {},
});
// 생명주기 onMounted()
onMounted(() => {
// 백엔드로 데이터를 받음
state.items.result = [
{ no:1, title:'가1', writer :'b', hit:14},
{ no:2, title:'가2', writer :'c', hit:24},
{ no:3, title:'가3', writer :'d', hit:34},
];
console.log(state.items.result);
});
return {state}
},
}
</script>
<style lang="scss" scoped>
</style>
====================================================
파일명 src/component/Admin.vue
<template>
<div>
<h3>src/component/Admin.vue</h3>
{{menu}}
<button @click="handleMenu(1)">메뉴1</button>
<button @click="handleMenu(2)">메뉴2</button>
<button @click="handleMenu(3)">메뉴3</button>
<button @click="handleCount">1씩 증가</button>
<hr />
<menu-1 v-if="menu.code ===1"
title="메뉴111" :count="count.value" @handleCount="handleCount"></menu-1>
<menu-2 v-if="menu.code ===2"
title="메뉴222" :count="count.value" @handleCount="handleCount"></menu-2>
<menu-3 v-if="menu.code ===3"
title="메뉴333" :count="count.value" @handleCount="handleCount"></menu-3>
<!-- title 을 String으로 불러옴 -->
<!-- count 앞메 : 이 있으면 count.value 를 가지고 와야함(:는 변수로 생각함) -->
<!-- @handleCount="handleCount" 부모와 자식 components의 handleCont를 자식으로 보냄-->
</div>
</template>
<script>
// import 시킴
import Menu1 from './admin/Menu1.vue';
import Menu2 from './admin/Menu2.vue';
import Menu3 from './admin/Menu3.vue';
import { reactive } from '@vue/reactivity';
export default {
// import 시킨것
components:{
Menu1, Menu2, Menu3
},
setup () { // setup = created
// state 변수 생성
const menu = reactive(
{ code:1 }
);
// count.value
const count = reactive(
{value : 1}
);
// handleMenu 메소드
const handleMenu = (idx) =>{
console.log(idx);
menu.code = idx;
}
// count.calue 값을 1씩 증가
const handleCount = () =>{
count.value++;
}
return {menu,count, handleMenu, handleCount}
}
}
</script>
<style lang="scss" scoped>
</style>
====================================================
파일명 src/component/admin/Menu1.vue
<template>
<div>
<h3>src/component/admin/Menu1.vue</h3>
{{props}}
<hr />
<button @click="handleCount">부모메소드 호출 후 값 증가 시키기</button>
<el-button type="danger">Primary</el-button>
</div>
</template>
<script>
export default {
// 부모 컴포넌트에서 전달되는 값을 보관
props:{
title : String,
count : Number,
},
setup (props,{emit}) { // emit 부모의 메서드르 사용하기 위해 사용함
console.log(props.title);
const handleCount = () =>{
// 부모의 @handleCount = "실제호출 메소드"가 반응
emit('handleCount',{});
};
return {props, handleCount}
},
}
</script>
<style lang="scss" scoped>
</style>
====================================================
파일명 : src/stores/index.js
// npm install vuex@next --save
// 파일명 : src/stores/index.js
import {createStore} from "vuex"
// 모든 컴포넌트에서 공통으로 사용할 변수 설정
// props 와 emit 를 여기에서 처리함
const stores = createStore({
// 공통 상태 변수
state : {
menu : sessionStorage.getItem("CURL"),
logged : false,
},
//가져가기 (getter)
getters : {
getMenu(state){
return state.menu;
},
getLogged(state){
return state.logged;
}
},
// 변경하기 (mutation) : 증시변경
mutations:{
setMenu(state,value){
state.menu = value;
},
setLogged(state,value){
state.logged = value;
}
},
// 변경하기(action) : 기다려야 되는 상황
actions:{
},
});
export default stores;