Vue.js 입문 코스

태그: ,

카테고리:


출처 VueMastery.com

🚫 아래의 내용은 사실과 다를 수 있다
코스의 내용 또한 임의로 생략하거나 순서를 바꾼 부분이 있다


2. 뷰 앱 생성

학습용 뷰 라이브러리 한줄 추가로 필요한 임포트가 끝난다
index.html

<script src="https://unpkg.com/vue@next"></script>

앱은 아래와 같은 방식으로 선언되는데

const app = Vue.createApp({Options object})

Options object는 옵션이 아니다 빈 오브젝트({})라도 넘겨줘야 작동을 한다

앱을 js 파일에 선언한다
main.js

const app = Vue.createApp({
  data() {
    return {
      product: 'Socks',
      image: './assets/images/socks_green.jpg',
      stock: 55,
      cart: 0,
      ...
    }
  },
  methods: {
    addToCart() {
      this.cart += 1
    },
    ...
  },
  computed: {	// 기본적으로 method와 같으나 결과가 캐싱됨
    title() {
      return this.brand + ' ' + this.product
    },
    ...
  }
})

선언한 앱의 사용은 마운트를 통해 이루어진다
index.html

<body>
	<div id="app">
		<h1></h1>
	</div>

	<!-- Import Js -->
	<script src="./main.js"></script>

	<!-- Mount App -->
	<script>
		const mountedApp = app.mount('#app')
	</script>
</body>

마운트가 되면 자바스크립트 표현식()으로 내부 변수들에 접근이 가능해진다

자바스크립트 표현식이기 때문에
main.js

&#123;&#123; product &#125;&#125;                      // 변수
&#123;&#123; firstName + ' ' + lastName &#125;&#125;   // 산술
&#123;&#123; clicked ? true : false &#125;&#125;       // 삼항
&#123;&#123; message.method() &#125;&#125;             // 함수

등과 같은 처리도 가능하다

뷰는 값이 변하면 동적으로 반응한다(바로 바꾸고 적용함)


3. 속성연결 v-bind

v-bind는 태그 속성에 입력한 문자열을 표현식으로 인식할 수 있게 도와준다
:src=”image” == :src=
v-bind로 src 속성에 경로를 변수로 전달해보자
index.html

<div id="app">
  ...
    <img v-bind:src="image" alt="">
  ...
</div>

v-bind는 class나 style도 적용 가능하고 생략도 가능하다

<div :class="[isActive ? activeClass(함수) : '']">
<div :style="{ backgroundColor: variant.color }"> camelCased
<div :style="{ 'background-color': variant.color }"> 'kebab-cased'
<div :style="variantStyle"> 변수에 담기
<img :disabled="stock <= 0">
<img v-bind:src="image" alt="">
== <img :src="image" alt="">

4. 조건부 출력 v-if

v-if와 v-else로 간단하게 조건문을 사용할 수 있다

index.html

<p v-if="stock > 10">In Stock</p>
<p v-else-if="stock > 0">Almost sold out!</p>
<p v-else>Out of Stock</p>

v-show는 조건문이 거짓일 때,
style=”display: none;”을 추가한다

<p v-show="stock > 0">In Stock</p>

5. v-for Iterator

아래와 같은 순환 가능한 형태의 변수는 main.js

variants: [
  { id: 2234, color: 'green', ...},
  { id: 2235, color: 'blue', ...},
]

v-for로 순환하며 출력이 가능하다
index.html

<ul>
  <li v-for="variant in variants">
     
  </li>
</ul>

또한 v-bind:key=”variant.id”와 같은 방식으로 식별키를 지정할 수도 있다


6. v-on 이벤트 리스너

v-on:이벤트 수신방식="이벤트 발생시 실행할 표현식"

click 이벤트 예시는 다음과 같다 index.html

<button class="button" v-on:click="addToCart">Add to Cart</button>

또한 v-on은 @로도 표현 가능하다

<button v-on:click="addToCart"></button>
 == <button @click="addToCart"></button>

click 외에도 가능하다

ex) <div @mouseover="updateImage(variant.image)">

9. Components & Props

컴포넌트를 사용하면 코드의 재사용성을 크게 높일수 있다

컴포넌트의 이름은 임포트 후에 태그로 사용하므로 작명에 신경쓰자

<!-- Import Component -->
<script src="./components/ProductDisplay.js"></script>
...
<product-display :premium="premium"></product-display>
<!-- product-display props = premium -->

해당 컴포넌트보다 더 넓은 스코프에서 쓰이는 변수와 같은 항목들은
props로 지정해서 컴포넌트의 생성자 파라미터처럼 받아올 수 있다

이제 재사용할 부분들을 추출해서 컴포넌트를 만들어보자

ProductDisplay.js

app.component('product-display', { // <- 컴포넌트 이름
  props: {
    premium: {
      type: Boolean,
      required: true
    }
  },
  template:
  /*html*/		// <- ms code에서 이렇게 명시하면 보기 편하다
  `<div class="product-display">
    <div class="product-container">
      <div class="product-image">
        <img v-bind:src="image">
      </div>
      <div class="product-info">
        <h1></h1>

        <p v-if="inStock">In Stock</p>
        <p v-else>Out of Stock</p>

        <p>Shipping: </p>
        <ul>
          <li v-for="detail in details"></li>
        </ul>

        <div 
          v-for="(variant, index) in variants" 
          :key="variant.id" 
          @mouseover="updateVariant(index)" 
          class="color-circle" 
          :style="{ backgroundColor: variant.color }">
        </div>
        
        <button 
          class="button" 
          :class="{ disabledButton: !inStock }" 
          :disabled="!inStock" 
          v-on:click="addToCart">
          Add to Cart
        </button>

      </div>
    </div>
  </div>`,
  data() {
    return {
      product: 'Socks',
      brand: 'Vue Mastery',
      selectedVariant: 0,
      details: ['50% cotton', '30% wool', '20% polyester'],
      variants: [
        { id: 2234, color: 'green', image: './assets/images/socks_green.jpg', quantity: 50 },
        { id: 2235, color: 'blue', image: './assets/images/socks_blue.jpg', quantity: 0 },
      ]
    }
  },
  methods: {
    addToCart() {
        this.$emit('add-to-cart', this.variants[this.selectedVariant].id)
    },
    updateVariant(index) {
        this.selectedVariant = index
    }
  },
  computed: {
    title() {
      return this.brand + ' ' + this.product
    },
    image() {
      return this.variants[this.selectedVariant].image
    },
    inStock() {
      return this.variants[this.selectedVariant].quantity
    },
    shipping() {
      if (this.premium) {
        return 'Free'
      }
      return 2.99
    }
  }
})

이제 복붙이 가능하다

<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>
<product-display :premium="premium"></product-display>

10. Emit

컴포넌트 내부에서 발생한 이벤트를 외부로 방출하는 방식을 설명한다

아래와 같이 컴포넌트에서 방출 받을 내용을
@이름=”실행할 표현식” 형식으로 미리 지정해주고 index.html

<product-display :premium="premium" @add-to-cart="updateCart"></product-display>
<!-- main.js에 updateCart(id) 메소드가 있다 -->

컴포넌트에서는
this.$emit(지정했던 이름, 함수 파라미터) 형식으로 지정하면 된다 ProductDisplay.js

...
methods: {
  addToCart() {
    this.$emit('add-to-cart', this.variants[this.selectedVariant].id)
  },
...

12. Forms & v-model

form에 v-model 속성을 이용, 양방향 연결을 적용해보자

form 내부의 값들에 v-model 속성을 추가하고,
그 값들을 data() 내부의 연결할 값들로 지정해준다

<form ... @submit.prevent="onSubmit">

이것은 submit 버튼이 눌려도 onSubmit 함수가 실행될 때는
화면이 새로고침 되는것을 방지하라는 내용이다

ReviewForm.js

app.component('review-form', {
  template:
    /*html*/
    `
    <form class="review-form" @submit.prevent="onSubmit">
      <h3>Leave a review</h3>
      <label for="name">Name:</label>
      <input id="name" v-model="name">
    
      <label for="review">Review:</label>      
      <textarea id="review" v-model="text"></textarea>
      <label for="rating">Rating:</label>
      <select id="rating" v-model.number="rating">
        <option>5</option>
        <option>4</option>
        <option>3</option>
        <option>2</option>
        <option>1</option>
      </select>
  
      <input class="button" type="submit" value="Submit">  
    
    </form>
  `,
  data() {
    return {
      name: '',
      text: '',
      rating: null
    }
  },
  methods: {
    onSubmit() {
      if (this.name === '' || this.text === '' || this.rating === null) {
        alert('Review is incomplete. Please fill out every field.')
        return
      }

      const review = {
        name: this.name,
        text: this.text,
        rating: this.rating
      }
      this.$emit('review-submitted', review)
      this.name = ''
      this.text = ''
      this.rating = null
    }
  }
})

코스가 끝났다
3시간 배워서 깊이 있는 기술을 구현하기에는 부족하겠지만
이것들만 응용해도 충분히 많은것들이 가능할 것 같다
당장의 가성비에는 이 정도가 적당한듯 하다

태그: ,

카테고리:

업데이트:

댓글남기기