Client/VueJS 3.0

Axios로 데이터 받아서 state, store 사용하기

Juzdalua 2022. 5. 10. 10:54

DB에 저장된 데이터들을 배열 리스트로 받아와 출력하고 싶었다.

 

먼저 데이터 타입에 맞게 스토어를 작성한다.

// stire/store.js

import {createStore} from "vuex";

const store = createStore({
    state(){
        return {
            categories: [],
        }
    },

    getters:{
        categories: state => {
            return state.categories;
        }
    },

    mutations:{
        categories: (state, categories) => {
            state.categories = [...state.categories, ...categories];
        },
    },

    actions:{
        categories: (context, categories) => {
            context.commit("categories",categories);
        },
    },
});

export default store;

 

메인에 스토어를 추가한다.

// main.js

import { createApp } from 'vue'
import App from './App.vue'
import store from "./store/store";
import router from "./router/index"

createApp(App)
    .use(store)
    .use(router)
    .mount('#app')

 

vue 페이지를 작성한다.

// article.vue

<template>
<div>
    <form class="upcomingForm" @submit.prevent="onSubmit()">
        <input placeholder="TITLE" type="text" v-model="title" required />
        <input placeholder="DESCRIPTION" type="text" v-model="description" required />
        <input placeholder="TAGS" type="text" v-model="tags" required />
        <input placeholder="CONTRACT_ADDRESS" type="text" v-model="contractAddress"  />

        <select v-model="category">
            <option disabled value="0">카테고리</option>
            <option v-for="(item, index) in state.categories" :key="index" :value="item.UID">{{item.NAME}}</option>
        </select>
        <input type="file" id="imageFile" @change="uploadImg()" ref="image" accept="image/*" multiple="multiple" required/>
        <img :src="imagePreview" />
        <input type="submit" value="Submit" />
        <!-- <button type="submit">Sumbit</button> -->
        <button @click="checkStore()">Check Store</button>
    </form>
</div>
</template>

<script>
import axios from "axios";
import { onMounted, reactive, computed } from "vue";
import { useStore } from 'vuex';

export default {
    name: "ArticlePost",
    components: {},
    props:{},
    data(){
        return {
            title: "",
            description: "",
            tags: "",
            contractAddress: "",
            image: "",
            imagePreview: "",
            category: null
        };
    },

    setup(){
        const store = useStore();
        const state = reactive({
            categories: computed(() => store.getters["categories"]),
        });

        onMounted( async() => {
            const categories = await axios.get("http://localhost:4000/discover/category")
            if(categories.status === 200)
                store.dispatch("categories", categories.data);
        });

        return {
            state
        };
    },

    methods: {
        checkStore(){
            console.log(this.state.categories)
            console.log(this.$store.getters["categories"])
        },

        uploadImg(){
            // form data
            const image = this.$refs['image'].files[0];
            this.image = image;

            // preview
            const objectUrl = URL.createObjectURL(image);
            this.imagePreview = objectUrl;
        },

        async onSubmit(){

            const body = {
                title: this.title,
                description: this.description,
                tags: this.tags,
                contractAddress: this.contractAddress,
                category: this.category,
                cover: this.image,
            };

            let form = new FormData();
            for(const key of Object.entries(body)){
                form.append(key[0], key[1]);
            }

            try {
                const result = await axios.post(`http://localhost:4000/discover/article`, form);
                console.log(result)
                if(result.data.success){
                    alert("성공~!");
                    this.title = "",
                    this.description = "",
                    this.tags = "",
                    this.contractAddress = "",
                    this.category = "",
                    this.imagePreview = ""
                }
            } catch (error) {
                alert("실패")
                return ;
            }

        },
    },
}
</script>

<style>
    .upcomingForm{
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        padding: 10px;
    }

    .upcomingForm > input, select, label{
        margin-top: 5px;
        padding: 5px 10px;
        width: 500px;
    }
</style>

페이지가 마운트되면 BE DB에 접근하여 데이터를 가져온다. 해당 데이터를 store/state에 저장한다.

template에서는 데이터 배열을 item으로 받고 for문을 수행하여 해당 데이터들의 길이만큼 출력한다.

 

 

데이터를 받아 선택하고 폼을 전송하면 해당 value값이 전송된다.

 

Check Store 버튼을 클릭하여 데이터 형식을 확인할 수 있다.

'Client > VueJS 3.0' 카테고리의 다른 글

Vue3) Youtube iframe 영상 재생  (0) 2022.07.12
Vue3) Tailwind css 적용하기  (0) 2022.07.11
CSS) Box Shadow  (0) 2022.07.07
vue-router 사용하기. 페이지 이동  (0) 2022.05.03
VueJS 3.0 개념 익히기  (0) 2022.04.29