vue 2022/01/24 (새 프로젝트 시작)

무간·2022년 1월 24일

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;
profile
당신을 한 줄로 소개해보세요

0개의 댓글