Vue v: 동작 다루기

KHW·2021년 9월 20일
0

프레임워크

목록 보기
2/43

Vue

🍒 디렉티브 : v-

Vue에서 제공하는 특수 속성임을 나타내는 v- 접두어가 붙어있으며 렌더링 된 Dom에 특수한 반응형 동작을 합니다.


🍒 기본적으로 이해할 것

1. Vue 동작

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 {…}

2. 일반 동작

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는 전역객체로 바뀌므로)


🍒 1. 1초마다 count 증가 코드

<!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>

🍒 2. 버튼 클릭시 count 증가 코드

<!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>

v-on : 이벤트="함수이름"

vue의 이벤트에 따라 해당하는 함수를 동작시킬수 있다.
해당 함수는 methods : 를 통해 등록되어 있다.


🍒 3. 오렌지색 글씨의 count 증가 코드

<!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>

v-bind:class="{ class 값 : return의 key 값}"

변수값이 true냐 false냐에 따라 class에 key값이 적용되면서 v-bind를 통해 class = key 형태로 만들어진다.
만약 v-bind를 사용하지않으면 class="{orange:active}" 이런식으로
제대로된 결과가 나타나지 않는다.


🍒 4. 버튼 클릭에 따르는 출력/미출력

<!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

v-if가 true일때 해당 태그는 출력되고
v-if가 false일때 해당 태그는 주석처리된다.


🍒 5. 특정 태그 반복 출력

<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>

v-for="val in arr"

arr의 배열마다 각각의 val을 처리할 수 있게 순회하며 처리한다.

<ul>
  <li>Apple</li>
  <li>Banana</li>
  <li>Cherry</li>
</ul>

🍒 6. fruit-item 태그 사용하기

  1. templateprops를 가진 객체를 하나 생성 (FruitItem)
  2. App components에 해당 객체를 등록
    (등록시 같은 key와 변수일 경우 하나로 생략가능)
  3. components의 key값을 대문자에 따라 소문자와-로 태그에서는 처리한다.
    (FruitItem -> fruit-item)
  • 1~3이 fruit-item태그를 li로 만드는 방법이다.
  1. v-for의 fruits를 통해 태그를 반복실행한다.
  2. n의 경우 각각 apple,banana,cherry이다.
  3. FruitItem의 props의 받아온 fruitName이 마찬가지로 태그에서는 fruit-name으로 바뀌어 innerHTML 값을 각각 처리하되
  4. "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>

🍒 7. v-에 영향을 받지 않게 하기

<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>

v-once

app을 통해 만들어진 인스턴스인 vm에 vm.msg의 값을 바꿀경우
h1 태그 내의 값은 변경되나 h2의 값은 변경되지 않는다.

🍒 8. 태그값 집어넣기

<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

v-html의 대상으로 return의 key값을 설정해 놓으면 하위태그로 해당 value값이 적용된다.

profile
나의 하루를 가능한 기억하고 즐기고 후회하지말자

0개의 댓글