Reactivity
- ๊ฐ์ฒด์ ๋์์ ์ฌ์ ์ํจ
- ๋ฐ์ดํฐ์ ๋ณ๊ฒฝ์ด ํ๋ฉด์ ๋ฐ๋ก ๋ฐ์๋จ
<div id="app"></div>
<script>
var div = document.querySelector("#app");
var viewModel = {};
// Object.defineProperty(๋์ ๊ฐ์ฒด, ๊ฐ์ฒด์ ์์ฑ, {
// ์ ์ํ ๋ด์ฉ
// });
// ์ฆ์ ์คํ ํจ์
(function () {
function init() {
Object.defineProperty(viewModel, "str", {
get: function () {
console.log("์ ๊ทผ");
},
set: function (newValue) {
console.log("ํ ๋น", newValue);
render(newValue);
},
});
}
function render(value) {
div.innerHTML = value;
}
init();
})();
</script>
์ธ์คํด์ค
์์ฑ
new Vue({
el: ,
template: ,
data: ,
methods: ,
created: ,
watch: ,
});
์ปดํฌ๋ํธ
- ํ๋ฉด์ ์์ญ์ ๊ตฌ๋ถํ์ฌ ๊ฐ๋ฐํ ์ ์๋ ๋ทฐ์ ๊ธฐ๋ฅ
- ์ฌ์ฌ์ฉ์ฑ์ด ํฅ์๋์ด ํ๋ฉด์ ๋น ๋ฅด๊ฒ ์ ์ ๊ฐ๋ฅ
์ ์ญ ์ปดํฌ๋ํธ
// Vue.component('์ปดํฌ๋ํธ ์ด๋ฆ', ์ปดํฌ๋ํธ ๋ด์ฉ);
// ์ ์ญ ์ปดํฌ๋ํธ - ๊ฑฐ์ ์์
Vue.component("app-header", {
template: "<h1>Header</h1>",
});
Vue.component("app-content", {
template: "<div>content</div>",
});
์ง์ญ ์ปดํฌ๋ํธ
new Vue({
el: "#app",
// ์ง์ญ ์ปดํฌ๋ํธ ๋ฑ๋ก ๋ฐฉ์
components: {
// '์ปดํฌ๋ํธ ์ด๋ฆ': ์ปดํฌ๋ํธ ๋ด์ฉ
"app-footer": {
template: "<footer>footer</footer>",
},
},
});
์ปดํฌ๋ํธ์ ์ธ์คํด์ค์ ๊ด๊ณ
- ์ ์ญ ์ปดํฌ๋ํธ๋ ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ๊ณ components์ ๋ฃ์ด์ฃผ์ง ์๋๋ผ๋ ๋ฐ์์ด ๋์ง๋ง (์ด๋ฏธ ๋ฑ๋ก์ด ๋์ด ์์)
- ์ง์ญ ์ปดํฌ๋ํธ๋ ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ๊ณ components์ ๋ฃ์ด์ฃผ์ด์ผ ๋ฐ์์ด ๋จ
์ปดํฌ๋ํธ ํต์ ๋ฐฉ์
๋ทฐ ๋ผ์ฐํฐ
- SPA๋ฅผ ๊ตฌํํ ๋ ์ฌ์ฉํ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
์ฌ์ฉ ๋ฐฉ๋ฒ
- CDN ์์ ์ฃผ์! (vue -> vue router ์)
- npm์ผ๋ก ์ค์นํ ์๋ ์์
<script src="[https://cdn.jsdelivr.net/npm/vue/dist/vue.js](https://cdn.jsdelivr.net/npm/vue/dist/vue.js)"></script>
<script src="[https://unpkg.com/vue-router@3/dist/vue-router.js](https://unpkg.com/vue-router@3/dist/vue-router.js)"></script>
์ต์
- routes : ๋ผ์ฐํ
ํ URL์ ์ปดํฌ๋ํธ ๊ฐ ์ง์
- mode : URL์ ํด์ฌ ๊ฐ ์ ๊ฑฐ ์์ฑ (mode: history)
router-view
- Vue์ ์ฑ๊ธ ํ์ด์ง
- URL์ด ๋ณ๊ฒฝ๋๋ฉด ํด๋น ์ปดํฌ๋ํธ๊ฐ ํ๋ฉด์ ๋ฟ๋ ค์ง๋ ์ง์ ์ ์ ํจ
router-link
- html์ a href ๊ฐ์ ๊ธฐ๋ฅ
- ํ์ด์ง ์ด๋
axios
- Vue์์ ๊ถ๊ณ ํ๋ Promise ๊ธฐ๋ฐ์ HTTP ํต์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ
- ๋ฌธ์ํ ์ ๋์ด ์๊ณ , API๊ฐ ๋ค์ํจ
์ค์น
<script src="[https://unpkg.com/axios/dist/axios.min.js](https://unpkg.com/axios/dist/axios.min.js)"></script>
npm install axios
์ฌ์ฉ๋ฐฉ๋ฒ
<div id="app">
<button v-on:click="fetchData">get data</button>
</div>
new Vue({
el: '#app',
methods: {
fetchData: function() {
axios.get('https://jsonplaceholder.typicode.com/users/')
.then(function(response) {
console.log(response);
})
.catch(function(error) {
console.log(error);
});
}
}
})
get data ๋ฒํผ์ ํด๋ฆญํ์ ๋ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ๋ฐ์์ค๋ ์ฝ๋
์คํํ๋ฉด ์ฌ์ฉ์ ์ ๋ณด๊ฐ ์ฝ์์ ์ถ๋ ฅ๋จ
ํ
ํ๋ฆฟ
๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ
๋ทฐ ์ธ์คํด์ค์์ ์ ์ํ ์์ฑ๋ค์ ํ๋ฉด์ ํ์ํ๋ ๋ฐฉ๋ฒ
<div>{{ message }}</div>
new Vue({
data: {
message: 'Hello Vue.js'
}
})
๋๋ ํฐ๋ธ (v-)
๋ทฐ๋ก ํ๋ฉด์ ์์๋ฅผ ๋ ์ฝ๊ฒ ์กฐ์ํ๊ธฐ ์ํ ๋ฌธ๋ฒ
- ์์ฃผ ์ฌ์ฉ๋๋ ๋๋ ํฐ๋ธ
- v-if
- v-for
- v-bind
- v-on
- v-model (2-way ๋ฐ์ดํฐ ๋ฐ์ธ๋ฉ)
watch
ํน์ ๋ฐ์ดํฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ์ฌ ์๋์ผ๋ก ํน์ ๋ก์ง์ ์ํํ๋ ์์ฑ
๊ฐ์ ๊ณ์ ์ถ์ , ์ด์ ๊ฐ๊ณผ ๋ฐ๋ ๊ฐ์ ๋ฐ์ ์ ์์, ๋ฐ์ดํฐ ์์ฒญ
new Vue({
data() {
return {
message: 'Hello'
}
},
watch: {
message: function(value, oldValue) {
console.log(value);
}
}
})
message์ ๋ฐ์ดํฐ๊ฐ ๋ณํ ๋๋ง๋ค watch ์์ฑ์ ์ ์ํ message ํจ์๊ฐ ์คํ๋๋ฉด์ ์ฝ์์ ๋ณํ ๋ฐ์ดํฐ ์ถ๋ ฅ
computed
๋ฐ๋ ๊ฐ์ ๋ํด์ ๋ชจ๋ฆ, ๋น ๋ฆ, ์บ์ ๊ฐ์ ๋๋, validation์ด๋ ๊ฐ๋จํ ์ฐ์ฐ ๊ฐ๋ฅ, ๊ฐ๋
์ฑ ํฅ์
computed: {
reverseMessage() {
return this.message.split('').reverse().join('');
}
}
<div>{{ reverseMessage }}</div>
- watch๋ณด๋ค computed ์ฐ๋ ๊ฒ์ ์ถ์ฒํจ
์ฑ๊ธ ํ์ผ ์ปดํฌ๋ํธ
- vue-cli๋ก ํ๋ก์ ํธ ์์ฑํ App.vue
- .vue ํ์ผ์ ๋ชจ๋ ์ฑ๊ธ ํ์ผ ์ปดํฌ๋ํธ๋ผ๊ณ ํจ
<!-- .vue ํ์ผ ๊ตฌ์กฐ -->
<template>
<!-- html (๋ทฐ ์ปดํฌ๋ํธ์ ํํ๋จ, ํ
ํ๋ฆฟ ๋ฌธ๋ฒ) -->
</template>
<script>
// ์๋ฐ์คํฌ๋ฆฝํธ (๋ทฐ ์ปดํฌ๋ํธ ๋ด์ฉ)
</script>
<style>
/* CSS (๋ทฐ ํ
ํ๋ฆฟ์ ์คํ์ผ๋ง) */
</style>
๋์ ์๋ฆฌ
- ์ฑ๊ธ ํ์ผ ์ปดํฌ๋ํธ๋ ๋ทฐ ๋ก๋์ ์ํด HTML, CSS, JS์ ๊ฐ์ ์น ์์์ผ๋ก ๋ถ๋ฆฌ๋์ด ์คํ๋จ
- ๋ทฐ ๋ก๋๋ ์นํฉ์ ๋ก๋ ์ข
๋ฅ ์ค ํ๋์ด๊ณ ๋ทฐ CLI๋ก ํ๋ก์ ํธ๋ฅผ ์์ฑํ๋ฉด ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ๋์ด ์์