vue.js/vue.js 2

59. <vue-news> 프로젝트 | API 데이터 출력하는 순서 | axios 순서

DEV-Front 2022. 8. 5. 23:56
반응형

api 폴더의 <index.js>

- 공통 API 함수들 정리

0. axios 연결

import axios from 'axios';


// 1. HTTP Requset & Response 와 관련된 기본 설정
const config = {
    baseUrl: 'https://api.hnpwa.com/v0/'
};

// 2. 공통 API 함수들 정리
function fetchNewsList(){
    // return 바로 해준게 핵심
    // return axios.get(config.baseUrl+'/news/1.json');
    return axios.get(`${config.baseUrl}news/1.json`);
}

function fetchJobsList(){
    return axios.get(`${config.baseUrl}jobs/1.json`)
}

function fetchAskList() {
    return axios.get(`${config.baseUrl}ask/1.json`)
}

function fetchUserInfo(username){
    // https://api.hnpwa.com/v0/user/lnyan.json
    return axios.get(`${config.baseUrl}user/${username}.json`)
}

function fetchCommentItem(id){
    // https://api.hnpwa.com/v0/item/32340433.json
    return axios.get(`${config.baseUrl}item/${id}.json`)
}

// 3. 마지막 내보내기
export { fetchNewsList, fetchJobsList, fetchAskList, fetchUserInfo, fetchCommentItem }

<action.js>

1. 백엔드 API를 actions으로 받고 

import { fetchNewsList,
	fetchAskList,
        fetchJobsList,
        fetchUserInfo,
        fetchCommentItem } from '../api/index.js'

export default { // 1. 백엔드 API를 actions으로 받고 
    FETCH_NEWS(context) {
        fetchNewsList()
            .then(res => {
                context.commit('SET_NEWS', res.data);
            })
            .catch(error => console.log(error));
    },
    FETCH_ASKS({ commit }) {
        fetchAskList()
            .then(({ data }) => {
                commit('SET_ASKS', data);
            })
            .catch(error => console.log(error))
    },
    FETCH_JOBS({ commit }) {
        fetchJobsList()
            .then(({ data }) => {
                commit('SET_JBOS', data);
            })
            .catch(error => console.log(error))
    },
    FETCH_USER({ commit }, name){
        fetchUserInfo(name)
            .then(({ data }) => {
                commit('SET_USER', data);
            })
            .catch(error => console.log(error))
    },
    FETCH_ITEM({ commit }, id) {
        fetchCommentItem(id)
            .then(({ data }) => {
                commit('SET_ITEM', data);
            })
            .catch(error => console.log(error))
    }
}

<mutation.js>

2. mutations으로 데이터 받아서

export default{ // 2. mutations으로 데이터 받아서
        SET_NEWS(state, data) {
            state.news = data;
        },
        SET_ASKS(state, data) {
            state.asks = data;
        },
        SET_JBOS(state, data) {
            state.jobs = data;
        },
        SET_USER(state, data){
            state.user = data;
        },
        SET_ITEM(state, data){
            state.items = data;
        }
    }

store폴더의 <index.js>

3. state에 저장한다

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutation.js';
import actions from './action.js'



Vue.use(Vuex);

// vuex는 상태관리 도구 
// 상태는 여러 컴포넌트 간에 공유되는 데이터 속성
export const store = new Vuex.Store({
    state : { // 3. state에 저장한다.
        news : [],
        asks : [],
        jobs : [],
        user : {},
        items: [],
    },
    getters:{
        fetchedNews(state) {
            return state.news
        },
        fetchedAsk(state){
            return state.asks
        },
        fetchedJobs(state){            
            return state.jobs
        },
        fetchedItem(state){
            return state.items
        }
    },
    mutations, // 2. mutations으로 데이터 받아
    actions // 1. 백엔드 API를 actions으로 받고 
        
})

store폴더의 <index.js>

4. 데이터 보여줄 페이지 만들고

import Vue from 'vue'
import VueRouter from 'vue-router'
import NewsView from '../views/NewsView.vue'
import AskView from '../views/AskView.vue'
import JobsView from '../views/JobsView.vue'
import ItemView from '../views/ItemView.vue'
import UserView from '../views/UserView.vue'

Vue.use(VueRouter);

export const router = new VueRouter({
    mode: 'history', // url #값 제거
    routes: [ //routes도 커졌을때 모듈화 가능
        {
            path: '/',
            redirect: '/news',
        },
        {
            path: '/news', // url에 대한 정보가 담기는곳, url주소
            component: NewsView, // url 주소로 갔을때 표시될 컴포넌트
        },
        {
            path: '/ask',
            component: AskView,
        },
        {
            path: '/jobs',
            component: JobsView,
        },
        {
            path: '/item/:id', // url에 id값 데이터 넘김 
            component: ItemView,
        },
        {
            path: '/user/:id',
            component: UserView,
        },
    ]
});

<AskView.vue>

/item/:id → `item/${item.id}`

router-link로 기사 제목 클릭하면 상세페이지 들어가게

<template>
    <div>
        <!-- <div v-for="(ask, i) in fetchedAsk" v-bind:key="i"> {{ ask.title}} </div> -->
        <p v-for="(item, i) in fetchedAsk" v-bind:key="i">
            <!-- v-bind:href 축약-->
            
            <router-link v-bind:to="`item/${item.id}`">
                {{ item.title }}
            </router-link>
            <small>{{ item.time_ago }}, {{ item.user }}</small>
        </p>
    </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
    computed:{
        // 3.
        ...mapGetters(['fetchedAsk'])
    
    // 2.
    // ...mapGetters({ //객체, 배열 풀어서 넣는 역할
    //     askItems: 'fetchedAsk'
    // })

    // 1.   
    //   ...mapState({
    //       asks: state => state.asks
    //   })
     },
   created(){
       this.$store.dispatch('FETCH_ASKS');
   }
};
</script>

<style lang="scss" scoped>

</style>

<ItemView.vue>

<template>
    <div>

        <section>
            <!--질문 상세정보-->
            <div class="user-container">
                <div>
                    <i class="fa-solid fa-user"></i>
                </div>
                <div class="user-description">
                    <router-link :to="`/user/${fetchedItem.user}`">{{ fetchedItem.user }}</router-link>
                    <div class="time">
                        {{ fetchedItem.time_ago }}
                    </div>
                </div>
            </div>

            <h2>{{ fetchedItem.title }}</h2>
        </section>

        <section>
            <!--질문 댓글-->
            <div v-html="fetchedItem.content"></div>
        </section>
    </div>
</template>

<script>
import { mapGetters } from 'vuex';

export default {
    computed:{
        ...mapGetters(['fetchedItem'])
    },
   created(){
      const itemId = this.$route.params.id; // router-link로 넘긴 데이터 받을때
       this.$store.dispatch('FETCH_ITEM', itemId); // actions에 보내는 dispatch
   }
};
</script>

<style scoped>

.user-container{
    display: flex;
    align-items: center;
    padding: 0.5rem;
}
.fa-user{
    font-size: 2.5rem;
}
.user-description{
    padding-left: 8px;
}
.time{
    font-size: 0.7rem;
}
</style>
반응형