데브코스 34일차 TIL : Vue 문법 [ 디렉티브, 템플릿, 라이프사이클, Proxy, watch ]

te-ing·2021년 9월 30일
0
post-thumbnail

디렉티브: v-으로 시작되는 것 v-if, v-...

ex)v-bind:class="{ orange: active }" <button v-on:click="">Toggle</button>

<div id="app">
    <div v-if="active">Hello Vue!</div>
    <button v-on:click="toggle">Toggle</button>
  </div>

  <script>
    const App = {
      data() {
        return {
          active: false
        }
      },
      methods: {
        toggle() {
          this.active = !this.active
        }
      }
    }
    Vue.createApp(App).mount('#app')
  </script>

fruits: [ 'Apple', 'Banana', 'Cherry' ]

<li *v-for*="fruit in fruits"> {{ fruit }} </li> 배열데이터 사용

<body>
  <div id="app">
    <ul>
      <fruit-item v-for="name in fruits" 
      v-bind:fruit-name="name"></fruit-item>
    </ul>
  </div>

  <script>
    const FruitItem = {
      template: '<li>{{ fruitName }}</li>',
      props: ['fruitName']
    }

    const App = {
      components: {
        FruitItem: FruitItem
      },

      data() {
        return {
          fruits: [
            'Apple', 'Banana', 'Cherry'
          ]
        }
      }
    }
    Vue.createApp(App).mount('#app')
  </script>

FruitItem이 fruit-item으로, fruitName이 fruit-name으로 변환됨

html에서는 dash-case를, JS에서는 camel-case를 사용하며, 변환되는 내용을 Vue가 처리해줌

Vue.JS 라이프사이클

beforeCreate() { 
        console.log("beforeCreate!", this.msg);
        console.log(document.querySelector('h1'));
      },
      created() { 
        console.log("created!", this.msg); // 데이터 접근
        console.log(document.querySelector('h1')); // html 접근불가
      },
      beforeMount() {
        console.log("beforeMount!", this.msg);
        console.log(document.querySelector('h1'));
      },
      mounted() { // 돔과 연결된 이후
        console.log("mounted!", this.msg);
        console.log(document.querySelector('h1')); // html 접근가능
      }
			// vm 변경시
			// beforeUpdate() { // 화면 업데이트 전
      //   console.log("beforeUpdate!", this.msg);
      //   console.log(document.querySelector('h1').textContent);
      // },
      // updated() { 
      //   console.log("updated!", this.msg); 
      //   console.log(document.querySelector('h1').textContent); 
      // },
			// mount 해제시 app.unmout() 
			// beforeUnmount() { 
      //   console.log("beforeUnmount!");
      // },
      // unmounted() { 
      //   console.log("unmountd!"); 
      // },
	}

템플릿 문법

v-once

<h2 v-once>{{ msg }}</h2> 한번만 실행되며 이후 수정되지않음

v-html

<div v-html="rawHTML" ></div> v-html으로 HTML코드 넣을 수 있음. 하지만 XSS 가능성이 높기 때문에 출처 데이터가 불분명한 곳에서는 사용을 자제하거나, xss npm으로 XSS를 막아야 함

v-bind

<h1 v-bind:class="name">Hello Vue!</h1> html 속성부분에 데이터를 보간하여 넣을 수 있다.

<input type="text" value="Hello Vue!" v-bind:disabled="disabled" /> v-bind:disabled를 이용하여 bullan데이터(true, false, null, {} ...)를 통해 조작할 수도 있다.

v-bind의 약어

v-bind:는 그냥 :으로 줄일 수 있음

<a v-bind:href="url">...</a><a :href="url">...</a>

v-on의 약어

v-on:@으로 줄일 수 있음

<a v-on:click="doSomething">...</a><a @click="doSomething">...</a>

전달인자와 동적 전달인자

<a v-bind:href="url"> ... </a> :으로 표기되는 전달인자를 가짐

<a v-bind:[attributeName]="url"> ... </a> attributeName 값으로 동적으로 변환할 수 있는 전달인자를 가짐

<h1 v-bind:[attr]="'active'">Hello Vue!</h1> active를 데이터로 취급되지 않도록 active를 두번 감싸야 함

동적인자 값에 접근할 때는 반응형데이터라는 것을 명시적으로 나타내기 위해 vm.$data['count'] 같이 $data를 통해 접근하는 것이 권장된다. 원래 모든 값은 사실 $data을 해야하지만 Vue에서 this를 통해 생략하도록 만든것이다.

반응성을 유지하려면 데이터의 초기값이 없더라도 undefined 혹은 null로 값을 선언해놔야 한다.

Proxy()

const proxyA = new Proxy(app.data(), { // new Proxy(target, handler)
      get(target, key) { // 조회
        return target[key]
      },
      set(target, key, value) { // 지정
        target[key] = value * 2
      }
    }) // Proxy 생성자

computed

<div id="app">
    <h1>{{ count }}</h1>
    <h2>{{ double() }}</h2>
    <h2>{{ double() }}</h2>
</div>
  <script>
    
    const App = {
      data() { 
        return {
          count: 3
        }
      },
      methods: {
        double() {
          return this.count * 2
        }
      }
    }

<div id="app">
    <h1>{{ count }}</h1>
    <h2>{{ double }}</h2> // () 없음, 여러개의 함수 사용시 (); 혹은 (), 붙여줘야 함
    <h2>{{ double }}</h2>
</div>
  <script>
    
    const App = {
      data() { 
        return {
          count: 3
        }
      },
      computed: { // 캐싱을 통해 반복적으로 사용해도 연산은 한번만 진행
        double() {
          return this.count * 2
        }

compute와 set(), watch

<script>
    const App = {
      data() {
        return {
          // user: {
            firstName: 'Leon',
            lastName: 'Miller'
          // }
        }
      },
      computed: {
        fullName: {
          get() {
            return `${this.firstName} ${this.lastName}`
          },
          set(newValue) { 
            console.log(newValue);
            const names = newValue.split(' ')
            this.firstName = names[0]
            this.lastName = names[1]
          }
        }
      },
      watch: { // 데이터가 바뀌면 실행됨
        firstName(newValue, oldValue) { // firstName의 데이터가 바뀌면 실행됨
          console.log('watch:', newValue, oldValue);
        },
        fullName() {
          console.log('watch:', this.fullName);
        }
      }
    }

set()을 통해 객체나 배열 내의 데이터를 바꿀 수 있도록 만듦

handler의 deep, immediate

watch: {
        user: {
          handler(newValue, oldValue) { 
            console.log(newValue, oldValue);
          },
          deep: true,
					immediate: true
        }
      }

watch는 데이터가 바뀌는 값을 감지

handlerdeep 옵션으로 객체나 배열 내의 데이터를 감지할 수 있도록 해줌

immediate 옵션은 데이터가 변하지 않더라도 데이터가 준비되면 handler 실행

profile
병아리 프론트엔드 개발자🐣

0개의 댓글