hello-world 2019. 4. 4. 18:14
728x90
반응형

1. 컴포넌트

Vue.component('컴포넌트 이름', { } );

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

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.js"></script>
<script>
    Vue.component('mycomp', {
          template:`<div>mycomp 컴포넌트</div>`
     } );
    new Vue({
       el:'#app'
    });
</script>
</body>

상*하위 컴포넌트 관계

- 컴포넌트는 각각 고유한 유효범위를 갖고 있기 때문에 직접 다른 컴포넌트의 값을 참조할 수 없다.

따라서 뷰에서 정한 데이터 전달 방법을 따라야 한다.

 

기본적인 데이터 전달 방법 

1. 상위에서 > 하위로는 props 라는 속성으로 값을 전달.

<child v-bind:props 속성이름="상위 컴포넌트의 data속성"></child>

 

2. 뷰는 단방향 데이터 바인딩을 구현하기에 하위에서 > 상위로는 이벤트 버스를 이용하여 데이터를 전달한다.

this.$emit('이벤트명'); //이벤트 발생시킴.

<child v-on:이벤트명="상위 컴포넌트의 메서드명"></child> // v-on으로 이벤트 수신.

3. 관계 없는 컴포넌트 간 통신( 이벤트 버스)지정한 2개의 컴포넌트 간에 데이터를 주고 받을 수 있다.

//이벤트 버스 인스턴스 1개 생성.

var eventBus=new Vue();

 

//이벤트를 보내는 컴포넌트

methods:{

  메서드명:function(){

    eventBus.$emit('이벤트명', 데이터);

}

 

//이벤트를 받는 컴포넌트

methods:{

  created:function(){

   eventBus.$on('이벤트명', function(데이터){

    .......

  } 

 

- 클래스 / 스타일 바인딩

 

a.객체 구문

 

- 인라인 방식

- active, text-danger 클래스가 적용되려면 true가 할당되면 된다.

<div class="static"
  v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
data: {
  isActive: true,
  hasError: false
}

 

- 객체 대입 방식

<div v-bind:class="classObject"></div>
data: {
  classObject: {
    active: true,
    'text-danger': false
  }
}

 

- 객체 (함수리턴) 대입 방식

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject() {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

 

b.배열 구문

- errorClass는 항상 적용되고 isActive가 true 일 경우에만  active 적용. 

<div v-bind:class="[{ active: isActive }, errorClass]"></div>

 

 

2. 라우터 & HTTP

터미널에 아래와 같은 구문으로 라우터를 추가

- ( TypeScript 사용자는 vue-router@3.0+ vue@2.5+를 사용 )

npm install vue-router

 

설치한 라우터 사용( 라우터를 명시적 추가 및 선언 )

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)
const User = {
  template: '<div>User</div>'
}

const router = new VueRouter({
  routes: [
    // 동적 세그먼트는 콜론으로 시작합니다.
    { path: '/user/:id', component: User }
  ]
})

동적 세그먼트는 콜론 : 으로 표시한다.

라우트가 이리하면 동적 세그먼트의 값은 모든 컴포넌트에서 this.$route.params 로 표신된다.

const User = {
  template: '<div>User {{ $route.params.id }}</div>'
}

동일한 라우트에 여러 동적 세그먼트를 가질 수 있으며, $route.params의 해당 필드에 매핑된다.

/user/:username  --> /user/tom  --> { username:'tom'}

 

$route.params 외에도 $route 객체는 $route.query (URL에 쿼리가 있는 경우), $route.hash 등의 유용한 정보를 제공한다.

동일한 컴포넌트의 params 변경 사항에 반응하려면 $route 객체를 watch로 체크할 수 있다.

const User = {
  template: '...',
  watch: {
    '$route' (to, from) {
      // 경로 변경에 반응하여...
    }
  }
}

혹은 beforeRouteUpdate 가드를 사용 할 수 있다.

const User = {
  template: '...',
  beforeRouteUpdate (to, from, next) {
    // react to route changes...
    // don't forget to call next()
  }
}

라우터 가드

- 아래 befoeEnter는 각 라우트에 해당하는 개별 라우트 가드이다.

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Home,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

네비게이션이 트리거될 때마다 가드가 작성 순서에 따라 호출되기 전의 모든 경우에 발생한다.

가드는 비동기식으로 실행 될 수 있으며 네비게이션은 모든 훅이 해결되기 전까지 보류 중 으로 진행된다.

모든 가드 기능은 세 가지 전달인자를 받는다.

  • to: 라우트: 대상 Route객체로 이동

  • from: 라우트: 현재 라우트로 오기전 라우트

  • next: 함수: 이 함수는 훅을 해결하기 위해 호출 되어야 한다.

  • next(): 파이프라인의 다음 훅으로 이동. 훅이 없는 경우 네비게이션은 승인.

  • next(false): 현재 네비게이션을 중단. 브라우저 URL이 변경되면(사용자 또는 뒤로 버튼을 통해 수동으로 변경됨) from경로의 URL로 재설정된다.

  • next('/') 또는 next({ path: '/' }): 다른 위치로 리디렉션.

  • next(error): (2.4.0 이후 추가) next에 전달된 인자가 Error 의 인스턴스이면 탐색이 중단되고 router.onError()를 이용해 등록 된 콜백에 에러가 전달.

 

axios

vue-resource라고는 있지만 더이상 업데이트 되지 않고 있고 해결되지 않은 이슈도 많다고 해서

공식 홈페이지에선 axios를 더 추천함. 터미널에서 아래의 코드로 설치.

npm install --save axios

전역으로 사용하려면 Vue의 프로토타입에 추가해서 사용하면 된다.

import Vue from 'vue'
import App from './App'
import axios from 'axios'

Vue.prototype.$http=axios

new Vue({
  el:'#app',
  template:'<App />',
  components:{ App }
  })

Request Method

axios.request(config)

axios.get(url[, config])

axios.delete(url[, config])

axios.head(url[, config])

axios.options(url[, config])

axios.post(url[, data[, config]])

axios.put(url[, data[, config]])

axios.patch(url[, data[, config]])

 

기본 사용법

const axios = require('axios');

// Make a request for a user with a given ID
axios.get('/user?ID=12345')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .then(function () {
    // always executed
  });

// Optionally the request above could also be done as
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .then(function () {
    // always executed
  });  

// Want to use async/await? Add the `async` keyword to your outer function/method.
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

동시요청 수행

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));

axios API

// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

// GET request for remote image
axios({
  method:'get',
  url:'http://bit.ly/2mTM3nY',
  responseType:'stream'
})
  .then(function (response) {
    response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
  });

전역적 axios 지정

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

interceptors

-요청 또는 응답이 처리되거나 처리되기 전에 해당요청 또는 응답을 인터셉트 할 수 있다.

//요청에 대한 interceptor 추가
axios.interceptors.request.use(function (config) {
    // ~ 요청 전에 무언가 보낼 코드 부분 ~
    return config;
  }, function (error) {
     //에러 응답
    return Promise.reject(error);
  });

//응답에 대한 interceptor 추가
axios.interceptors.response.use(function (response) {
    // ~ 응답에 대한 무언가의 코드 부분 ~
    return response;
  }, function (error) {
    //에러 응답
    return Promise.reject(error);
  });

3. 뷰 템플릿

- 디렉티브

 

1. v-bind

<!-- 전체 문법 -->
<a v-bind:href="url"> ... </a>
<!-- 약어 -->
<a :href="url"> ... </a>

 

2. v-on

<!-- 전체 문법 -->
<a v-on:click="doSomething"> ... </a>
<!-- 약어 -->
<a @click="doSomething"> ... </a>

3. v-for

v-for 디렉티브를 사용하여 배열을 기반으로 리스트 렌더링.

형식 - item in items

items는 원본 데이터 배열

item은 반복되는 배열 엘리먼트의 별칭.

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>
var example2 = new Vue({
  el: '#example-2',
  data: {
    parentMessage: 'Parent',
    items: [
      { message: 'Foo' },
      { message: 'Bar' }
    ]
  }
})

키에 대한 두번째 전달 인자를 제공.

<div v-for="(value, key) in object">
  {{ key }}: {{ value }}
</div>

4. v-for에서 :key

( 2.2.0 이상에서 v-for key가 필수. )

Vue가 각 노드의 ID를 추적하고 기존 엘리먼트를 재사용하고 재정렬할 수 있도록

힌트를 제공하려면 각 항목에 고유한 key 속성을 제공. ( key에 대한 이상적인 값은 각 항목의 고유한 ID. )

<div v-for="item in items" :key="item.id">
  <!-- content -->
</div>

반복되는 DOM 내용이 단순하지 않거나 의도적인 성능 향상을 위해 기본 동작에 의존하지 않는한 가능하면

언제나 v-for에 key를 추가하는 것이 좋다. key는 Vue가 노드를 식별하는 일반적인 메커니즘이기 때문에 

v-for와 특별히 연관되지 않는 다른 용도로도 사용된다. 

 

- 데이터 바인딩

템플릿 문법 - {{ }}

 

4. 상태관리

Vuex.Store

import Vuex from 'vuex'

const store = new Vuex.Store({ ...options })

 

Vuex.Store 생성자 옵션

state

  • 자료형: Object | Function

    Vuex 저장소의 루트 상태 객체.

    오브젝트를 반환하는 함수를 전달하면, 반환된 오브젝트가 루트 상태로 사용.

    이것은 모듈 재사용을 위해 상태 객체를 재사용하고자 할 때 유용하다.

mutations

  • 자료형: { [type: string]: Function }

    저장소에 변이를 등록. 핸들러 함수는 항상 첫 번째 전달인자로 state를 받는다

    (모듈에 정의 된 경우 모듈 로컬 상태가 된다).  두 번째 payload 전달인자가 있으면 처리.

actions

- 자료형: { [type: string]: Function }

  • 저장소에 액션을 등록한다. 핸들러 함수는 다음 속성을 노출하는 context 객체를 받는다.
{
  state,      // store.state와 같습니다. 또는 모듈에 있는 경우 로컬 상태
  rootState,  // store.state와 같습니다. 모듈 안에만 존재합니다
  commit,     // store.commit와 같습니다.
  dispatch,   // store.dispatch와 같습니다.
  getters,    // store.getters와 같습니다. 또는 모듈에 있는 로컬 getters
  rootGetters // store.getters와 같습니다. 모듈 안에만 존재합니다
}

두 번째 payload 전달인자가 있으면 처리한다.

 

컴포넌트 바인딩 헬퍼 ( 반복적이고 복잡한 코드선언 입력을 간소화 시킨다 )

mapState(namespace?: string, map: Array<string> | Object<string | function>): Object

컴포넌트가 여러 저장소 상태 속성이나 getter를 사용해야하는 경우 계산된 속성을 모두 선언하면 반복적이고 장황해진다.

이를 처리하기 위해 계산된 getter 함수를 생성하는 mapState 헬퍼를 사용하여 키 입력을 줄일 수 있다.

 

첫번째 인자값에 namespace는 타입이 string으로써 ?로 기재된 즉, optional 파라미터 타입이기에 생략 혹은 호출할 수 있다.

두번째 인자값은 유니언타입( let c = a | b  즉 c는 a또는 b 이다. )으로써 Array 혹은 오브젝트이다. 

오브젝트 내부 속성들 타입도 유니언타입으로써 string 혹은 함수가 될 수 있다. 

 

mapMutations(namespace?: string, map: Array<string> | Object<string | function>): Object

변이를 커밋하는 컴포넌트 메소드 옵션을 만든다.

첫번째 인자값은 string 타입의 namespace가 될 수 있다. ( optional 파라미터 타입이기에 생략 혹은 호출할 수 있다. )

두번째 인자값은 유니언타입( let c = a | b  즉 c는 a또는 b 이다. )으로써 Array 혹은 오브젝트이다. 

오브젝트 내부 속성들 타입도 유니언타입으로써 string 혹은 함수[ function(commit: function, ...args: any[])  ]가 될 수 있다. 

 

 

 

5. 트랜지션

Vue는 트랜지션 래퍼 컴포넌트를 제공하므로 다음과 같은 상황에서 모든 엘리먼트 또는

컴포넌트에 대한 진입 / 진출 트랜지션을 추가 할 수 있다.

 

1. 조건부 렌더링 (v-if 사용)

2. 조건부 출력 (v-show 사용)

3. 동적 컴포넌트

4. 컴포넌트 루트 노드

 

 

트랜지션 클래스

 

진입 : v-enter-active( v-enter + v-enter-to )

진출 : v-leave-active( v-leave + v-leave-to )

 

* v-enter: enter의 시작 상태. 엘리먼트가 삽입되기 전에 적용되고 한 프레임 후에 제거.

* v-enter-active: enter에 대한 활성 및 종료 상태. 엘리먼트가 삽입되기 전에 적용. 트랜지션 / 애니메이션이 완료되면 제거.

* v-enter-to: 2.1.8 이상 버전에서 지원합니다. 진입 상태의 끝에서 실행. 엘리먼트가 삽입된 후 (동시에 v-leave가 제거됨), 트랜지션/애니메이션이 끝나면 제거되는 하나의 프레임을 추가.

* v-leave: leave를 위한 시작 상태. 진출 트랜지션이 트리거 될 때 적용되고 한 프레임 후에 제거

* v-leave-active: leave에 대한 활성 및 종료 상태. 진출 트랜지션이 트리거되면 적용되고 트랜지션 / 애니메이션이 완료되면 제거.

* v-leave-to: 2.1.8 이상 버전에서 지원합니다. 진출 상태의 끝에서 실행. 진출 트랜지션이 트리거되고 (동시에 v-leave가 제거됨), 트랜지션/애니메이션이 끝나면 제거되는 하나의 프레임을 추가.

 

 여기서 v-접두어는 이름없이 <transition> 엘리먼트를 사용할 때의 기본값이다.

예를 들어<transition name = "my-trans">을 사용하면v-enter 클래스는 my-trans-enter 가 됩니다.

v-enter-active 와v-leave-active 는 입/출력 트랜지션을 위한 다른 easing curve를 지정할 수있는 기능을 제공한다.

 

<div id="example-1">
  <button @click="show = !show">
    Toggle render
  </button>
  <transition name="slide-fade">
    <p v-if="show">hello</p>
  </transition>
</div>
new Vue({
  el: '#example-1',
  data: {
    show: true
  }
})
/* 애니메이션 진입 및 진출은 다른 지속 시간 및 */
/* 타이밍 기능을 사용할 수 있습니다. */
.slide-fade-enter-active {
  transition: all .3s ease;
}
.slide-fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter, .slide-fade-leave-to{
  transform: translateX(10px);
  opacity: 0;
}

 

 

참고: https://kr.vuejs.org/v2/guide/

 

시작하기 — Vue.js

Vue.js - 프로그레시브 자바스크립트 프레임워크

kr.vuejs.org

https://vuex.vuejs.org/kr/api/

 

API 레퍼런스 | Vuex

API 레퍼런스 Vuex.Store Vuex.Store 생성자 옵션 state 자료형: Object | Function Vuex 저장소의 루트 상태 객체 입니다. 상세 오브젝트를 반환하는 함수를 전달하면, 반환된 오브젝트가 루트 상태로 사용됩니다. 이것은 모듈 재사용을 위해 상태 객체를 재사용하고자 할 때 유용합니다. 상세 mutations 자료형: { [type: string]: Function } 저장소에 변이를 등록하십시오. 핸들러 함수는 항상 첫

vuex.vuejs.org

 

728x90
반응형