v-
Vue에서 제공하는 특수 속성임을 나타내는
v-
접두어가 붙어있으며 렌더링 된 Dom에 특수한 반응형 동작을 합니다.
const App = {
data(){
return {
counter:0,
}
},
mounted(){
setInterval(()=>{
console.log(this.counter++)
console.log(this)
},2000)
}
}
const app = Vue.createApp(App).mount('#app')
해당 코드가 진행되면 Vue를 통해 return의 counter를 찾아가고
this는 Proxy {...}로 진행된다.
만약 setInterval을 function(){ ... }로 한다면 해당 부분의 this는 window객체가 되어 제대로 된 값을 찾지못한다.
따라서 화살표함수가 되어야한다.
0
Proxy {…}
1
Proxy {…}
2
Proxy {…}
const App = {
data(){
return {
counter:0,
}
},
mounted(){
setInterval(()=>{
console.log(this.counter)
console.log(this)
},2000)
}
}
App.mounted()
이런식으로 진행하면 this.counter는 아예 찾지 못하고 this 또한 App이긴 하지만 원하는 counter는 찾지를 못한다.
undefined
{ data: [Function: data], mounted: [Function: mounted] }
undefined
{ data: [Function: data], mounted: [Function: mounted] }
...
Vue는 Vue 나름의 틀을 통해 this는 Proxy로 접근하여 처리한다.
이때 this를 Proxy로 유지하기 위해서는 콜백함수로 화살표함수를 사용해야한다. (일반함수로 사용할 경우 this는 전역객체로 바뀌므로)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<div >{{counter}}</div>
</div>
<script type="module">
const App = {
data(){
return {
counter:0,
}
},
mounted(){
setInterval(()=>{
this.counter++
},1000)
}
}
const app = Vue.createApp(App).mount('#app')
</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<div>{{counter}}</div>
<button v-on:click="increase">Click me</button>
</div>
<script type="module">
const App = {
data(){
return {
counter:0,
active:true
}
},
methods:{
increase(){
this.counter++;
}
}
}
const app = Vue.createApp(App).mount('#app')
</script>
</body>
</html>
vue의 이벤트에 따라 해당하는 함수를 동작시킬수 있다.
해당 함수는methods :
를 통해 등록되어 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<style>
.orange{
color:orange;
}
</style>
<div id="app">
<div v-bind:class="{orange:active}">{{counter}}</div>
<button v-on:click="increase">Click me</button>
</div>
<script type="module">
const App = {
data(){
return {
counter:0,
active:true
}
},
methods:{
increase(){
this.counter++;
}
}
}
const app = Vue.createApp(App).mount('#app')
</script>
</body>
</html>
변수값이 true냐 false냐에 따라 class에 key값이 적용되면서 v-bind를 통해
class = key
형태로 만들어진다.
만약 v-bind를 사용하지않으면class="{orange:active}"
이런식으로
제대로된 결과가 나타나지 않는다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vite App</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app">
<div v-if="active">Hello Vue!</div>
<button v-on:click="toggle">Toggle</button>
</div>
<script type="module">
const App = {
data() {
return {
counter: 0,
active : false
}
},
methods:{
toggle(){
this.active = !this.active
}
}
}
const app = Vue.createApp(App).mount('#app')
</script>
</body>
</html>
v-if가 true일때 해당 태그는 출력되고
v-if가 false일때 해당 태그는 주석처리된다.
<body>
<div id="app">
<ul>
<li v-for="fruit in fruits">
{{ fruit }}
</li>
</ul>
</div>
<script type="module">
const App = {
data() {
return {
fruits:[
'Apple','Banana','Cherry'
]
}
},
methods:{
toggle(){
this.active = !this.active
}
}
}
const app = Vue.createApp(App).mount('#app')
</script>
arr의 배열마다 각각의 val을 처리할 수 있게 순회하며 처리한다.
<ul>
<li>Apple</li>
<li>Banana</li>
<li>Cherry</li>
</ul>
template
와props
를 가진 객체를 하나 생성 (FruitItem)- App components에 해당 객체를 등록
(등록시 같은 key와 변수일 경우 하나로 생략가능)- components의 key값을 대문자에 따라 소문자와
-
로 태그에서는 처리한다.
(FruitItem -> fruit-item)
- v-for의 fruits를 통해 태그를 반복실행한다.
- n의 경우 각각 apple,banana,cherry이다.
- FruitItem의 props의 받아온 fruitName이 마찬가지로 태그에서는
fruit-name
으로 바뀌어innerHTML
값을 각각 처리하되"n"
을n
이 아니라 원하는 vue와 관련된 처리를 해야하므로 앞에 v-bind를 붙여준다.
<body>
<div id="app">
<ul>
<fruit-item
v-for="n in fruits"
v-bind:fruit-name="n"></fruit-item>
</ul>
</div>
<script type="module">
const FruitItem = {
template : '<li>{{fruitName }}</li>',
props : ['fruitName']
}
const App = {
components : {
FruitItem : FruitItem //FruitItem으로 생략 가능
},
data() {
return {
fruits:[
'Apple','Banana','Cherry'
]
}
},
}
const app = Vue.createApp(App).mount('#app')
</script>
<div id="app">
<h1>{{msg}}</h1>
<h2 v-once>{{ msg }} </h2>
</div>
<script>
//App 변수를 통해 넣는다
const App = {
data(){
return {
msg : 'Hello Vue!'
}
}
}
const app = Vue.createApp(App)
const vm = app.mount('#app')
</script>
app을 통해 만들어진 인스턴스인 vm에
vm.msg
의 값을 바꿀경우
h1 태그 내의 값은 변경되나 h2의 값은 변경되지 않는다.
<div id="app">
<div v-html="rawHTML"></div>
</div>
<script>
//App 변수를 통해 넣는다
const App = {
data(){
return {
rawHTML : '<h3 style="color:red;">Raw HTML</h3>'
}
}
}
const app = Vue.createApp(App)
const vm = app.mount('#app')
</script>
v-html의 대상으로 return의 key값을 설정해 놓으면 하위태그로 해당 value값이 적용된다.