반응형
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>
반응형
'vue.js > vue.js 2' 카테고리의 다른 글
61. <vue-news> 프로젝트 | 1차 완성 (0) | 2022.08.06 |
---|---|
60. <vue-news> 프로젝트 | Router 트렌지션 (0) | 2022.08.06 |
58. <vue-news> 프로젝트 | Dynamic Route Matching | 동적 라우트 매칭 (0) | 2022.08.05 |
57. 첫번째 비동기처리 방법 collback | promise (0) | 2022.08.05 |
56. JavaScript의 this (0) | 2022.08.05 |