[Vue.js] ๋ทฐ ๊ธฐ์ด
Vue.js ๊ธฐ๋ณธ ๊ตฌ์กฐ
- Vue ์ปดํฌ๋ํธ์ ๊ฒฝ์ฐ ์ธ๊ฐ์ ๊ตฌ์ญ์ผ๋ก ๋๋์ด์ ธ ์๋ค.
- template: html๋ถ๋ถ์ด๋ค. ์ด ์์ styleํ๊ทธ์ scriptํ๊ทธ๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- script: ์ด ํ ํ๋ฆฟ์์ ์ฌ์ฉํ ์คํฌ๋ฆฝํธ ์ฝ๋์ด๋ค. import๋ก ์ธ๋ถ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
- style: ์ด ํ ํ๋ฆฟ์์ ์ฌ์ฉํ css์ด๋ค. scoped์์ฑ์ ๋ถ์ฌํ๋ฉด ๋ฑ ์ด ์คํ์ผ์์๋ง ์ฌ์ฉํ ์ ์๋ค. ์๋ฌด๊ฒ๋ ์์ผ๋ฉด ์์ ์ปดํฌ๋ํธ๋ ์ผ๊ด ์ ์ฉ๋๋ค.
-
Vue.js๋ (Value, Key) ์์์ด๋ค.
-
this.$set(person1, 'name', 'John')
๋ฉ์๋๋ก vue๊ฐ ๊ฐ์ฑ ๋ด ๋ณํ๋ฅผ ์์์ฑ๊ณ ์ฌ๋ ๋๋ง ์ํด -
vue๋ ๊ฐ์ฒด ์์ฒด์ ๋ณํ๋ ๊ฐ์งํ์ง๋ง ๊ฐ์ฒด ๋ด ์์ฑ, ๋ฐฐ์ด ๊ฐ ๋ณํ ๋ฑ ๊ฐ์ฑ ๋ด ๋ณํ๋ ๊ฐ์งํ์ง ๋ชปํ๋ค.
-
๋ฐฐ์ด์ ํฌ๊ธฐ ๋ณ๊ฒฝ์ ์ฌ๋ ๋๋ง ํ ๋, splice ๋ฉ์๋๋ฅผ ์ฌ์ฉ ex)
this.arr.splice(4)
: arr๋ฐฐ์ด์ ํฌ๊ธฐ๋ฅผ 4๋ก ์ฌ๋ ๋๋ง -
mousedown/mousedown ์ด๋ฒคํธ(๋ชจ๋ ์ด๋ฒคํธ๋ '@'๋ก ๋์ฒด ๊ฐ๋ฅํ๋ค)์์
method:function(e){
if(e.button==0 ๋๋ 1 ๋๋ 2) // 0: ์ผ์ชฝ๋ง์ฐ์ค, 2: ์ค๋ฅธ์ชฝ๋ง์ฐ์ค
}
<a>
: anchor ์ต์ปค ํ๊ทธ (๋ฆฌ๋ค์ด๋ ํธ ์ํค๋ ํ๊ทธ)
<a @click.prevent href="http://www.naver.com">naver๋งํฌ</a> // click์ด๋ฒคํธ์ prevent๋ฅผ ์ฐ๋ฉด ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ๋ง๋๋ค.
์ด๋ฒคํธ
- self : ์์ ์ ์ง์ ๋๋ ์๋๋ง ์ด๋ฒคํธ ๋ฐ์
- stop : ์์ ์ด๋ฒคํธ๊น์ง๋ง ์คํ ์ํค๊ณ ํ์ ์ด๋ฒคํธ๋ ์ค์ง
- prevent
- capture : ์ฐ์ ์์์ ๋ฐ๋ผ ์ด๋ฒคํธ ๋ฐ์
- once : ์ด๋ฒคํธ ํ ๋ฒ๋ง ๋ฐ์
- props : ์ปดํฌ๋ํธ์ ์์ฑ, ๋ถ๋ชจ ์ปดํฌ๋ํธ๊ฐ ์์ ์ปดํฌ๋ํธ์๊ฒ ์ ๋ฌํ ์ ์๋ค.
- template : ์ธ๋ถ์์ ์ด ์ปดํฌ๋ํธ๋ฅผ ํธ์ถํ ๋ ๋ ๋๋ง๋ ํ ํ๋ฆฟ์ด๋ค.
- data : ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฐ์ผ ๋ณ์
- methods : ์ปดํฌ๋ํธ ๋ด๋ถ์์ ์ฐ์ผ ๋ฉ์๋
<!DOCTYPE html>
<html lang="kr">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div id="app">
<simple-component v-bind:initial-counter="counter"></simple-component> <!-- HTML ์์ญ -->
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.js"></script>
<script> // Vue.js ์์ญ
// ๊ธ๋ก๋ฒ ์ปดํฌ๋ํธ
Vue.component('simple-component', { // Vue.component([์ปดํฌ๋ํธ๋ช
],[์ปดํฌ๋ํธ์ ๋ณด]) / simple-component๋ ํด๋น Vue ์ปดํฌ๋ํธ์ ์ด๋ฆ
props: ['initialCounter'], // props๋ง ์ปดํฌ๋ํธ๋ผ๋ฆฌ์ ๋ฐ์ดํฐ ์ ๋ฌ์ด ๊ฐ๋ฅ
template: '<button @click="addCounter">{{counter}}</button>',
data: function () {
return {
counter: this.initialCounter
};
},
methods: {
addCounter: function () {
this.counter += 1;
}
}
});
new Vue({
el: '#app',
data: {
counter: 0
},
components: {
'simple-component': simpleComponent, // ๋ก์ปฌ ์ปดํฌ๋ํธ
}
});
</script>
</html>
๋ค์ด๋ฐ ์ผ์ด์ค
-
์ผ๋ฐฅ-์ผ์ด์ค: kebab-case, spinal-case, Train-Case, Lisp-case
-ํ์ดํ์ผ๋ก ๋จ์ด๋ฅผ ์ฐ๊ฒฐํ๋ ํ๊ธฐ๋ฒ
-HTML ํ๊ทธ์ id, class ์์ฑ์ผ๋ก ํํ ์ฌ์ฉ๋จ. -
ํ์ค์นผ ํ๊ธฐ๋ฒ: PascalCase, BackgroundColor, TypeName, PowerPoint
-์ฒซ ๋จ์ด๋ฅผ ๋๋ฌธ์๋ก ์์ํ๋ ํ๊ธฐ๋ฒ -
์ค๋ค์ดํฌ ์ผ์ด์ค(๋ฑ ํ๊ธฐ๋ฒ):
snake_case, background_color, type_name
-๋จ์ด๋ฅผ ๋ฐ์ค ๋ฌธ์๋ก ๊ตฌ๋ถํ๋ ํ๊ธฐ๋ฒ
-perl, php, python, ruby, rust.... -
ํ๊ฐ๋ฆฌ์ธ ํ๊ธฐ๋ฒ:
strName, bBusy, szName
-์ ๋์ด๋ฅผ ์ฌ์ฉํ๋ ํ๊ธฐ๋ฒ
-str -> string, b -> boolean, sz -> null๋ก ๋๋๋ ๋ฌธ์์ด(string+zero) -
์นด๋ฉ์ผ์ด์ค:
ex) userName
-
์๋ฐ์คํฌ๋ฆฝํธ ๋ด์์ ์นด๋ฉ์ผ์ด์ฑ์ผ๋ก ์ ์ธํ ๋ณ์๋ HTML๋ด์์ ์ผ๋ฐฅ์ผ์ด์ฑ์ผ๋ก ์๋๋ณํ๋๋ค.
-
userName(JS) -(์๋๋ณํ)-> user-name(HTML)
-
'{{ }}'
: ๋จธ์คํ์น
๋ผ์ฐํ
-
https://www.naver.com/user/ ์์ ์ปจํ ์คํธ ๋ฃจํธ๋ https://www.naver.com
-
๋ง์ฝ http://www.naver.com/user/#/kim ์ด๋ผ๋ฉด '#' ์ดํ๋ถํฐ๋ ํ๋ก ํธ์๋์์ ๋ผ์ฐํ ๋๊ฑฐ์
-
ํ๋ก ํธ์๋์์ Vue๋ก ๋ผ์ฐํ ํ๊ธฐ ์ํด์๋ ๋จ์ํ Vue ๋ฟ๋ง์๋๋ผ Vue-router๊ฐ ํ์
๋์ ๋ณ๊ฒฝ
- v-model์ ์ด์ฉํ์ฌ ๋์ ๋ณ๊ฒฝ์ ๊ฐ๋จํ๊ฒ ์์ฑํ ์ ์์
<body>
<div id="app">
<input v-model="name">
<br/>
{{name}}
</div>
</body>
<script>
new Vue({
el: '#app',
data: {
name: 'kimdongmin',
}
});
</script>
Vue Import
<template>
<div id="app">
<img alt="Vue logo" src="./assets/logo.png">
<HelloWorld msg="Welcome to Your Vue.js App"/>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'app',
components: {
HelloWorld
},
}
</script>
- Vueํ์ผ์ import์ํจ๋ค.
- import๊ตฌ๋ฌธ์ ๊ฒฐ๊ณผ๋ก vue์ปดํฌ๋ํธ๊ฐ ๋ฐํ๋๋ค.
- ๋จ, ๋ถ๋ฌ ์ค๋ ์์ ์์ js๊ฐ์ฒด๋ก ๋ฐ๋๊ฒ ๋๋ค. (์ปดํ์ผ ๋๋๊ฑฐ์)
- components์ ํฌํจ์์ผ์ค๋ค.
- ๊ทธ๋์ผ template ๊ตฌ๋ฌธ์ ์ฌ์ฉํ ์ ์๋ค.
Vue.js ๋ผ์ดํ์ฌ์ดํด
-
beforeCreate: ๋์ ์ ๊ทผ ๋ถ๊ฐ๋ฅ
-
created: this.data ๋๋ this.fetchData() ๋ฅผ ์ด์ฉํ์ฌ data, methods์ ์ ์๋ ๊ฐ์ ์ ๊ทผ ๊ฐ๋ฅ. ๋จ, template ์์ฑ์ ์ ์๋ ๋ ์์๋ก ์ ๊ทผ ๋ถ๊ฐ
-
beforeMount: render() ํจ์๊ฐ ํธ์ถ๋๊ธฐ ์ง์ ์ ๋ก์ง์ ์ถ๊ฐํ๊ธฐ ์ข์
-
mounted: ํ๋ฉด ์์(๋)์ ์ ๊ทผํ ์ ์์ด ํ๋ฉด ์์๋ฅผ ์ ์ดํ๋ ๋ก์ง์ ์ํํ๊ธฐ ์ข์ ๋จ๊ณ
-
beforeUpdate: ๋ฐ์ดํฐ ๊ฐ์ ๊ฐฑ์ ํ๋ ๋ก์ง์ ๊ฐ๊ธ์ beforeUpdate์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์
-
updated: ๋ณ๊ฒฝ ๋ฐ์ดํฐ์ ํ๋ฉด ์์(๋)์ ๊ด๋ จ๋ ๋ก์ง์ ์ถ๊ฐํ๋ ๊ฒ์ด ์ข์
-
beforeDestroy: ๋ทฐ ์ธ์คํด์ค๊ฐ ํ๊ดด๋๊ธฐ ์ง์ ์ ํธ์ถ. ๋ทฐ ์ธ์คํด์ค์ ๋ฐ์ดํฐ๋ฅผ ์ญ์ ํ๊ธฐ ์ข์ ๋จ๊ณ
-
destroyed
new Vue({ el: '#app', data: { name: 'kimdongmin', }, beforeCreate: function(){ console.log("beforeCreate") }, created: function(){ console.log("created") }, mounted: function(){ console.log("mounted") this.name = 'dongminkim' // beforeUpdate & updated ๋ผ์ดํ์ฌ์ดํด๋ก ๋์ด๊ฐ๊ธฐ ์ํด name์ update ํจ }, beforeUpdate: function(){ console.log("beforeUpdate") }, updated: function(){ console.log("updated") } });
- ์ด๋ฌํ ๋ผ์ดํ์ฌ์ดํด ๋ฉ์๋ ๋ด์ ๊ฐ ๋ผ์ดํ์ฌ์ดํด ์์ ์ ๋ง๋ ๋ก์ง์ ์์ฑํ ์ ์๋ค.
Vue ์ปดํฌ๋ํธ
- ์ ์ญ ์ปดํฌ๋ํธ
Vue.component('์ปดํฌ๋ํธ ์ด๋ฆ', {
// ์ปดํฌ๋ํธ ๋ด์ฉ
});
์์
<body>
<div id="app">
<button>์ปดํฌ๋ํธ ๋ฑ๋ก</button>
<test-component></test-component> <!-- JS์ ์นด๋ฉ์ผ์ด์ค๋ HTML์์ ์ผ๋ฐฅ์ผ์ด์ค๋ก ๋ฐ๋ -->
</div>
</body>
<script>
// ๊ธ๋ก๋ฒ ์ปดํฌ๋ํธ
Vue.component('testComponent', { // JS์ ์นด๋ฉ์ผ์ด์ค๋ HTML์์ ์ผ๋ฐฅ์ผ์ด์ค๋ก ๋ฐ๋ (testComponent -> test-component)
template: '<div>์ ์ญ ์ปดํฌ๋ํธ๊ฐ ๋ฑ๋ก๋์์ต๋๋ค.</div>',
});
new Vue({
el: '#app',
data: {
name: 'kimdongmin',
},
});
</script>
- ์ง์ญ ์ปดํฌ๋ํธ
<script>
var cmp = {
template: '<div>์ง์ญ ์ปดํฌ๋ํธ๊ฐ ๋ฑ๋ก๋์์ต๋๋ค!</div>'
};
new Vue({
el: '#app',
components: {
'my-local-component': cmp
}
});
</script>
- ์ง์ญ ์ปดํฌ๋ํธ & ์ ์ญ ์ปดํฌ๋ํธ
<body>
<div id="app">
<b>์ปดํฌ๋ํธ ๋ฑ๋ก</b>
<test-local-component></test-local-component> <!-- ์ง์ญ ์ปดํฌ๋ํธ ํ์ -->
<test-global-component></test-global-component> <!-- ์ ์ญ ์ปดํฌ๋ํธ ํ์ -->
</div>
</body>
<script>
// ์ ์ญ ์ปดํฌ๋ํธ ๋ฑ๋ก
Vue.component('test-global-component', {
template: "<div>์ ์ญ ์ปดํฌ๋ํธ์
๋๋ค.</div>" // ์ ์ญ ์ปดํฌ๋ํธ ๋ด์ฉ
});
// ์ง์ญ ์ปดํฌ๋ํธ ๋ด์ฉ
var localcmp = {
template: "<div>์ง์ญ ์ปดํฌ๋ํธ์
๋๋ค.</div>"
}
new Vue({
el: '#app',
data: {
},
components:{ // ์ง์ญ ์ปดํฌ๋ํธ ๋ฑ๋ก
'test-local-component' : localcmp,
}
});
</script>
- ์ ์ญ ์ปดํฌ๋ํธ๋ app, app1 ... ๋ฑ ์ฌ์ฌ์ฉ์ด ๊ฐ๋ฅํ์ง๋ง ์ง์ญ ์ปดํฌ๋ํธ๋ ๊ทธ๋ ์ง ๋ชปํ๋ค.
<body>
<div id="app">
<simple-component></simple-component> <!-- ์ ์ญ ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ O -->
<local-component></local-component> <!-- ๋ก์ปฌ ์ปดํฌ๋ํธ -->
</div>
<div id="app1">
<simple-component></simple-component> <!-- ์ ์ญ ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ O -->
<local-component></local-component> <!-- Error ๋ก์ปฌ ์ปดํฌ๋ํธ ์ฌ์ฌ์ฉ X -->
</div>
</body>
<script>
Vue.component('simpleComponent', {
template: '<b>Hello, world!</b>',
});
var cmp = {
template: '<h1>Hello world local compoenents</h1>'
}
new Vue({
el: "#app",
data: {
},
components: {
'local-component': cmp,
},
});
new Vue({ // ์์ฑ์ ์ถ๊ฐ
el: "#app1",
data: {
},
});
</script>
์ํ์ ์ปดํฌ๋ํธ ๊ด๊ณ
props
๋ฅผ ํตํด ์์ ์ปดํฌ๋ํธ์์ ํ์ ์ปดํฌ๋ํธ๋ก ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ค.- ํ์ ์ปดํฌ๋ํธ์์ ์์ ์ปดํฌ๋ํธ๋ก๋ ์ด๋ฒคํธ๋ง ์ ๋ฌํ ์ ์์. (์ด๋ฒคํธ ๋ฒ์ค๋ฅผ ์ด์ฉํ์ฌ ๋ฐ์ดํฐ ์ ๋ฌ ๊ฐ๋ฅ?)
Vue.component('child-component', {
props:['props ์์ฑ ์ด๋ฆ'],
});
์์
<body>
<div id="app">
<child-component :propstest="message"></child-component>
</div>
</body>
<script>
Vue.component('child-component', {
props:['propstest'],
template: "<p>{{propstest}}</p>"
});
new Vue({
el: '#app',
data: {
message: "hello, world",
},
});
</script>
์ํ์ ์ปดํฌ๋ํธ ๊ฐ ์ด๋ฒคํธ
- ์ด๋ฒคํธ ๋ฐ์
this.$emit('์ด๋ฒคํธ๋ช
')
- ์ด๋ฒคํธ ์์
<child-component v-on:์ด๋ฒคํธ๋ช
="์์ ์ปดํฌ๋ํธ์ ๋ฉ์๋๋ช
"></child-component>
์์
<body>
<div id="app">
<child-component v-on:show-log="printText"></child-component>
<!-- show-log: ํ์ ์ปดํฌ๋ํธ์ ์ด๋ฒคํธ ๋ช
, printText: ์์ ์ปดํฌ๋ํธ์ ๋ฉ์๋ ๋ช
-->
</div>
</body>
<script>
Vue.component('child-component', {
template: "<button v-on:click='showLog'>show</button>" // ๋ฒํผ ์์ ์ถ๊ฐ
,methods:{
showLog:function(){
this.$emit('show-log'); // ์ด๋ฒคํธ ๋ฐ์ ๋ก์ง (์ผ๋ฐฅ ์ผ์ด์ฑ)
}
}
});
new Vue({ // ์ต์์ ์ปดํฌ๋ํธ
el: '#app',
data: {
message: "hello, world",
},
methods:{
printText:function(){
console.log(this.message);
}
}
});
</script>
์ด๋ฒคํธ ๋ฒ์ค
- ๊ฐ์ ๋ ๋ฒจ์ ์ปดํฌ๋ํธ์ ๊ฒฝ์ฐ, ๋ฐ์ดํฐ ์ ๋ฌ์ ์์ ์ปดํฌ๋ํธ(๊ณตํต)๋ก ์ด๋ฒคํธ๋ฅผ ์ ๋ฌ ํ props๋ฅผ ์ด์ฉํ์ฌ ํ์ ์ปดํฌ๋ํธ๋ค(์ด๋ฒคํธ๋ฅผ ์ ๋ฌํ ์๊ธฐ์์ ํฌํจ, ๋์ ๊ฐ์๋ ๋ฒจ ์ปดํฌ๋ํธ)์๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํจ
- ์ด์ ๊ฐ์ ๋ฐ์ดํฐ ์ ๋ฌ ๊ตฌ์กฐ๋ ๋นํจ์จ์ ์ด๋ฏ๋ก '์ด๋ฒคํธ ๋ฒ์ค'๋ฅผ ํ์ฉ
- ์ด๋ฒคํธ ๋ฒ์ค๋ ์ํ์ ๊ด๊ณ๋ฅผ ์ ์งํ๊ณ ์์ง ์์๋ ์ปดํฌ๋ํธ ๊ฐ ๋ฐ์ดํฐ ์ ๋ฌ ๊ฐ๋ฅ. (Vuex ์ฃผ๋ก ์ฌ์ฉ)
<body>
<div id="app">
<child-component></child-component>
</div>
</body>
<script>
var eventBus = new Vue(); // ์ด๋ฒคํธ ๋ฒ์ค ์ธ์คํด์ค ์์ฑ
// ํ์ ์ปดํฌ๋ํธ
Vue.component('child-component',{
template: "<button v-on:click='showLog'>show</button>",
methods:{
showLog:function(){
eventBus.$emit('triggerEventBus', 100, 150, "hello"); // ์ด๋ฒคํธ ๋ฐ์ , $emit
}
}
});
// ์ต์์ ์ปดํฌ๋ํธ
new Vue({
el: '#app',
data: {
message: "hello, world! Vue.js"
},
methods:{
},
created:function(){
eventBus.$on('triggerEventBus', function(value1, value2, value3){ // ์ด๋ฒคํธ ์์ , $on
console.log(value1, value2, value3);
});
}
});
</script>
- ํ์ง๋ง, ์ปดํฌ๋ํธ๊ฐ ๋ง์์ง๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ด๋์ ์ด๋๋ก ๋ณด๋๋์ง ๊ด๋ฆฌ๊ฐ ์ด๋ ค์์ ธ Vuex(๋ทฐ์์ค)๋ผ๋ ์ํ ๊ด๋ฆฌ ๋๊ตฌ๊ฐ ํ์ํ๋ค.
๋ผ์ฐํ
-
์น ํ์ด์ง ๊ฐ์ ์ด๋ ๋ฐฉ๋ฒ์ผ๋ก ์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ ์์ ์ฃผ๋ก ์ฌ์ฉ
-
์ฑ๊ธ ํ์ด์ง ์ ํ๋ฆฌ์ผ์ด์ : ํ์ด์ง๋ฅผ ์ด๋ํ ๋๋ง๋ค ์๋ฒ์ ์น ํ์ด์ง๋ฅผ ์์ฒญํ์ฌ ์๋ก ๊ฐฑ์ ํ๋ ๊ฒ์ด ์๋๋ผ ๋ฏธ๋ฆฌ ํด๋น ํ์ด์ง๋ค์ ๋ฐ์ ๋๊ณ ํ์ด์ง ์ด๋ ์์ ํด๋ผ์ด์ธํธ์ ๋ผ์ฐํ ์ ์ด์ฉํ์ฌ ํ๋ฉด์ ๊ฐฑ์ ํ๋ ํจํด
-
CDN: ์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ(Content delivery network ๋๋ content distribution network)
<body>
<div id="app">
<h1>๋ทฐ ๋ผ์ฐํฐ ์์ </h1>
<p>
<router-link to="/main">Main ์ปดํฌ๋ํธ๋ก ์ด๋</router-link> <!-- to=""์ ์ ์๋ ํ
์คํธ ๊ฐ์ด ๋ธ๋ผ์ฐ์ URL ๋์ ์ถ๊ฐ๋จ -->
<router-link to="/login">Login ์ปดํฌ๋ํธ๋ก ์ด๋</router-link>
<router-link to="/sub">Sub ์ปดํฌ๋ํธ๋ก ์ด๋</router-link>
</p>
<router-view></router-view> <!-- URL ๊ฐ์ ๋ฐ๋ผ ๊ฐฑ์ ๋๋ ํ๋ฉด ์์ญ -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script> <!-- ๋ผ์ฐํฐ CDN -->
<script>
// 3. Main. Login ์ปดํฌ๋ํธ ๋ด์ฉ ์ ์
var Main = { template: '<div>main</div>' }; // Main ์ปดํฌ๋ํธ ์ ์
var Login = { template: '<div>login</div>' };
var Sub = { template: '<div>sub</div>'}
// 4. ๊ฐ url์ ํด๋นํ๋ ์ปดํฌ๋ํธ ๋ฑ๋ก
var routes = [
{ path: '/main', component: Main }, // routes ๋ณ์์๋ URL ๊ฐ์ด /main ์ผ ๋ Main ์ปดํฌ๋ํธ๋ฅผ ํ์ํ๋๋ก ์ ์
{ path: '/login', component: Login },
{ path: '/sub', component: Sub },
];
// 5. ๋ทฐ ๋ผ์ฐํฐ ์ ์
var router = new VueRouter({ // ๋ทฐ ๋ผ์ฐํฐ๋ฅผ ํ๋ ์์ฑํ๊ณ , routes๋ฅผ ์ฝ์
ํด URL์ ๋ฐ๋ผ ํ๋ฉด์ด ์ ํ๋ ์ ์๊ฒ ์ ์
routes
});
// 6. ๋ทฐ ๋ผ์ฐํฐ๋ฅผ ์ธ์คํด์ค์ ๋ฑ๋ก
var app = new Vue({
router // ๋ผ์ฐํฐ ์ถ๊ฐ
}).$mount('#app'); // $mount: ์ธ์คํด์ค๋ฅผ ํ๋ฉด์ ๋ถ์ฌ์ค (el ์์ฑ๊ณผ ๋์ผ)
// ์ธ์คํด์ค๋ฅผ ์์ฑํ ๋ el ์์ฑ์ ๋ฃ์ง ์์๋๋ผ๋ ์์ฑํ๊ณ ๋์ $mount()๋ฅผ ์ด์ฉํ๋ฉด ๊ฐ์ ๋ก ์ธ์คํด์ค๋ฅผ ํ๋ฉด์ ๋ถ์ผ ์ ์์
</script>
</body>
๋ผ์ฐํฐ URL์ ํด์ ๊ฐ(#)์ ์์ ๋ ค๋ฉด
- ํ์คํ ๋ฆฌ ๋ชจ๋(history mode) ํ์ฉ
var router = new VueRouter({
mode: 'history',
routes
});
๋ค์คํฐ๋ ๋ผ์ฐํฐ
- ๋ผ์ฐํฐ๋ก ํ์ด์ง๋ฅผ ์ด๋ํ ๋, ์ต์ 2๊ฐ ์ด์์ ์ปดํฌ๋ํธ๋ฅผ ํ๋ฉด์ ๋ํ๋ผ ์ ์๊ฒ ํจ
- ๋ค์คํฐ๋ ๋ผ์ฐํฐ๋ฅผ ์ด์ฉํ๋ฉด URL์ ๋ฐ๋ผ์ ์ปดํฌ๋ํธ์ ํ์ ์ปดํฌ๋ํธ๊ฐ ๋ค๋ฅด๊ฒ ํ์๋จ
<body>
<div id="app">
<router-view></router-view> <!-- User (์์) ์ปดํฌ๋ํธ๊ฐ ๋ฟ๋ ค์ง ์์ญ -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
<script>
var User = { // ์์ ์ปดํฌ๋ํธ ํ
ํ๋ฆฟ ์ ์ (๊ฐ์์ ์ผ๋ก ์ดํด๋ฅผ ๋๊ธฐ ์ํด button์ผ๋ก ์ ์ํจ)
template: `
<button>
User Component
<router-view></router-view>
</button>
`
// <router-view></router-view> : ํ์ ์ปดํฌ๋ํธ๊ฐ ๋ค์คํฐ๋ ๋ ์์ญ
// ์์ ๊ฐ์ด template์ ๋ค์ฌ์ฐ๊ธฐํ์ฌ ํ๊ธฐํ๋ ค๋ฉด ' ๊ฐ ์๋ ` ๋ก ๋ฌถ์ด ํ๊ธฐํด์ ํจ
};
var UserProfile = { template: '<button>User Profile Component</button>' }; // ํ์ ์ปดํฌ๋ํธ ํ
ํ๋ฆฟ ์ ์ (Profile)
var UserPost = { template: '<button>User Post Component</button>' }; // ํ์ ์ปดํฌ๋ํธ (Post)
var routes = [ // ๋ค์คํฐ๋ ๋ผ์ฐํ
์ ์
{
path: '/user',
component: User, // /user url์ User์ปดํฌ๋ํธ ๋งคํ
children: [ // ํ์ ์ปดํฌ๋ํธ ๋ผ์ฐํ
์ ์
{
path: 'posts', // /posts url์ UserPost์ปดํฌ๋ํธ ๋งคํ
component: UserPost
},
{
path: 'profile',
component: UserProfile
},
]
}
];
var router = new VueRouter({
routes
});
var app = new Vue({ // ๋ทฐ ์ธ์คํด์ค์ ๋ผ์ฐํฐ ์ถ๊ฐ
router
}).$mount('#app');
</script>
</body>
-
domain ๋ค์ ๋ถ์ด๊ธฐ
- /user : ์ต์์ ์ปดํฌ๋ํธ ์์ user(์์ ์ปดํฌ๋ํธ)๊ฐ ๋ถ์
- /user/profile : ์ต์์ ์ปดํฌ๋ํธ ์์ user(์์ ์ปดํฌ๋ํธ) ์์ profile(ํ์ ์ปดํฌ๋ํธ)๊ฐ ๋ถ์
- /user/posts
-
๋ค์คํฐ๋ ๋ผ์ฐํฐ๋ ํ๋ฉด์ ๊ตฌ์ฑํ๋ ์ปดํฌ๋ํธ์ ์๊ฐ ์ ์ ๋๋ ์ ์ฉํ์ง๋ง ๋ง์ ์ปดํฌ๋ํธ๋ฅผ ํ์ํ ๋๋ ๋ค์๋ ๋ทฐ๊ฐ ์ข์
๋ค์๋ ๋ทฐ
- ๋ค์๋ ๋ทฐ๋ ํน์ ํ์ด์ง๋ก ์ด๋ํ์ ๋, ์ฌ๋ฌ ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ๋์์ ํ์ํ๋ ๋ผ์ฐํ ๋ฐฉ์
- ๋ค์๋ ๋ทฐ๋ ์ ๊ทธ๋ฆผ ์ฒ๋ผ ๊ฐ์ ๋ ๋ฒจ์์ ์ฌ๋ฌ ๊ฐ์ ์ปดํฌ๋ํธ๋ฅผ ํ ๋ฒ์ ํ์ํ๋ ๋ฐฉ์
<body>
<div id="app">
<router-view name="header"></router-view> <!-- name="header" ๋ผ๋ name์ ๋ช
์ -->
<router-view></router-view> <!-- name์ด ์๋ ๊ฒฝ์ฐ 'default' -->
<router-view name="footer"></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.0.1/dist/vue-router.js"></script>
<script>
// ์ปดํฌ๋ํธ์ ํ
ํ๋ฆฟ ์ ์
var Body = { template: '<div>This is Body</div>' };
var Header = { template: '<div>This is Header</div>' };
var Footer = { template: '<div>This is Footer</div>' };
var router = new VueRouter({
routes: [
{
path: '/', // ๋ฃจํธ url์ ๋ชจ๋ ํ์; URL ๊ฐ '/'์ ์ํด ๋ค์๋ ๋ทฐ๊ฐ ๋ฐ๋ก ์คํ ๋จ
components: { // <router-view>์ name ์์ฑ๊ณผ ์ปดํฌ๋ํธ๋ฅผ ์ฐ๊ฒฐ
default: Body, // default์ Body ์ปดํฌ๋ํธ ์ฐ๊ฒฐ (default๋ <router-view> ํ๊ทธ์์ name์ ์ ์ํ์ง ์์ ๊ณณ์ ๋งคํ๋จ)
header: Header, // header์ Header ์ปดํฌ๋ํธ ์ฐ๊ฒฐ. <router-view name="header"> ์ ๋งคํ
footer: Footer
}
}
]
})
var app = new Vue({
router
}).$mount('#app');
</script>
</body>
๋ทฐ HTTP ํต์
-
์น ์ฑ HTTP ํต์ ์ ๋ํ์ ์ธ ์ฌ๋ก๋ก๋ jQuery์ ajax๊ฐ ์์ (JavaScript)
-
ajax๋ ์๋ฒ์์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ฅผ ํ์ํ ๋, ํ๋ฉด ์ ์ฒด๋ฅผ ๊ฐฑ์ ํ์ง ์๊ณ ํ๋ฉด ์ผ๋ถ๋ถ๋ง ๋ณ๊ฒฝํ ์ ์๊ฒ ํจ
-
Vue์์๋ ๋ทฐ ๋ฆฌ์์ค ๋๋ Axios๋ฅผ ์ฌ์ฉํ์ฌ HTTP ํต์ ์ ํจ. Axios๋ฅผ ํตํด Vue์ Spring Controller ๊ฐ ๋ฐ์ดํฐ ์ ์ก ๊ฐ๋ฅ
-
๋ทฐ ๋ฆฌ์์ค
-
Axios ์ก์์ค์ค
-
์ก์์ค์ค ๋ํ NPM์ ์ด์ฉํ์ฌ ์ค์นํ๊ฑฐ๋ CDN(์ฝํ ์ธ ์ ์ก ๋คํธ์ํฌ)์ ์ด์ฉํ์ฌ ์ค์นํ ์ ์์
-
Axios CDN
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
- ์ ์ฝ๋๋ฅผ HTML์ ์ถ๊ฐํ๋ฉด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ก๋ฉํ์ฌ ์ฌ์ฉํ ์ ์๋ ์ํ๊ฐ ๋จ
1.
// HTTP GET ์์ฒญ
axios.get('URL ์ฃผ์').then().catch();
- .get() : HTTP GET ์์ฒญ์ ๋ณด๋
- .then() : ์๋ฒ์์ ๋ณด๋ธ ๋ฐ์ดํฐ๋ฅผ ์ ์์ ์ผ๋ก ๋ฐ์์ค๋ฉด then() ์์ ์ ์ํ ๋ก์ง ์คํ
- .catch() : ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋ ์ค๋ฅ ๋ฐ์ ์ catch() ์์ ์ ์ํ ๋ก์ง ์ํ
2.
// HTTP POST ์์ฒญ
axios.post('URL ์ฃผ์').then().catch();
- .post() : HTTP POST ์์ฒญ์ ๋ณด๋
- .then() : ์๋ฒ์์ ๋ณด๋ธ ๋ฐ์ดํฐ๋ฅผ ์ ์์ ์ผ๋ก ๋ฐ์์ค๋ฉด then() ์์ ์ ์ํ ๋ก์ง ์คํ
- .catch() : ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ๋ ์ค๋ฅ ๋ฐ์ ์ catch() ์์ ์ ์ํ ๋ก์ง ์ํ
3.
// HTTP ์์ฒญ์ ๋ํ ์ต์
์์ฑ ์ ์
axios({
method: 'get',
url: 'URL ์ฃผ์',
...
});
-
HTTP ์์ฒญ์ ๋ํ ์์ธํ ์์ฑ๋ค์ ์ง์ ์ ์๊ฐ๋ฅ
-
์์
<body>
<div id="app">
<button v-on:click="getData">ํ๋ ์์ํฌ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ</button>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> <!-- axios CDN -->
<script>
new Vue({
el: '#app',
methods: {
getData: function() {
axios.get('https://raw.githubusercontent.com/joshua1988/doit-vuejs/master/data/demo.json')
.then(function(response) {
console.log(response);
}).catch(function(){
console.log('Error!')
});
}
}
});
</script>
</body>
- 'ํ๋ ์์ํฌ ๋ชฉ๋ก ๊ฐ์ ธ์ค๊ธฐ' ๋ฒํผ ํด๋ฆญ ํ '๊ฐ๋ฐ์ ๋๊ตฌ'๋ก ๊ฐ์ฒด ํ์ธ
๋ทฐ ํ ํ๋ฆฟ
- ์๋ฐ์คํฌ๋ฆฝํธ ํํ์ ์ฌ์ฉ ์ ์ฃผ์ํ ์
<!-- 1. -->
{{ var a = 10; }} <!-- X, ์ ์ธ๋ฌธ์ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ -->
{{ if (true) {return 100} }} <!-- X, ๋ถ๊ธฐ ๊ตฌ๋ฌธ์ ์ฌ์ฉ ๋ถ๊ฐ๋ฅ -->
{{ true ? 100 : 0 }} <!-- O, ์ผํญ ์ฐ์ฐ์๋ก ํํ ๊ฐ๋ฅ -->
<!-- 2. -->
{{ message.split('').reverse().join('') }} <!-- X, ๋ณต์กํ ์ฐ์ฐ์ ์ธ์คํด์ค ์์์ ์ํ -->
{{ reversedMessage }} <!-- O, ์คํฌ๋ฆฝํธ์์ computed ์์ฑ์ผ๋ก ๊ณ์ฐ ํ ์ต์ข
๊ฐ๋ง ํํ -->
- ์บ์ฑ: ๋ฐ์ดํฐ๋ ๊ฐ์ ์์ ์ฅ์์ ๋ฏธ๋ฆฌ ๋ณต์ฌํด ๋๋ ๋์
- ๋ทฐ ๋๋ ํฐ๋ธ: HTML ํ๊ทธ ์์ v- ์ ๋์ฌ๋ฅผ ๊ฐ์ง๋ ๋ชจ๋ ์์ฑ ex) v-bind, v-if ...
๋ทฐ ๋๋ ํฐ๋ธ
v-if
์ง์ ํ ๋ทฐ ๋ฐ์ดํฐ ๊ฐ์ ์ฐธ, ๊ฑฐ์ง ์ฌ๋ถ์ ๋ฐ๋ผ HTML ํ๊ทธ๋ฅผ ํ๋ฉด์ ํ์ํ๊ฑฐ๋ ๋ฏธํ์v-for
์ง์ ํ ๋ทฐ ๋ฐ์ดํฐ์ ๊ฐ์๋งํผ HTML ํ๊ทธ๋ฅผ ๋ฐ๋ณต ์ถ๋ ฅv-show
v-if์ ์ ์ฌ, v-if๋ ๊ฑฐ์ง์ ํ๊ทธ๋ฅผ ์์ ์ญ์ ํ์ง๋ง v-show๋ cssํจ๊ณผ๋ง display:none์ผ๋ก ์ฃผ์ด ์ค์ ํ๊ทธ๋ ๋จ๊ณ ํ๋ฉด ์์ผ๋ก๋ง ๋ณด์ด์ง ์์v-bind
HTML ํ๊ทธ์ ๊ธฐ๋ณธ ์์ฑ๊ณผ ๋ทฐ ๋ฐ์ดํฐ ์์ฑ์ ์ฐ๊ฒฐv-on
ํ๋ฉด ์์์ ์ด๋ฒคํธ๋ฅผ ๊ฐ์ง ex) v-on:click์ ํด๋น ํ๊ทธ์ ํด๋ฆญ ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ์ฌ ํน์ ๋ฉ์๋๋ฅผ ์คํํ ์ ์์v-model
form(ํผ)์์ ์ฃผ๋ก ์ฌ์ฉ๋๋ ์์ฑ. ํผ์ ์ ๋ ฅํ ๊ฐ์ ๋ทฐ ์ธ์คํด์ค์ ๋ฐ์ดํฐ์ ์ฆ์ ๋๊ธฐํ
computed ์์ฑ๊ณผ methods ์์ฑ์ ์ฐจ์ด์ (+ watch ์์ฑ)
- methods ์์ฑ์ ํธ์ถํ ๋๋ง ํด๋น ๋ก์ง์ด ์ํ๋๊ณ , computed ์์ฑ์ ๋์ ๋ฐ์ดํฐ์ ๊ฐ์ด ๋ณ๊ฒฝ๋๋ฉด ์๋์ ์ผ๋ก ์ํ๋จ
computed ์ฅ์
- computed ์์ฑ์ ์ฒซ ๋ฒ์งธ ์ฅ์ ์ data ์์ฑ ๊ฐ์ ๋ณํ์ ๋ฐ๋ผ ์๋์ผ๋ก ๋ค์ ์ฐ์ฐ
- computed ์์ฑ์ ๋ ๋ฒ์งธ ์ฅ์ ์ ์บ์ฑ - ๋์ผํ ์ฐ์ฐ์ ๋ฐ๋ณตํด์ ํ์ง ์๊ธฐ ์ํด ์ฐ์ฐ์ ๊ฒฐ๊ณผ ๊ฐ์ ๋ฏธ๋ฆฌ ์ ์ฅํ๊ณ ์๋ค๊ฐ ํ์ํ ๋ ํธ์ถ
- ๋ง์ฝ ํ๋ฉด ์ฌ๋ฌ ๊ณณ์ ๊ฐ์ ๊ฐ์ ํ์ํด์ผ ํ๋ค๋ฉด ์บ์ฑ์ ์ ๊ณตํ๋ computed๋ฅผ ํ์ฉํ๋ฉด ์ข์
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
computed: { // computed
reverseMsg: function() {
return this.message.split('').reverse().join('');
}
}
});
watch ์์ฑ
- watch ์์ฑ์ ๋ฐ์ดํฐ ๋ณํ๋ฅผ ์ค์๊ฐ์ผ๋ก ๊ฐ์งํ์ฌ ์๋์ผ๋ก ํน์ ๋ก์ง์ ์ํ
- ๋ฐ์ดํฐ ํธ์ถ๊ณผ ๊ฐ์ด ์๊ฐ์ด ์๋์ ์ผ๋ก ๋ ๋ง์ด ์๋ชจ๋๋ ๋น๋๊ธฐ ์ฒ๋ฆฌ์ ์ ํฉ
<body>
<div id="app">
<input v-model="message"> <!-- v-model ํ์ฉ -->
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script>
<script>
new Vue({
el: '#app',
data: {
message: 'Hello Vue.js!'
},
watch: { // watch
message: function(data) {
console.log("message์ ๊ฐ์ด ๋ฐ๋๋๋ค : ", data);
}
}
});
</script>
</body>
.vue ํ์ผ ๊ตฌ์กฐ / ์ฑ๊ธ ํ์ผ ์ปดํฌ๋ํธ ์ฒด๊ณ
- .vue ํ์ผ์ ์๋์ ๊ฐ์ ๊ธฐ๋ณธ๊ตฌ์กฐ๋ฅผ ๊ฐ์ง๋ค.
<template>
<!-- HTML ํ๊ทธ ๋ด์ฉ -->
</template>
<script>
export default {
// ์๋ฐ์คํฌ๋ฆฝํธ ๋ด์ฉ
}
</script>
<style>
/* CSS ์คํ์ผ ๋ด์ฉ */
</style>
Author And Source
์ด ๋ฌธ์ ์ ๊ดํ์ฌ([Vue.js] ๋ทฐ ๊ธฐ์ด), ์ฐ๋ฆฌ๋ ์ด๊ณณ์์ ๋ ๋ง์ ์๋ฃ๋ฅผ ๋ฐ๊ฒฌํ๊ณ ๋งํฌ๋ฅผ ํด๋ฆญํ์ฌ ๋ณด์๋ค https://velog.io/@kmdngmn/Vue.js-๊ธฐ๋ณธ-๊ตฌ์กฐ์ ์ ๊ท์: ์์์ ์ ๋ณด๊ฐ ์์์ URL์ ํฌํจ๋์ด ์์ผ๋ฉฐ ์ ์๊ถ์ ์์์ ์์ ์ ๋๋ค.
์ฐ์ํ ๊ฐ๋ฐ์ ์ฝํ
์ธ ๋ฐ๊ฒฌ์ ์ ๋
(Collection and Share based on the CC Protocol.)
์ข์ ์นํ์ด์ง ์ฆ๊ฒจ์ฐพ๊ธฐ
๊ฐ๋ฐ์ ์ฐ์ ์ฌ์ดํธ ์์ง
๊ฐ๋ฐ์๊ฐ ์์์ผ ํ ํ์ ์ฌ์ดํธ 100์ ์ถ์ฒ ์ฐ๋ฆฌ๋ ๋น์ ์ ์ํด 100๊ฐ์ ์์ฃผ ์ฌ์ฉํ๋ ๊ฐ๋ฐ์ ํ์ต ์ฌ์ดํธ๋ฅผ ์ ๋ฆฌํ์ต๋๋ค