본문 바로가기
개발 관련 지식/SpringBoot-Vue

SpringBoot - Vue project 3. Vue 프로젝트 구성

by 권태일1147 2020. 3. 27.

 

먼저 http Client를 초기화하기 위해 axios를 설치한다.

터미널에서 vue 폴더로 이동하고 npm install axios를 입력한다.

 

그리고 http-common.js 파일을 다음과 같이 만들어서 http Client를 초기화 한다.

import axios from 'axios';

export default axios.create({
  baseURL: 'http://localhost:8080/_api',
  headers: {
    'Content-type': 'application/json',
  },
});

 

 

router

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'

import UserList from "../components/UserList.vue"
import AddUser from "../components/AddUser.vue"
import SearchUser from "../components/SearchUser.vue"

Vue.use(VueRouter)

const routes = [
  {
    path: "/userList",
    name: "userList",
    component: UserList,
  },
  {
    path: "/addUser",
    name: "addUser",
    component: AddUser
  },
  {
    path: "/searchUser",
    name: "searchUser",
    component: SearchUser
  }
]

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes
})

export default router

 

 

store

store/index.js

import Vue from 'vue'
import Vuex from 'vuex'
import http from '../http-common'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        userList: [],
        searchedUser: {},
    },
    mutations: {
        setUserList(state, payload) {
            state.userList = payload;
        },
        setSearchedUser(state, payload) {
            state.searchedUser = payload;
        }
    },
    actions: {
        readUserList(store) {
            http.get('/userList')
                .then(response => {
                    store.commit('setUserList', response.data)
                })
                .catch(error => {
                    console.log(error)
                })
        },
        addUser(store, userInfo) {
            http.post('/user', userInfo)
                .then(() => {})
                .catch(error => {
                    console.log(error)
                })
        },
        updateUserActive(store, userInfo) {
            http.put(`/user/${userInfo.id}`, userInfo)
                .then(() => {})
                .catch(error => {
                    console.log(error)
                })
        },
        deleteUser(store, userId) {
            http.delete(`/user/${userId}`)
                .then(() => {
                    store.dispatch('readUserList')
                })
                .catch(error => {
                    console.log(error)
                })
        },
        searchUser(store, userAge) {
            http.get(`/users/age/${userAge}`)
                .then(response => {
                    store.commit('setSearchedUser', response.data)
                })
                .catch(error => {
                    console.log(error)
                })
        }
    },
    getters: {
        userList: state => {
            return state.userList
        },
        searchedUser: state => {
            return state.searchedUser
        }
    }
})

 

 

 

App.vue

<template>
  <div id="app">
    <div>
      <h3>Vue SpringBoot H2 CRUD example</h3>
    </div>
    <nav>
      <button class="mr-15" @click="$router.push('/userList').catch(()=>{})">User List</button>
      <button class="mr-15" @click="$router.push('/addUser').catch(()=>{})">Add User</button>
      <button class="mr-15" @click="$router.push('/searchUser').catch(()=>{})">Search User</button>
    </nav>
    <br/>
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}

  .mr-15 {
    margin: 15px;
  }
</style>

 

 

UserList.vue

<template>
    <div class="list">
        <div>
            <h4>User List</h4>
            <ul>
                <li v-for="(user, index) in userList" :key="index">
                    <div @click="userDetail(user)">
                        {{user.name}}
                    </div>
                </li>
            </ul>
        </div>
        <div>
            <userDetail :user="userInfo" @initUserDetail="initUserDetail"></userDetail>
        </div>
    </div>
</template>

<script>
    import userDetail from './UserDetail'
    import {mapActions, mapGetters} from 'vuex'
    export default {
        name: "UserList",
        data(){
            return {
                userInfo: null
            }
        },
        methods: {
            ...mapActions(['readUserList']),
            userDetail(user){
                this.userInfo = user
            },
            initUserDetail(){
                this.userInfo = null
            }
        },
        computed:{
            ...mapGetters(['userList']),
        },
        components:{
            userDetail
        },
        mounted(){
            this.readUserList()
        }

    }
</script>

<style scoped>
    .list {
        text-align: left;
        max-width: 450px;
        margin: auto;
    }
</style>

 

 

UserDetail.vue

<template>
    <div v-if="this.user">
        <h4>Customer</h4>
        <div>
            <label>Name: </label> {{this.user.name}}
        </div>
        <div>
            <label>Age: </label> {{this.user.age}}
        </div>
        <div>
            <label>PH: </label> {{this.user.ph}}
        </div>
        <div>
            <label>Active: </label> {{this.user.active}}
        </div>
        <button v-if="this.user.active"
              v-on:click="updateUser(false)"
              class=''>Inactive</button>
        <button v-else
              v-on:click="updateUser(true)"
              class="">Active</button>
        <button class="" @click="deleteUserId(user)">Delete</button>
    </div>
    <div v-else>
        <br/>
        <p>Click on a User</p>
    </div>
</template>

<script>
    import { mapActions } from 'vuex'
    export default {
        name: "User",
        props:["user"],
        methods: {
            ...mapActions(['deleteUser', 'updateUserActive']),
            updateUser(status){
                this.user.active = status;
                this.updateUserActive(this.user)
            },
            deleteUserId(user){
                this.deleteUser(user.id)
                this.$emit('initUserDetail')
            }
        },
    }
</script>

<style scoped>

</style>

 

 

AddUser.vue

<template>
    <div>
        <div class="input-box-wrapper" v-if="!submitted">
            <div class="mr-10">
                <label for="name">Name</label>
                <input type="text" id="name" required v-model="user.name" name="name">
            </div>
            <div class="mr-10">
                <label for="age">Age</label>
                <input type="number" id="age" required v-model="user.age" name="age">
            </div>
            <div class="mr-10">
                <label for="age">PH</label>
                <input type="text" id="ph" required v-model="user.ph" name="ph">
            </div>
            <button v-on:click="saveCustomer">Save</button>
        </div>

        <div v-else>
            <h4>You submitted successfully!</h4>
            <button v-on:click="newCustomer">Add</button>
        </div>
    </div>
</template>

<script>
    import { mapActions } from 'vuex'
    export default {
        name: "AddUser",
        data(){
            return {
                submitted: false,
                user:{}
            }
        },
        methods:{
            ...mapActions(['addUser']),
            saveCustomer(){
                this.addUser(this.user)
                this.submitted = true
            },
            newCustomer(){
                this.user = {}
                this.submitted = false
            }
        },
    }
</script>

<style scoped>
    .input-box-wrapper{
        margin: auto;
        text-align: left;
        max-width: 250px;
    }
    .mr-10{
        margin: 10px;
    }
</style>

 

 

SearchUser.vue

<template>
    <div>
        <h4>Find by Age</h4>
        <div>
            <input type="number" id="age" required v-model="age" name="age">
        </div>
        <div>
            <button v-on:click="searchUserInfo">Search Age</button>
        </div>
        <div class="info-wrapper" v-for="(user, index) in searchedUser" :key="index">
            <h6>name : {{user.name}}</h6>
            <h6>age  : {{user.age}}</h6>
            <h6>ph   : {{user.ph}}</h6>
        </div>
    </div>
</template>

<script>
    import { mapActions, mapGetters } from 'vuex'
    export default {
        name: "SearchUser",
        data(){
            return {
                age: null,
            }
        },
        methods:{
            ...mapActions(['searchUser']),
            searchUserInfo(){
                this.searchUser(this.age)
            }
        },
        computed:{
            ...mapGetters(['searchedUser'])
        }
    }
</script>

<style scoped>
.info-wrapper{
    border: 1px solid black;
}
</style>

 

 

 

github : https://github.com/workerKwon/Springboot-Vue-H2DB