title | date | categories | tags | ||||
---|---|---|---|---|---|---|---|
Vue Master |
2021-12-06 |
|
|
vue-master{:target="_blank"}
$ sudo apt update
$ sudo apt install nodejs // node download
$ nodejs -v // read version
$ sudo apt install npm // npm(node manager) download
sudo apt install git-all
- vetur, TSLInt, ESLint, auto close tag, Metarial icon thema, Night owl
- vscode git ๊ถํ์ค์ : https://hyeo-noo.tistory.com/184
https://vuejs.org/v2/style-guide/
- ์๋ต
- ์๋ต
-
vue-cli2
์์๋ webpack ์ค์ ํ์ผ์ด ๋๋ฌ๋์์ -
ํ๋ก์ ํธ ๋ด node_modules ๊ฐ ์ถ๊ฐ๋์ด ์์ง ์๊ธฐ ๋๋ฌธ์ ์ด๊ธฐ์ npm install ํ์ํจ.
-
gitHub์์ ํฌํ๋ฆฟ์ ๋ค์ด๋ฐ๋ ํ์์ผ๋ก ์.
vue-cli3
์ webpack ์ค์ ํ์ผ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ด๋ถ์์ ์์์ ์ฒ๋ฆฌ๋จ. ๋ ธ์ถX. โ webpack ์ค์ ํ๋ ค๋ฉด ์ง์ ์ถ๊ฐ.- ํ๋ฌ๊ทธ์ธ์ ์ฌ์ฉํด์ ์ํ๋ ๊ธฐ๋ฅ์ ์ถ๊ฐํ ์ ์๋๋ก ํจ.
- preset์ผ๋ก ๊ตฌ์ฑ ์ ํ ๊ฐ๋ฅ
-
์๋ฐ์คํฌ๋ฆฝํธ ์์ง์ด ์ฝ๋๋ฅผ ๋ถ์ํ๋ฉฐ ๋ง์ง๋ง์ ;๋ฅผ ๋ฃ์ด์ค โ ;๋ฅผ ๋ถ์ด์ง ์์๋ ์ฝ๋ ๋์์ ๋ฌด๋ฆฌ๊ฐ ์์
-
ํ์ง๋ง ;๋ฅผ ์ฐ๊ฒ๋ ์ ๋ํจ โ ์๋ฐ์คํฌ๋ฆฝํธ ํด์๊ธฐ๊ฐ ํผ๋์ ํ ์๋ ์๊ธฐ ๋๋ฌธ
-
๊ฐ์ฑ ๋ด ํ ์์ด ์ค๋ ๊ฒฝ์ฐ์๋ ,๋ฅผ ์ฐ์ง ์์๋ ๋จ
-
๋ ๋ฒ์งธ ์์ด ์ค๋ ๊ฒฝ์ฐ ,๋ฅผ ์ฐ์
โ ESLint : ์ค๋ฅ๊ฐ ์๋ ์ฝ๋๋ฅผ ์ ๋ํ๊ธฐ ์ํ ์ฅ์น.
-
ESLInt ์ค์
-
ESLint๋ฅผ ๋ค์ ๋ช ๋ น์ด๋ก ์ปดํฌ๋ํธ์ ์ถ๊ฐํ ์ ์์ง๋ง, ์๊ฐ ๋ง์์ง ์๋ก ๋ฒ๊ฑฐ๋ก์.
eslint-disable-next-line eslint-disable
-
๋ค๋ฅธ ๋ฐฉ๋ฒ : vue.config.jsํ์ผ ์์ฑ
// vue.config.js module.exports = { lintOnSave: false }
npm
i
vue - router--
save
-
package.json์
dependencies
: ์ฑ์ ์คํ์ํค๋ ๋ฐ ํ์ํ ๋น์ง๋์ค ๋ก์ง, ์ฑ์ ๋์์ ๋ด๋นํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํฌํจ๋จ. (๋ฐฐํฌํ ๋๋ ํฌํจ๋์ด์ผ ํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ)
- ๋ผ์ฐํฐ๋ฅผ
main.js์ ์ค์
ํจ. - main.js๋ ๊ฐ๋ฐ์๊ฐ ํ๋ก์ ํธ ๊ตฌ์กฐ, ๋ผ์ด๋ธ๋ฌ๋ฆฌ, ๋ฑ์ ํ๋์ ๋ณผ ์ ์๋ ํ์ผ์ด๋ฏ๋ก,
router๋ฅผ ๋ณ๋ ํด๋์ ๋บ
. - router๊ฐ์ฒด๋ฅผ ๋ง๋ค๊ณ ๊ทธ ์์ routes์ ๋ณด๋ฅผ ์ธํ
ํจ. ์ฌ๊ธฐ์,
path์ ๋ํ component
๋ page์ ๊ฐ๋ ๊ณผ ๊ฐ์. โ ์ด page๋ค์viewsํด๋๋ฅผ ๋ง๋ค์ด ๊ทธ ์์์ ๊ด๋ฆฌ
ํจ. - view page component๋ฅผ importํด์ component์ ๋ฃ๊ธฐ
- router๋ฅผ export ํด์ main.js์ importํ ๋ค์ vue ๊ฐ์ฒด์ ๋ฃ๊ธฐ
-
App.vue
<template> <div id="app"> <router-view></router-view> </div> </template>
-
๋ ๊ฐ์ง import, export ๋ฐฉ๋ฒ
// router/index.js const router = new VueRouter({ ... }); export default router; // main.js import router from './router/index'
// router/index.js export const router = new VueRouter({ // main.js import { router } from './router/index'
-
์ปดํฌ๋ํธ ์ด๋ฆ ์ฝ๋ฉ ์คํ์ผ
- ๋ก ์จ์ผ ํ๋ ์ด์ : alt+์ปดํฌ๋ํธ ํด๋ฆญํ๋ฉด ํด๋น ์ปดํฌ๋ํธ๋ก ๋์ด๊ฐ ์ ์์ด์ ๋ ํธ๋ฆฌ.
- ์๋ต
- router ํด๋๋ฅผ routes๋ก ๋ฐ๊ฟ
- mode: history ์ถ๊ฐ
- views์ ๋ค์ด๊ฐ๋ page(์ปดํฌ๋ํธ)๋ด์๋ ํ์ด์ง ๋ผ์ฐํ ์ ๊ด๋ จ๋ ์ ๋ณด๋ง ํฌํจ์ํค๋ ๊ฒ ์ข๋ค.
- views์ ๋ฐ์ดํฐ ํจ์น ๋ฑ ๋ก์ง์ด ํฌํจ๋์ด ์์ผ๋ฉด ์ ์ข์. โ ๋ณ๋์ ์ปดํฌ๋ํธ์์ ๋ก์ง ๋ถ๋ฌ์ค๊ธฐ.
- ์ฌ๊ธฐ์๋ ์ค์ต์ ์ํด ์ผ๋จ views์ ์ฝ๋๋ฅผ ์ฐ๊ณ ๋์ค์ ๊ฐ์ .
- axios ์ค์น
npm
install
axios
// http, xhr ๋ฑ์ ํธํ๊ฒ ์ธ ์ ์๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
08_[์ค์ต ์๋ด] axiosแแ ด api แแ กแทแแ ฎ ๊ตฌ์กฐํ แแ กแผแแ ฅแธ แแ ตแพ แแ ตแฏแแ ณแธ แแ กแซแแ ข
- NewsView์ axios ๋ก์ง /api/index๋ก ์ฎ๊น
axios.get('https://api.hnpwa.com/v0/news/1.json')
.then(res => {
console.log(res.data)
this.users = res.data;
})
.catch(error => console.log(error));
// ==> // new Promise()
// .then(function(response) {
// console.log(response);
// })
// .catch(function() {
// })
-
๋ค๋ฅธ ์ธ์ด๋ ์ง์ญ scope๋ก ์์ํ๋ค๋ฉด, ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ ์ญ scope๋ก ์์ํจ.
-
์ฒซ๋ฒ์งธ this :๊ทธ๋ฅ this
-
๋๋ฒ์งธ this : ํจ์ ์ this
- ํจ์ ์์์๋ this๋ ์ ์ญ์ ๊ฐ๋ฆฌํด
-
์ธ๋ฒ์งธ this : Vue์์ฑ์ ํจ์ ์์ฑ
function Vue(el) { console.log(this); // => Vue {} // ๋น๋๊ธฐ์ฒ๋ฆฌ์์์ this this.el = el; }
sum ํจ์
์ this๊ฐ์ ์ญ
์ ๊ฐ๋ฆฌํค๋ ๊ฒ๊ณผ ๋ค๋ฅด๊ฒVue ์์ฑ์
์ this๋ํจ์ ์์ฒด
๋ฅผ ๊ฐ๋ฆฌํด.
-
NewsView
- ํธ์ถ ์ ์๋ vue component, ํธ์ถ ํ์๋ undefined๋ฅผ ๊ฐ๋ฆฌํด.
- http๋ก ์๋ฒ์ ๊ฐ๋ค์ค๊ธฐ ๋๋ฌธ์ ๋น๋๊ธฐ๋ก ํธ์ถ๋จ โ ํ์ฌ ์์น์์ ๋ฒ์ด๋ this๊ฐ ๋ฐ์(์๋ฐ์คํฌ๋ฆฝํธ ๊ธฐ๋ณธ ๋์ ๋ฐฉ์)
- ์ปดํฌ๋ํธ, ๊ฐ์ฒด ๋ฑ์ ๊ฐ๋ฆฌํค๊ณ ์ถ์ ๋๋
var vm = this;
๋ฅผ ์ฌ์ฉํ์. โ ๋ฐ์ธ๋ฉ์ ํด์ค์ผ ํ๋ ๋ฒ๊ฑฐ๋ก์์ด ์์.
-
ES6 ํ์ดํ ๋ฌธ๋ฒ์ผ๋ก ๋ฐ๊ฟ์ ๋ค์ ์ฝ์ ์ฐ์ด๋ณด๋ฉด ํธ์ถ ์ ๊ณผ ํ๊ฐ ๊ฐ์ โ
this.user = response.data;
์ this๊ฐ ํธ์ถ๋๋ ์์น์ this๋ฅผ ๊ฐ์ง๊ณ ์ด.
-
callback.html
file:///home/jonah/Documents/vue-master/vue-master-cli3/src/callback.html
- ํจ์ ๊ฒฐ๊ณผ(3)์ด ๋จผ์ ๋์ค๊ณ ๋ฐ์ดํฐ ํธ์ถ ๊ฒฐ๊ณผ(2)๊ฐ ๋์ค์ ๋์์, result ๊ฐ์ฒด ์์ ๊ฐ์ด ๋ค์ด๊ฐ์ง ์์. โ ์๋ฐ์คํฌ๋ฆฝํธ ๋น๋๊ธฐ์ฒ๋ฆฌ ๋๋ฌธ.
- ajax ๋ฐ์ดํฐ ์์ฒญ์ด ๊ฐ๊ณ ๋์, ๊ธฐ๋ค๋ฆฌ์ง ์๊ณ ๋ค์ ์ฝ๋๋ฅผ ์คํ โ ๋น๋๊ธฐ์ฒ๋ฆฌ ์ฝ๋ฐฑํจ์.
-
์ฝ๋ฐฑ์ ์ฒ๋ฆฌํ๊ณ ๋์, success๊ฐ ๋์ ๋ ๊ฒฐ๊ณผ๋ฅผ ์ฐ์.
- ๋ฐ์ดํฐ ํธ์ถ ๊ฒฐ๊ณผ, ํจ์ ๊ฒฐ๊ณผ๊ฐ ์ฐํ.
-
์ฝ๋ฐฑ ๊ณผ์ ์ด ๋ง์์ง๊ฒ ๋๋ฉด ์ฝ๋ฐฑ ์ง์ฅ์ด ์๊น. ์ฝ๋ฉ ์ฌ๊ณ ์ ์๋ฐฐ.
-
Promise : ์ฝ๋ฐฑ ๊ด๋ฆฌ๋ฅผ ํจ์จ์ ์ผ๋ก ํ๊ณ , ์ฝ๋๋ฅผ ์ง๊ด์ ์ผ๋ก ์ง๊ธฐ ์ํด ๋ฑ์ฅ.
// ajax call function function callAjax() { return new Promise(function (resolve, reject) { // Promise must get parameter named resolve and reject $.ajax({ // ajax call url: 'https://api.hnpwa.com/v0/news/1.json', success: function (data) { resolve(data); // when ajax call success, resolve handle success data } }); }); };
function fetchData() { var result = []; callAjax() // Promise Object call .then(function() { // Promise resolve : Situation when Promise call success console.log('data call result', data); result = data; console.log('function result', result); }) .catch(function(err) { // Promise reject console.log(err); }); }
- new Promise๋ก ์ธํด ์ด๋ค ๋์์ ์คํํ๊ณ ๋์ resolveํ๋ฉด, callAjax์ then์ผ๋ก ์ฐ๊ฒฐ๋จ.
- ์ฆ, callAjax๋ new Promise๋ฅผ ๋ฐํํ๋๋ฐ, ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์์ ๋ฐ์ดํฐ๋ฅผ resolveํ์ ๋, then์์ ๊ตฌ๋ฌธ์ด ์คํ๋จ.
- .then()์ ์ฐ๊ฒฐ์์ผ ์ฒด์ด๋๋ ๊ฐ๋ฅ.
- ์ ์ด์ฟผ๋ฆฌ์๋ Promise ์ฑ๊ฒฉ์ ๋ด์ฅ ๊ฐ์ฒด(๋ํผ๋)๊ฐ ์์ง๋ง, ๋ณด์์ด ํ์ํจ
- ํ๋ก๋ฏธ์ค ์ฝ๊ฒ ์ดํดํ๊ธฐ ๊ธ ์ฃผ์
- Promise MDN ์ฃผ์
Vuex แแ ฅแฏแแ ต แแ ตแพ Vuexแแ ก แแ ฅแจแแ ญแผแแ ฌแซ แแ ขแธ แแ ฎแแ ฉ แแ ฉแแ ข
-
๊ตฌ์กฐ๋
- NewView์์ api๋ฅผ ๋ฐ๋ก ๋ถ๋ฌ์ค๋ ๊ฒ ์๋๋ผ, vuex๋ผ๋ ์ํ, ์ฆ state์ api๋ฅผ ๋ด์ ์ด
-
vuex : ์ํ ๊ด๋ฆฌ ๋๊ตฌ. ์ฌ๋ฌ ์ปดํฌ๋ํธ ๊ฐ ๊ณต์ ๋๋ ๋ฐ์ดํฐ ์์ฑ.
- state๋ฅผ ์ด์ฉํด, NewsView๊ฐ users๋ผ๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ๊ณต์ ํ ์ ์๊ฒ ๋จ.
- ์๋ต
-
api์์ actions ํธ์ถ, actions์์ mutations ํธ์ถ, mutations์์ state ๊ฐ์ ๋ณํํ ๋ค์ NewsView์ ์ ์ฉ.
- ์๋ต
- ์๋ต
[แแ ตแฏแแ ณแธ] map แแ ฆแฏแแ ฅ แแ กแทแแ ฎแ แ ณแฏ แแ ตแแ ญแผแแ กแซ AskView แแ ฎแฏแแ ต
- ์๋ต
- ์๋ต
- ์๋ต
14_แแ ฉแผแแ ฅแจ แ แ กแแ ฎแแ ณ แแ ขแแ ตแผ แแ ฏแซแ แ ต แแ ตแพ แแ ฅแจแแ ญแผ
-
https://router.vuejs.org/kr/guide/essentials/dynamic-matching.html
-
์์ด๋๊ฐ path๋ก ๋์ด์ด
<router-link :to="`/user/${news.user}`">{{ news.user }}</router-link>
15_แ แ กแแ ฎแแ ฅ paramsแแ ณแฏ แแ ตแแ ญแผแแ กแซ User แแ กแผแแ ฆ แแ ฆแแ ตแแ ต แแ ฎแแ งแซ
-
mapActions 2๊ฐ์ง ๋ฐฉ๋ฒ
created() { console.log(this.$route.params.id); const userName = this.$route.params.id; this.$store.dispatch('FETCH_USER', userName); },
created() { console.log(this.$route.params.id); const userName = this.$route.params.id; this.FETCH_USER(userName); }, methods: { ...mapActions({ FETCH_USER: 'FETCH_USER', }), }
[แแ ตแฏแแ ณแธ] แแ ตแฏแแ ฎแซ แแ กแผแแ ฆ แแ ฆแแ ตแแ ต แแ ฎแแ งแซ แแ ตแฏแแ ณแธ แแ กแซแแ ข
16_[แแ ตแฏแแ ณแธ] แแ ตแฏแแ ฎแซ แแ กแผแแ ฆ แแ ฆแแ ตแแ ต แแ ตแฏแแ ณแธ แแ ฎแฏแแ ต แแ ตแพ แแ ฉแ แ ฒ แแ ตแแ ฅแแ ตแผ
17_แแ ตแฏแแ ฎแซ แแ กแผแแ ฆ แแ ฆแแ ตแแ ต แแ ณแแ กแแ ตแฏแ แ ตแผ แแ ตแพ v-html แแ ตแ แ ฆแจแแ ตแแ ณ แแ กแแ ญแผแแ ฅแธ แแ ฉแแ ข
- ์๋ต
- ๋ผ์ฐํฐ ํธ๋์ง์ : vue ๋ด๋ถ์์ ํ๋ฉด์ด ๋ณด๋ค ๋ ๋ถ๋๋ฝ๊ฒ ์ ํ๋๋๋ก ํด ์ฃผ๋ ๊ธฐ๋ฅ
- ์ฌ๋ฌ๊ฐ์ง ํธ๋์ง์ ์ดํํธ
- prefix๊ฐ fade์ด๋ฏ๋ก, ๋ค๋ฅธ ์ด๋ฆ(page)๋ก ๋ฐ๊ฟ๋ ๋จ
<transition name="fade">
<router-view></router-view>
</transition>
/* router transition */
.fade - enter - active,
.
fade - leave - active
{
transition: opacity
.5
s;
}
.
fade - enter,
.
fade - leave - to /* .fade-leave-active below version 2.1.8 */
{
opacity: 0;
}
<transition name="page">
<router-view></router-view>
</transition>
/* router transition */
.page - enter - active,
.
page - leave - active
{
transition: opacity
.5
s;
}
.
page - enter,
.
page - leave - to /* .fade-leave-active below version 2.1.8 */
{
opacity: 0;
}
- ์ด๋ ๊ฒ ์ ์ฉํ๋ฉด ๋ผ์ฐํฐ ์ด๋ํ ๋ ํ๋ฉด์ด ๋ถ๋๋ฝ๊ฒ ๋์ด๊ฐ.
- enter, leave๋ ๋ณดํต ์์ผ๋ก ์ง์ ์ง์ด css๋ฅผ ์ ์ฉํจ.
- view์์ ๋ฐ๋ก ๊ฐ๋ฐํ๋ ๊ฒ ์๋, component ๊ธฐ๋ฐ์ผ๋ก ๋ฆฌํฉํ ๋ง
- ์๋ต
- NewsView ์๋ list-item ์ด๋ผ๋ ์ปดํฌ๋ํธ๊ฐ ์๊น
- AskView ์๋ ์์
21_แแ ฉแผแแ ฉแผ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ(1) - แแ ฆแแ ตแแ ตแแ งแฏ แแ ฆแแ ตแแ ฅ แแ ฎแซแแ ต
- ์์ ์ ๋ณด๊ณ ๋ด ๋ง๋๋ก ํจ
22_แแ ฉแผแแ ฉแผ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ(2) - computed แแ ฉแจแแ ฅแผ
- ListItem
computed: {
listItems()
{
if (this.router === 'news') {
return 'news';
} else if (this.router === 'jobs') {
return 'jobs';
} else if (this.router === 'asks') {
return 'asks';
}
}
}
,
23_แแ ฉแผแแ ฉแผ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ(3) - template แแ ฉแจแแ ฅแผแแ ช v-if แแ ตแ แ ฆแจแแ ตแแ ณ แแ ชแฏแแ ญแผ 1, 2
- ListItem.vue
<p>
<template v-if="item.domain">
<a :href="item.url">
{{item.title}}
</a>
</template>
<template v-else>
<router-link
:to="`/item/${item.id}`">
{{item.title}}
</router-link>
</template>
</p>
24_แแ กแแ ญแผแแ ก แแ ณแ แ ฉแแ ตแฏ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฉแแ ข แแ ตแพ แแ ณแผแ แ ฉแจ
- UserProfile
๐ก Router path์ router-link ํ์์ด ๋ง์ง ์์ผ๋ฉด ์ปดํฌ๋ํธ๋ ๋ทฐ๊ฐ ๋จ์ง ์์.
<template>
<router-link to="/user">User</router-link>
</template>
{
path: '/user/:id',
component
:
UserView,
}
,
<template>
<router-link to="/user/:id">User</router-link>
</div>
</template>
{
path: '/user/:id',
component
:
ItemView,
}
- ์๋ต
- ์๋ต
27_slotแแ ณแฏ แแ ตแแ ญแผแแ กแซ แแ กแแ ญแผแแ ก แแ ณแ แ ฉแแ ตแฏ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ
-
user, item ํ์์ []์์ {}๋ก ๋ฐ๊ฟ์ค.
state: { news: [], jobs: [], asks: [], user: {}, item: {}, },
28_แแ กแแ ญแผแแ ก แแ ณแ แ ฉแแ ตแฏ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ณแแ กแแ ตแฏแ แ ตแผ แแ ตแพ แแ ฉแแ ณ แแ ฅแผแ แ ต
- ์๋ต
29_แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ขแแ ชแฏแแ ญแผ แแ กแผแแ ฅแธ แแ ตแพ แแ ขแแ ชแฏแแ ญแผแแ กแฏ แแ ฉแแ ตแซแแ ณ แแ ฉแแ ข
- ํ์ด์ง ์ปดํฌ๋ํธ ์ฌํ์ฉ
30_แแ ตแแ ฆแซแแ ณ แแ ฅแแ ณแ แ ณแฏ แแ ตแแ ญแผแแ กแซ แแ ณแแ ตแแ ฅ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ
- ํ์ด์ง ์ด๋ํ ๋ ๋ฐ์ดํฐ ๋ถ๋ฌ์ค๋ ๋์ spinner๋ฅผ ๋์ ๋ค๊ฐ, ๊บผ์ง๋ ์๊ฐ spinner ๋ฅผ ๋๋ฉด ๋จ.
-
spinner๋ NewsView์์ props๋ก ๋ด๋ ค์ฃผ๋ ๊ฒ ๋ณด๋ค๋, app์์ emit์ผ๋ก ๊ด๋ฆฌํ๋ ๊ฒ ๋ ๋์. (์ด๋ฒคํธ ๋ฒ์ค)
-
/src/utils/bus.js : ๋น ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ์ปดํฌ๋ํธ ๊ฐ ์ด๋ฒคํธ ์ ๋ฌ
-
default์ ๊ทธ์ธ์ ์ฐจ์ด์
// bus.js export const bus = new Vue(); // App.vue import { bus } from './bus.js' // default // bus.js export default new Vue(); // App.vue import Bus from './bus.js' // ๋ญ ์ ์ธํ๋ ๋ฐ์ ์ ์์(Bus๊ฐ ๋๋ , bbbb๋ ๋ค ๋จ)
-
start:spinner๊ฐ ๋๊ณ ์๋ ๋ชจ์ต
-
start๋ก spinner๊ฐ ์๊ธฐ๊ณ , end๋ก ์ฌ๋ผ์ง โ ์ธ์ ์๊ธฐ๊ฒ ํ๊ณ ์ฌ๋ผ์ง๊ฒ ๋ง๋ค๊ฑด์ง๋ง ๊ณ ๋ฏผํ๋ฉด ๋จ
-
๋ง์ง๋ง์ off ํ์
- ์ด๋ฒคํธ๋ฅผ ๋ฑ๋กํ๋ฉด ์ด๋ฒคํธ ๋ฒ์ค์ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ๊ณ์ ์์ด๊ธฐ ๋๋ฌธ์.
- ํญ์ ํ์ด์ง์์ ์ฑ์ ์ข ๋ฃํ๊ธฐ ์ ์ ๋๋ ์ปดํฌ๋ํธ์ ์ญํ (์ด๋ฒคํธ๋ฅผ ๋ฐ๋)์ด ๋๋๊ณ ๋์ off๋ฅผ ํด ์ค์ผ ์ด๋ฒคํธ ๊ฐ์ฒด๊ฐ ํด์ง๋จ.
created()
{
// bus.$on('start:spinner', () => this.spinner = true);
bus.$on('start:spinner', this.startSpinner); // recieved
bus.$on('end:spinner', this.endSpinner); // recieved
}
,
beforeDestroy()
{
bus.$off('start:startSpinner')
bus.$off('start:endSpinner')
}
31_แแ ณแแ ตแแ ฅ แแ ตแฏแแ ขแผ แแ ตแพ แแ ฉแผแ แ ญ แแ ตแแ ฅแท แแ กแฏแแ กแแ ฉแแ ต
FETCH_NEWS(context)
{
fetchNewsList()
.then(res => { // ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์์
context.commit('SET_NEWS', res.data); // mutation์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ฃ๊ณ
return res; // ํ๋ก๋ฏธ์ค ๊ฐ์ฒด๋ฅผ ๋ฆฌํด
})
.catch(err => console.log(err));
}
,
32_แแ กแแ ต แแ ฉแแ ฅ แแ ฅแทแแ ฉแแ ฅแซแแ ณ(HOC) แแ ฉแแ ข แแ ตแพ แแ ฎแแ งแซ
-
createListView ์์ฑ โ router์์ ์ฌ์ฉ
-
NewsView ์ปดํฌ๋ํธ๋ก ๋ฐ๋ก ์ฐ๊ฒฐํ์ง ์์
โ ๊ธฐ์กด ์ปดํฌ๋ํธ ์์ ์ปดํฌ๋ํธ(ํ์ด์ค๋)๊ฐ ํ๋ ๋ ์๊น
{ path: '/news', // url address name: 'news', // component: NewsView, component: createListView('NewsView'), }, { path: '/ask', // If you go to '/ask', name: 'asks', // component: AskView, component: createListView('NewsView'), }, { path: '/jobs', name: 'jobs', // component: JobsView, component: createListView('NewsView'), },
-
-
๋น๊ต
- NewView ๋ก ๋ฐ๋ก ๊ฐ
- createListView๋ฅผ ํตํด ๊ฐ๋ ๊ฑด App๋ฐ์ ์ปดํฌ๋ํธ ํ๋ ๋ ์๊น
-
ListView.vue๋ฅผ ๋ง๋ค์ด createListView์ ๋๋๋ง
import ListView from './ListView' export default function createListView (name) { return { name: name, render(createElement) { return createElement(ListView); } } }
33_ํ์ด ์ค๋ ์ปดํฌ๋ํธแแ ฆแแ ฅ แแ กแแ ญแผแแ กแฏ ListView แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ฎแแ งแซ
-
ListView.vue : ๋ฐ์ดํฐ๋ฅผ ๋ฟ๋ ค์ฃผ๋ ์ญํ
-
createListView : ๋ฐ์ดํฐ๋ฅผ ์์ฒญํ๋ ์ญํ
-
router/index.js : createListView๋ฅผ ๊ฑฐ์ณ ํ์ด์ง ์ด๋์ ํ๋๋ก ํจ
{ path: '/news', // url address name: 'news', // component: NewsView, component: createListView('NewsView'), // high order component }, { path: '/ask', // If you go to '/ask', name: 'asks', // component: AskView, component: createListView('AskView'), }, { path: '/jobs', name: 'jobs', // component: JobsView, component: createListView('JobsView'), },
-
CreateListView์์ ๋ฐ์ดํฐ ๋ฐ์
created() { console.log(11111); bus.$emit('start:spinner'); setTimeout(() => { this.$store.dispatch('FETCH_LIST', this.$route.name) .then(() => { bus.$emit('end:spinner'); }) .catch(err => console.log(err)); }, 1500); },
-
๊ทธ๊ฑธ ListView๋ก ๋๋๋ง
// (2) rendering render(createElement) { console.log(22222); return createElement(ListView); }
-
NewsView์ ListView ๋ด์ฉ ๋ฟ๋ ค์ค> NewsView, JobsView, AskView.vue ํ์ ์์ผ๋ฏ๋ก ์ญ์ createListView('NewsView') ๊ฐ ์๋๋๋ฉฐ, ListView๊ฐ ํ์ด์ง ์ญํ ์ ํจ.
-
ListView.vue๋ ListItem ๋ด์ฉ์ ๋ฟ๋ ค์ค
-
ListItem์ ํ๋ฉด ๊ตฌ์ฑ : ๋ฐ์ดํฐ๊ฐ ์ ๋จ๊ณ์์ ์๋ฃ๋์ผ๋ฏ๋ก ๊ฐ์ ธ์ค๊ธฐ๋ง ํ๋ฉด ๋จ
<li v-for="item in listItems" :key="item.id"> computed: { listItems() { return this.$store.state.list; } },
-
์ปดํฌ๋ํธ ๊ตฌ์กฐ(์ด์ ์๋ NewsView ์๋ ๋ฐ๋ก ListItem์ด ์์์) : ์ค์ง์ hoc๋ NewsView
34_แแ กแแ ต แแ ฉแแ ฅ แแ ฅแทแแ ฉแแ ฅแซแแ ณแแ ก แแ ฅแจแแ ญแผแแ ฌแซ แแ ขแธ แแ ฎแแ ฉ แแ ฅแฏแแ งแผ แแ ตแพ แแ ณแ แ ณแท แแ ฅแผแ แ ต
- createListView
name: 'HOC component',
// ๊ทธ๋ฅ name์ ๋ฐ์ธ๋ฉํ๋ฉด
// component: createListView('AskView'), component: createListView('JobsView'),
// ์ฒ๋ผ ์ธ์๊ฐ ์ปดํฌ๋ํธ ์ด๋ฆ์ด ๋จ
- ์ฆ, NewsView, AskView, JobsView๊ฐ ํ์ด์ค๋์ปดํฌ๋ํธ(hoc)
- ์ด์ NewsView, JobsView, AskView.vue ํ์ ์์ผ๋ฏ๋ก ์ญ์
๐ก ๋จ๊ณ router change โ createListView(get data) โ ListView(page view) โ ListItem(component)
Mixinแแ ด แแ ขแแ ญแแ ช แแ ชแฏแแ ญแผแแ ฅ แแ ณแ แ ตแแ ฉ HOCแแ ชแแ ด แแ กแแ ตแแ ฅแท
- hoc์ ๋จ์ : hoc๋ฅผ ๋ง์ด ์ธ ์๋ก ์ปดํฌ๋ํธ๊ฐ ๊น์ด์ง๋ฏ๋ก, ์ปดํฌ๋ํธ ๊ฐ ํต์ ์ด ์ด๋ ค์
- Mixin : ์ฌํ์ฉ ๋ก์ง
- ์ฅ์
- mixin์ ์ ์ธ๋ ์ฝ๋๋ฅผ ๋ถ๋ฌ์ค๊ธฐ๋ง ํ๋ฉด ๋๋ฏ๋ก ์ฝ๋๊ฐ ๊น๋ํ๊ฒ ์ ๋ฆฌ๋จ
- spinner, modal๋ฑ์ Mixin์ผ๋ก ๋นผ๋ฉด ํจ์จ์ด ์ข์
- crud๋ฅผ ์ ์ธํ ๋ถ์ฐจ์ ๋ก์ง์ ์ ๋ถ Mixin์ผ๋ก ๋นผ๋ฉด ๋จ
- ์ฅ์
35_**[แแ ตแฏแแ ณแธ แแ กแซแแ ข] Mixin แแ ฅแจแแ ญแผ แแ ฎ HOC แแ ฎแแ ฉแแ ช แแ ตแแ ญ, [แแ ตแฏแแ ณแธ] Mixin แแ ตแฏแแ ณแธ แแ ตแพ แแ ฅแทแแ ฉแแ ฅแซแแ ณ แแ ขแแ ชแฏแแ ญแผ แแ กแผแแ ฅแธแแ ฆ แแ ขแแ กแซ
แ แ ตแแ ฒ**
- NewsView : mixins๋ฅผ ์ ์ธํ๋ฉด, ์ปดํฌ๋ํธ๊ฐ ์คํ๋๋ฉด ๋ก์ง์ ๋ถ๋ฌ์ด
export default {
components: {
ListItem,
},
mixins: [ListMixin]
}
- hoc ์ mixin ๋น๊ต
- ๋ฐ์ดํฐ ํธ์ถ ์์
-
์ปดํฌ๋ํธ ๋ผ์ดํ ์ฌ์ดํด ํ : create
- ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋์๋ง์ ์์ฑ๋๋ ๋ก์ง
- ๊ธฐ๋ณธ์ vue์ ๋์ ์๋ฆฌ(๋ฐ์ดํฐ ๊ด์ฐฐ, computed, watch ์ฝ๋ฐฑ ๋ฑ)์ ์ ๊ทผํ ์ ์๋ ๋ผ์ดํ ์ฌ์ดํด ํ
- ํ๋ฉด์ ์ธ์คํด์ค ๋ด์ฉ๋ค์ด ๋ถ์ด์์ง ์๋ ์ํ
- ์ฆ, ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋์๋ง์ ํธ์ถ๋๋ ๋ก์ง
-
๋ผ์ฐํฐ ๋ค๋น๊ฒ์ด์ ๊ฐ๋ : ์ปดํฌ๋ํธ์ ์ง์ ํ๊ธฐ ์ ์ ๋ผ์ฐํฐ ์์ฑ์ ์ด์ฉ(๊ณต์๋ฌธ์)
-
๋ผ์ฐํฐ๋ก ํน์ url์ ์ ๊ทผํ๊ธฐ ์ ์ ๋์๋ค์ ์ ์
-
ํน์ url์ ์ ๊ทผํ์ง ๋ชปํ๊ฒ ํ๋ค๋์ง, ์ธ์ฆ๊ฐ์ ํ์ธํ๋ค๋์ง
-
์ฆ, ํน์ url๋ก ์ ๊ทผํ๊ธฐ ์ ์ ๋์์ ์ ์ํ๋ ์์ฑ(ํจ์)
router.beforeEach(function (to, from, next) { // ๋ผ์ฐํฐ ์ฃผ์์ ์ง์ ํ๊ธฐ ์ ์ ์ด๋ค ๋ก์ง์ ์ฌ๊ธฐ ์ฝ๋ฐฑ ์์ ์ ์ // ์ด ๋ก์ง์ด ๋๋๊ณ next๋ฅผ ํธ์ถํ์ ๋๋ง ์๋ํ ์์น๋ก ๊ฐ๋ฅ });
-
-
์์๋ ๋ผ์ฐํฐ ๋ค๋น๊ฒ์ด์ ๊ฐ๋๊ฐ ๋จผ์ ์
- ๋ผ์ดํ ์ฌ์ดํด ํ : ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋๊ณ ๋์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ ๊ฑด์ง
- ๋ผ์ฐํฐ ๋ค๋น๊ฒ์ด์ ๊ฐ๋ : ์ปดํฌ๋ํธ๊ฐ ์์ฑ๋๊ธฐ ์ ์ ๋ผ์ฐํ ์ํ์์ ๋ฐ์ดํฐ๋ฅผ ํธ์ถํ ๊ฑด์ง
-
36_แ แ กแแ ตแแ ณ แแ กแแ ตแแ ณแฏ แแ ฎแจแแ ณแฏ แแ ตแแ ญแผแแ กแซ แแ ฆแแ ตแแ ฅ แแ ฉแแ ฎแฏ แแ กแผแแ ฅแธ์ ๋ฌธ์ ์ แแ ตแแ ฉแผแแ ต แแ ฅแ แ ต แแ ฉแแ ณ แแ ฎแแ ฅแผ
- News ๋ฉ๋ด์์ Ask ๋ฉ๋ด๋ก ์ด๋ํ๋๋ฐ, NewsView ๋ชฉ๋ก์ด ์ ๊น ๋ณด์ด๊ณ AskView ๋ชฉ๋ก์ด ์ถ๋ ฅ๋๋ ํ์์ ๋ํ์ฌ
state: {
news: [],
jobs
:
[],
// ์ด๋ ๊ฒ ๊ฐ๊ฐ ๋๋์ด์ ธ ์์ ๋๋ ์ค๋์์ด ๋์ง ์์์
list
:
[],
// list๋ผ๋ ๋ฐ์ดํฐ๋ฅผ news, jobs, askview๊ฐ ๊ณต์ ํ๊ธฐ ๋๋ฌธ์ ์ค๋์ ๋ฐ์
}
,
-
spinner๊ฐ ์ ๋๋ ์ค๋ฅ : return ๋นผ๋จน์
- return fetchList์ ํ๋ ์ด์ : ํ๋ฉด์์ dispatch๋ฅผ ํธ์ถํ๊ณ ๋์, then์ผ๋ก ์ฒด์ด๋์ ํด์ผ ํ๋๋ฐ return์ด ์ ๋์ด์ค๋ฉด ์๋๋๋ก ๋น๋๊ธฐ ์ฒ๋ฆฌ๊ฐ ๋์ง ์์
FETCH_LIST({ commit }, name) { return fetchList(name) .then(res => { // get data commit('SET_LIST', res.data); // send mutation return res; // return response(send Promise object to View Page - in this case, NewsView.vue) }) .catch(err => console.log(err)); }, FETCH_USER(context) { return fetchUserInfo() .then(res => { context.commit('SET_USER', res.data); }) .catch(err => console.log(err)); }, FETCH_ITEM({ commit }, id) { return fetchCommentItem(id) .then(({ data }) => { commit('SET_ITEM', data); }) .catch(err => console.log(err)); },
- mixin.js
created() { bus.$emit('start:spinner'); // #1 console.log(1); this.$store.dispatch('FETCH_LIST', this.$route.name) // #5 .then(() => { console.log(5); bus.$emit('end:spinner'); }) .catch(err => console.log(err)); },
- actions.js
- fetchList์ ๋ํ ๊ฒฐ๊ณผ๊ฐ Promise๋ก ์ฒด์ด๋์ด ๋์ด, #5์ .then()์ด ๋จ
- fetchList ์์ return์ด ์์ ์ #5๊ฐ ์ ๋๋ก ๋์ํ์ง ์์
// #2 FETCH_LIST({ commit }, name) { // #3 console.log(3); return fetchList(name) // #4 .then(res => { console.log(4); commit('SET_LIST', res.data); return res; }) .catch(err => console.log(err)); },
37_แ แ กแแ ฎแแ ฅ แแ ฆแแ ตแแ ฆแแ ตแแ งแซแแ ณแฏ แแ ตแแ ญแผแแ กแซ แแ ฆแแ ตแแ ฅ แแ ฉแแ ฎแฏ แแ กแผแแ ฅแธ
-
router/index
{ path: '/news', // url address name: 'news', component: NewsView, // high order component beforeEnter: (to, from, next) => { console.log(to) console.log(from) console.log(next) } },
beforeEnter: (to, from, next) => { next(); } // next๋ฅผ ํธ์ถํด ์ค์ผ url๋์ด๊ฐ
[แแ ตแฏแแ ณแธ] แ แ กแแ ฎแแ ฅ แแ ฆแแ ตแแ ฆแแ ตแแ งแซ แแ กแแ ณ แแ ตแฏแแ ณแธ แแ กแซแแ ข
- ๋ด์ฉ์์
38_[แแ ตแฏแแ ณแธ] แ แ กแแ ฎแแ ฅ แแ ฆแแ ตแแ ฆแแ ตแแ งแซ แแ กแแ ณ ์ค์ต ๋ฐ ์คํผ๋ ์ข ๋ฃ ์์ ๋ณ๊ฒฝ
- spinner ์์ ์ด ์ฝ๊ฐ ์ ๋ง์ โ mounted(์ธ์คํด์ค๊ฐ ํ๋ฉด์ ๋ถ๋ฌ์ค๋ ๊ฒ์ด ์๋ฃ๋์์ ๋)์ spinner ์ข ๋ฃ์ํค๊ธฐ
แแ กแแ กแแ ณแแ ณแ แ ตแธแแ ณ แแ ตแแ ฉแผแแ ต แแ ฅแ แ ต แแ ขแแ ฅแซแแ ด แแ กแฏแแ ฅแซ แแ ชแแ ฅแผ
-
์ผ๋ฐ ์๋ฐ์คํฌ๋ฆฝํธ์ ๋น๋๊ธฐ ์ฝ๋
john์ด๋ผ๋ id๊ฐ ์์ ์ products ํจ์ ์คํ
๋ฐ์ ์จ ๊ฒฐ๊ณผ ๊ฐ products๋ ์ฝ๋ฐฑ ํจ์ ์์์ ์ฒ๋ฆฌํด์ผ ๋น๋๊ธฐ ์ฒ๋ฆฌ ๊ฐ๋ฅ
-
promise๋ก ์ฐ๋ ๋น๋๊ธฐ ์ฝ๋
-
2์์ ํจ์ ์ด๋ฆ์ ์ข ๋ ๋ช ์์ ์ผ๋ก
-
๊ฒฐ๊ตญ, john ์ด๋ผ๋ id๊ฐ ์์ ์ ๋ถ๋ฌ์จ products๊ฐ์ products ๋ณ์์ ๋ด๊ณ , ์ด ๊ฐ์ ๋ถ๋ฌ์ฌ ์ ์๋์ง์ ๋ํ ๊ณผ์ ์ด ํต์ฌ.
๋ ผ๋ฆฌ๊ณผ์ ์์(์ค์ ๋ก์ง ์๋)
- ์๋ฐ์คํฌ๋ฆฝํธ async์ await, [2]
- ํจ์ ์ ์ธ๋ฌธ ์์
async
๋ฅผ ๋ถ์ด๊ณ , ๊ทธ async function ์์ ๋น๋๊ธฐ ์ฒ๋ฆฌ๋ฅผ ๋ด๋นํ๊ณ promise๋ฅผ ๋ฐํํ๋ ๋ก์ง ์์await
๋ฅผ ๋ถ์ฌ์ค.
async function ํจ์๋ช
() {
await ๋น๋๊ธฐ_์ฒ๋ฆฌ_๋ฉ์๋_๋ช
();
}
- ์๋ต
- ์๋ต
41_async await แแ ฆแ แ ฅ แแ ฅแ แ ต แแ กแผแแ ฅแธแแ ช แแ ฉแผแแ ฉแผแแ ช แแ กแทแแ ฎ แแ กแจแแ ฅแผ แแ กแผแแ ฅแธ
- promise์ then, catch : ๋คํธ์ํฌ ์์ฒญ, ๋น๋๊ธฐ ์์ฒญ์ ๋ํด์๋ง ์์ธ์ฒ๋ฆฌ
loginUser()
{
axios.get('https://jsonplaceholder.typicode.com/users/1')
.then(response => {
if (response.data.id === 1) {
axios.get('https://jsonplaceholder.typicode.com/todos')
.then(response2 => console.log(response2))
.catch(error => console.log(error));
}
})
.catch(error => console.log(error));
}
- async, await์ try-catch : ๋น๋๊ธฐ ์ฒ๋ฆฌ ์์ฒญ๋ฟ ์๋๋ผ, ์ผ๋ฐ์ ์๋ฐ์คํฌ๋ฆฝํธ ์ฝ๋ ์๋ฌ๊น์ง ํฌ๊ด์ ์ผ๋ก ์์ธ์ฒ๋ฆฌ
async
loginUser2()
{
try {
var response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
if (response.data.id === 1) {
var response2 = await axios.get('https://jsonplaceholder.typicode.com/todos');
console.log(response2);
}
} catch (error) {
handleException(error);
console.log(error);
}
}
- ๊ณตํต ์๋ฌ์ฒ๋ฆฌ : utils/handelException.js
function handleException(status) {
// handle error logic
}
- api ๊ฒฐ๊ณผ๊ฐ์ new Promise(); ํํ
function fetchList(name) {
return axios.get(`${config.baseUrl}/${name}/1.json`);
// = return new Promise();
}
-
return response๋ฅผ ํ์ง ์์ผ๋ฉด ํ๋ฉด์์ ๋น๋๊ธฐ ์์๋ฅผ ๋ณด์ฅํ ์ ์์ผ๋ฏ๋ก, ํ๋ก๋ฏธ์ค ์ฒด์ด๋
-
๊ฒฐ๊ณผ๊ฐ์ ๋ฐํํด์ค์ผ FETCH_LIST2(); ๋ฅผ ์คํํ๊ณ ๋์ ๋ค์ ๋จ๊ณ๋ฅผ ์ด์ด ์คํํ ์ ์๊ฒ ๋จ.
โ FETCH_LIST2().then().catch();
-
async ํจ์์์ ์ด๋ค ๊ฒ์ ๋ฆฌํดํ๋ promise๊ฐ ๋ฆฌํด๋จ.
async
FETCH_LIST({commit}, name)
{
const response = await fetchList(name);
commit('SET_LIST', response.data);
return response; // promise
}
,
- ๋ด์ฉ ์์
- ์๋ต
- ์ธ๋ถ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋ชจ๋ํ
- ์ด์ : vue.js ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ์์ ๋ ์ผ๋ฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฒฐํฉํ ์ ์์ด์ผ ํจ.
- ์ข ๋ฅ : ์ฐจํธ, ๋ฐ์ดํธ ํผ์ปค, ํ ์ด๋ธ, ์คํผ๋
- ์ค์น
npm
install
chart.js
- https://www.inflearn.com/course/vue-js/lecture/16981?volume=1.00&quality=1080
- router, routes ์ฐจ์ด : https://im-nc2u.tistory.com/entry/Vue-Router-Router-์ธ์คํด์ค์-Route-๊ฐ์ฒด-๋น๊ต
- https://www.notion.so/vue-lesson-bb01133a21e94a969b42f1a82f8c24c7
- https://velog.io/@ywoosang/Node.js-%EC%84%A4%EC%B9%98
- vscode git ๊ถํ์ค์ :https://hyeo-noo.tistory.com/184