(참고. https://github.com/19park/mask-finder)
10일 19시부터 건강보험심사평가원에서 제공하는 마스크 정보(판매처별 입고량, 판매량 등)를
공공데이터활용지원센터에서 오픈API형태로 제공해주길래 테스트 해봄.
vue 프로젝트를 하나만들기
vue create mask-finder
모듈 설치해주기
npm i
통신위한 axios와 라우팅위한 vue-router, 전역상태관리위한 vuex 설치하기
npm i axios lodash vue-router material-design-icons-iconfont
npm i -D eslint-config-airbnb-base eslint-plugin-import eslint-plugin-vue
vue add vuetify
vue add vuex
eslint 는 ide 오류떠서 ^5.16.0 버전으로 재설치하면 사라짐
시작해보기
npm run serve
기본적으로 사용하는 보일러플레이트가 있지만, jest나 여러설정들을 빼고 다시세팅..
아래는 기본세팅이 완료 된 package.json 임 ㅋ
{
"name": "mask-finder",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.19.2",
"core-js": "^3.6.4",
"lodash": "^4.17.15",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
"vuetify": "^2.2.11",
"vuex": "^3.1.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.2.0",
"@vue/cli-plugin-eslint": "~4.2.0",
"@vue/cli-plugin-vuex": "~4.2.0",
"@vue/cli-service": "~4.2.0",
"babel-eslint": "^10.0.3",
"eslint": "^5.16.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.20.1",
"eslint-plugin-vue": "^6.2.2",
"sass": "^1.19.0",
"sass-loader": "^8.0.0",
"vue-cli-plugin-vuetify": "~2.0.5",
"vue-template-compiler": "^2.6.11",
"vuetify-loader": "^1.3.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true,
"es6": true
},
"plugins": [
"vue"
],
"extends": [
"airbnb-base",
"plugin:vue/essential",
"eslint:recommended"
],
"rules": {
"import/no-unresolved": "off",
"import/order": "off",
"no-console": "off",
"indent": "off",
"linebreak-style": 0,
"semi": [
2,
"always"
]
},
"parserOptions": {
"parser": "babel-eslint"
}
},
"browserslist": [
"> 1%",
"last 2 versions"
]
}
아래는 route, store 기본세팅하고 main페이지 정의해주고 api를 분리시킨 폴더구조임
실행하면 vuetify 기본템플릿으로 layout낀 화면 확인
이제 api 이용해서 data 뿌려봄
https://www.data.go.kr/dataset/15043025/openapi.do
위 api를 가지고 테스트 해보기전에 로컬이니까 proxy설정해줘야함.
/api 패스를 마스크 api url로 proxy 설정해주고
// vue.config.js
module.exports = {
"transpileDependencies": [
"vuetify"
],
devServer: {
disableHostCheck: true,
proxy: {
'/api/': {
target: "https://8oi9s0nnth.apigw.ntruss.com/corona19-masks/v1",
changeOrigin: true,
pathRewrite: {
'^/api': ''
}
}
}
}
};
아래 mask객체의 fetchByAddr에 넘기는 url엔 api가 없지만
api/common.js에 작성한 request함수이용해서 호출앞 url에 /api 붙여주면 proxy될거임
* 빌드하고나면 proxy안되니 참고
// src/api/index.js
import api from '@/api/common';
function jsonToQueryString(json) {
if (!json) return '';
return '?' +
Object.keys(json).map(function (key) {
if (json[key] instanceof Array) {
let query = [];
for (let i = 0;i < json[key].length;i++) {
query.push(encodeURIComponent(key) + '=' +
encodeURIComponent(json[key][i]));
}
return query.join('&');
} else {
return encodeURIComponent(key) + '=' +
encodeURIComponent(json[key]);
}
}).join('&');
}
export const mask = {
fetchByAddr(data) {
return api.request({
method: 'get',
url: `/storesByAddr/json${jsonToQueryString(data)}`
});
}
};
export default mask;
그럼 src/pages/Main.vue 에서 가져와보자..
mask 객체를 import해서 fetchByAddr을 실행해보자..
<template>
<v-container fluid>
{{result}}
</v-container>
</template>
<script>
import {mask} from '@/api';
export default {
name: "Main",
data() {
return {
result: []
};
},
created() {
mask
.fetchByAddr()
.then(res => {
console.log(res.data);
this.result = res.data.stores;
}).catch(console.log);
}
};
</script>
<style scoped>
</style>
음.. 잘가져온다..
조금 보기좋게 바꿔보자..
v-list 사용하고 vuetify icon설정을 md로 세팅한다.
// src/plugins/vuetify.js
import Vue from 'vue';
import Vuetify from 'vuetify/lib';
import 'material-design-icons-iconfont/dist/material-design-icons.css'; // Ensure you are using css-loader
Vue.use(Vuetify);
export default new Vuetify({
icons: {
iconfont: 'md',
},
});
// Main.vue
<template>
<v-container fluid>
<v-list three-line>
<v-subheader>마스크 판매처 정보</v-subheader>
<template v-for="(item, index) in list.items">
<v-list-item
:key="item.code"
@click="() => {}"
>
<v-list-item-content>
<v-list-item-title>{{item.name}}</v-list-item-title>
<v-list-item-subtitle v-html="item.addr"></v-list-item-subtitle>
</v-list-item-content>
<v-list-item-action>
<v-list-item-action-text>{{item.remain_stat | formatStat}}</v-list-item-action-text>
<v-icon
v-if="getStatColor(item.remain_stat)"
:color="getStatColor(item.remain_stat)"
>
star_border
</v-icon>
</v-list-item-action>
</v-list-item>
<v-divider
:key="index"
></v-divider>
</template>
</v-list>
</v-container>
</template>
<script>
import {mask} from '@/api';
export default {
name: "Main",
data() {
return {
list: {
items: []
}
};
},
filters: {
formatStat(stat) {
switch (stat) {
case "plenty": return '100개 이상';
case "some": return '30개이상';
case "few": return '2개이상';
case "empty": return '';
}
}
},
methods: {
getStatColor(stat) {
switch (stat) {
case "plenty": return 'green';
case "some": return 'yellow';
case "few": return 'red';
case "empty": return '';
}
}
},
created() {
mask
.fetchByAddr()
.then(res => {
console.log(res.data);
this.list.items = res.data.stores;
}).catch(console.log);
}
};
</script>
<style scoped>
</style>
리스트 형태로 개수확인해서 색표시까지 해보았다.. (디폴트로 "서울특별시 강남구" 가져옴)
근데 332개 가져오느라 시간이 꽤나 걸린다. 페이징이 없나.. (아직 api 잘 안살펴보긴했음)
lat, lng 도 있어서 지도에도 뿌릴수있을거고, 마커색상도 줄 수 있을것같다.
일단은 조회조건에 address (ex/ 서울특별시 강남구) 형태로 넘길수가 있으니,
조회조건을 ui에 추가해봐야 할듯 싶다.
'프로그래밍 > Vue.js' 카테고리의 다른 글
vuejs 공공데이터 공적 마스크 판매 정보 api 사용해보기 (3) (0) | 2020.03.13 |
---|---|
vuejs 공공데이터 공적 마스크 판매 정보 api 사용해보기 (2) (0) | 2020.03.12 |
Vue.js testing jest 사용해보기 (1) | 2019.02.14 |
Vue.js 테스트 Vuex테스트 (0) | 2019.01.06 |
vuejs handsontable 사용하기 excel table 컴포넌트 (0) | 2018.05.14 |