์ด์ ๋ Vue๋ ์๋ฐ๊ฑฐ์์๋ผ๊ณ ์๊ฐํ ์ ๋๋ผ๋ฉด ์ค๋๋ถํฐ๋ ์ธ์ธํ๊ฒ ํ๋์ฉ ๊ฐ๋
๋ค์ ์ง์ด๋๊ฐ๋ค.
HTML ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์ธ๋ฉํ ๋ ์ ์ฉํ๊ฒ ์ธ ์ ์๋ Computed์ Watch ์์ฑ, ํด๋์ค๋ก ์คํ์ผ์ ๋ฐ์ธ๋ฉํ๋ ๋ฒ์ ๋ฐฐ์ ๋ค.
2์ฐจํ ์ธํฌํ์๋ค๊ณผ ์์ง๊น์ง ์ด์์ด์ํ๋ค ใ ใ ใ ใ 1์ฐจํ ๋๋ ๊ทธ๋ฌ์์ผ๋ ํ๋ฃจํ๋ฃจ ์กฐ๊ธ์ฉ ํ์๋ค์ ์์๊ฐ์ผ๊ฒ ๋ค. ๋๋ฌด ๊ฐ์์ค๋ฝ๊ฒ ์นํด์ง๋ ค๊ณ ๋ค๊ฐ๊ฐ๋ฉด ๋ถ๋ด์ค๋ฌ์ธ ์ ์์ผ๋... ์ธํฌํ์๋ถ๋ค ๋ณด๊ณ ๊ณ์์ฃ ?
Vue์์๋ computed ์์ฑ์ผ๋ก ๋ฉ์๋๋ฅผ ํตํด ๊ณ์ฐ๋ ๊ฐ์ ๋ฐ๋ก HTML์ ๋ฐ์ธ๋ฉ ํ ์ ์๋ค.
<div id="app">
<h1>{{count}}</h1>
<h2>{{double}}</h2>
<h2>{{double}}</h2>
<h2>{{double}}</h2>
<h2>{{double}}</h2>
</div>
<script>
const App = {
data() {
return {
count: 3,
};
},
computed: {
double() {
return this.count * 2;
},
},
};
...
</script>
methods ์์ฑ์ ํตํด double
์ด๋ ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด HTML์ ์ฌ์ฉํ ๋๋ง๋ค ๊ณ์ฐ ๋ก์ง์ ๋๋ ค์ผ ํ๋ฏ๋ก ๋ฉ๋ชจ๋ฆฌ ์ฑ๋ฅ ์ธก๋ฉด์์ ๋ญ๋นํ๊ฒ ๋๋ค.
๋ฐ๋ผ์ ๋๊ฐ์ ๊ณ์ฐ๊ฐ์ ์ฌ์ฌ์ฉํ๋ ์ํฉ์ผ ๋๋ methods๊ฐ ์๋ computed ์์ฑ์ ์ฌ์ฉํ์!
computed ์์ฑ์ ํตํด ๊ณ์ฐ๋ ๋ฐ์ดํฐ๋ฅผ ์ฌ์ฌ์ฉํ๋ ๊ฒ๊น์ง ์๊ฒ ๋ค.
ํ์ง๋ง ๋จ์ํ ๋ฉ์๋ ํํ๋ก ๋ฐ์ดํฐ๋ฅผ computed๋ก ์ฌ์ฉํ๋ฉด ๋ฌธ์ ๊ฐ ์๋ค.
<div id="app">
<h1>{{ fullName }}</h1>
<h2>{{ firstName }}</h2>
<h2>{{ lastName }}</h2>
</div>
<script>
const App = {
data() {
return {
firstName: 'Cho',
lastName: 'ikjun',
};
},
computed: {
fullName() {
return `${this.firstName} ${this.lastName}`
},
},
};
const vm = Vue.createApp(App).mount('#app');
</script>
๊ธฐ์กด ๋ฐฉ์๋๋ก fullName
์ด๋ ๊ณ์ฐ๊ฐ์ ์ผ๋ฐ ํจ์ ๋ฐํ๊ฐ์ผ๋ก ๋๊ฒจ์ฃผ๊ฒ๋๋ฉด ์ผํ ๋ณด๋ฉด ์ ๋์ํ๋ ๊ฒ ๊ฐ๋ค.
ํ์ง๋ง fullName
์ด๋ ๊ฐ์ ์ง์ ๋ณ๊ฒฝํด๋ ๋ฐ์์ฑ์ด ์ ์ฉ๋์ง ์๋๋ค. 'Pro Grammers'๋ก ๋ณ๊ฒฝํ์ง๋ง ์ด๋ฆ์ด ๊ทธ๋๋ก์ด๋ค.
์ ๊ทธ๋ฐ๊ฑธ๊น?
๊ทธ ์ด์ ๋ Proxy ๊ตฌ์กฐ์์ ์ธ๊ธํ๋ ๊ฒ์ฒ๋ผ getter์ setter ํจ์ ์ค ํจ์ ๋ฐํ๊ฐ ํํ๋ก computed๋ฅผ ์์ฑํ๊ฒ๋๋ฉด getter๋ง ๊ตฌํ๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ด๋ค.
์๋กญ๊ฒ ๋ฐ์ดํฐ๋ฅผ ์ฐ๋ํ๊ธฐ ์ํด์๋ computed ์์ฑ ๋ด์์๋ get, set ํจ์๋ฅผ ๊ตฌ๋ถํด์ ๊ตฌํํด์ผ ํ๋ค.
computed: {
fullName: {
// fullName ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ค๋ get ํจ์
get() {
return `${this.firstName} ${this.lastName}`;
},
// fullName ๋ฐ์ดํฐ๋ฅผ ์ค์ ํ๋ set ํจ์
set(newValue) {
const names = newValue.split(' ');
this.firstName = names[0];
this.lastName = names[names.length - 1];
},
},
},
์์ ๊ฐ์ด ์ฝ๋๋ฅผ ๊ตฌํํ๊ฒ ๋๋ฉด fullName
์ ์ฝ์์์ ๋ณ๊ฒฝํ์ ๋ฐ๋ก ์ฐ๋๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ฐ์ดํฐ๊ฐ ์์ ํ์ ์ผ ๊ฒฝ์ฐ์๋ watch ์์ฑ์ ๋ฐ์ดํฐ ์ด๋ฆ ๋์ผํ๊ฒ ๋ฉ์๋ ํํ๋ก ์ง์ ํด์ฃผ๋ฉด ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋ ๋ ๋ก์ง์ ์คํํ ์ ์๋ค.
ํ์ง๋ง ๊ฐ์ฒด๋ ๋ฐฐ์ด์ผ ๊ฒฝ์ฐ์๋ ๋ด๋ถ ์์ฑ์ด๋ ์์๊ฐ ๋ณ๊ฒฝ๋์์ ๊ฒฝ์ฐ์๋ ๋ฉ์๋ ํํ๋ก watch ์์ฑ์ ์ง์ ํ๋ฉด ๊ฐ์งํ์ง ๋ชปํ๋ค.
๋ฐ๋ผ์ ์๋ ์ฝ๋์ ๊ฐ์ด watch ์์ฑ์ ํตํด ์คํํ ๋ก์ง์ handler
๋ก ๊ฐ์ธ๊ณ deep: true
์ด๋ ์์ฑ์ ์ถ๊ฐํ๋ฉด ๊น๊ฒ ๋ฐ์ดํฐ์ ๋ณํ๋ฅผ ๊ฐ์งํ ์ ์๋ค.
<script>
const App = {
data() {
return {
user: {
name: 'Ikjun',
age: 28,
},
fruits: [
{ id: 1, name: 'Apple' },
{ id: 2, name: 'Banana' },
{ id: 3, name: 'Cherry' },
],
};
},
watch: {
user: {
handler(newValue, oldValue) {
console.log(newValue, oldValue);
},
deep: true, // ๊น๊ฒ ๊ฐ์ง
},
fruits: {
handler() {
console.log(this.fruits);
},
deep: true,
immediate: true, // DOM์ด ๋ ๋๋ง๋์๋ง์ ๊ฐ์ง ์์
},
},
}
</script>
immediate: true
์์ฑ์ DOM์ด ๋ ๋๋ง๋์๋ง์ ํด๋น ๋ฐ์ดํฐ์ ์ํ๋ฅผ ๊ฐ์งํ๊ธฐ ์์ํ๋๋ก ํ๋ ์ต์
์ธ๋ฐ deep
๊ณผ ๊ฐ์ด ์ฌ์ฉํ๋ฉด ์ ์ฉํ๋ค.
์๋ ์ฌ์ง์์์ฒ๋ผ ์ด๊ธฐ fruits
๋ฐฐ์ด์ ํ๋ก์์ capitalize ๋ฒํผ์ ์ํด ๋ด๋ถ ์์๊ฐ ๋ณ๊ฒฝ๋ fruits
๋ฐฐ์ด ํ๋ก์๊ฐ ์ฝ์์ ์ถ๋ ฅ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
v-bind
๋ฅผ ํตํด classObject
๊ฐ์ฒด ํํ์ ํด๋์ค๋ก ์ฌ๋ฌ ํด๋์ค๋ฅผ ํ๊บผ๋ฒ์ HTML ์์์ ์ง์ ํ ์ ์๋ค.
<div id="app">
<!-- ... -->
<h1 :class="classObject" class="title">{{ msg }}</h1>
</div>
<script>
const App = {
data() {
return {
// ...
active: false,
small: true,
};
},
computed: {
classObject() {
return {
active: this.active,
'title--small color--orange': this.small,
};
},
},
};
</script>
์ ์ฌ์ง๊ณผ ์ฒ๋ผ acitve
์ title--small
, color--orange
ํด๋์ค์ ๋ํ acitve
, small
๋ฐ์ดํฐ๊ฐ ์ ๋ฐ์ธ๋ฉ๋์ด ์ถ๊ฐ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
ํ์ง๋ง ์๋์ ๊ฐ์ด computed ์์ฑ์ ์ฌ์ฉํ์ง ์๊ณ ๋ฐ์ธ๋ฉํ๊ฒ ๋๋ฉด data()
์ ์๋ acitve
์ small
์์ฑ์ ์ฐ๋ํ ์๊ฐ ์๋ค.
<script>
const App = {
data() {
return {
// ...
active: false,
small: true,
classObject: {
active: false,
'title--small color--orange': true
}
};
},
};
</script>
๋ฐ๋ผ์ Vue ์ดํ๋ฆฌ์ผ์ด์
๋ด ๋ฐ์ํ ๋ฐ์ดํฐ๋ฅผ ํ์ฉํด์ผ ํ๋ ๊ฐ์ฒด๋ ๋จ์ํ data ๋ด์ ๋ง๋๋ ๊ฒ์ด ์๋๋ผ
computed ์์ฑ์์ this๋ก ์ฐ๋ํด์ผ ํ๋ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ง๋ ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ฃผ์ด์ผ ํ๋ค.
์๋ ์ฝ๋์์ h1
ํ๊ทธ์ styleObject
, titleStyleObject
๋ ๊ฐ์ style ๊ด๋ จ ๊ฐ์ฒด๋ฅผ ๋ฐ์ธ๋ฉํ ๋ ์์๋ฅผ ์ฃผ์ํด์ผ ํ๋ค.
<div id="app">
<h1 :style="[titleStyleObject, styleObject]">Hello Vue!</h1>
</div>
<script>
const App = {
data() {
return {
styleObject: {
color: 'royalblue',
backgroundColor: 'orange',
},
titleStyleObject: {
fontSize: '40px',
fontWeight: 'bold',
color: 'brown',
},
};
},
};
// ...
</script>
๋ฐฐ์ด ๋ฆฌํฐ๋ด์์ ๋์ค์ ๋ฐ์ธ๋ฉ๋๋ CSS ๊ฐ์ผ๋ก ๋ฎ์ด์จ์ง๊ฒ ๋๋ฏ๋ก ํ์ฌ ์ฝ๋์์ ์ค๋ณต๋๋ color
์์ฑ์์ ๋์ค์ ๋ฐ์ธ๋ฉ๋styleObject
์ royalblue
๊ฐ์ ๊ฐ์ง๊ฒ ๋๋ค.
๊ฐ์๋ฅผ ๋ค์ผ๋ฉด์ ๋ชจ๋ ๋ด์ฉ์ ์ ๋ฆฌํ๋ ๊ฒ์ด ์๋๋ผ ๊ทธ ์ค ์ ๋ง ์ค์ํ ๊ฒ์ ๊ฐ์๋ณ๋ก ํ๋์ฉ ๊ผฝ์์ ์์ฝํ๋ ๋ญ๊ฐ ๋ ์ง์ค๋ ์๋๊ณ ์ดํด๊ฐ ๋น ๋ฅธ ๊ฒ ๊ฐ๋ค. ์์ฝํ์ฌ ์ค๋ช ํ๊ธฐ ๊ณ์ ์งํํด์ผ๊ฒ ๋ค.
Vue๋ง์ ํ ํ๋ฆฟ ๋ฌธ๋ฒ์ด ์์ง ์ต์์น๊ฐ ์์์ ๊ณ์ ๊ณต์๋ฌธ์๋ฅผ ์ฐพ์๋ณด๊ฒ๋๋ค. ์์ง 2์ผ์ฐจ๋ผ ๋ฐ๋ก ์๋๊ฒ ๋ถ๊ฐ๋ฅํ์ง๋ง์ ๊ธฐ๋ณธ ํ ํ๋ฆฟ ๋ฌธ๋ฒ์ ๋ํด์ ๋ ์์ง๊ฐ ํ์ํ๋ค.
Vue ๊ฐ์ ๋ง๊ณ ๋ CSS ๊ณผ์ ํผ๋๋ฐฑ ๋ฐ ํ๋ฌํ๊ณ ๋ฐ ํฌํธํด๋ฆฌ์ค ๋ณด์ ๋ฑ ํ ๊ฒ ํ์ฐ์ด๋ค. ์ผ๋ฅธ ํ๋์ฉ ๋๋ด๋๋ก ํ์.
๐ ํด๋น ๋ด์ฉ์ ๊ณต๋ถํ๋ฉด์ ์ ๋ฆฌํ ๊ธ์ ๋๋ค. ํ๋ฆฐ ๋ถ๋ถ์ด๋ ์คํดํ๊ณ ์๋ ๋ถ๋ถ์ด ์๋ค๋ฉด ํผ๋๋ฐฑ ๋ถํ๋๋ฆฝ๋๋ค.
ํ ๊ฒ ํ์ฐ์ด์๋ผ๋,, ์ค๋๋ ๋ฑ๋ํ์๊ฒ ๋ค์