Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
public:computer:vuejs [2021/08/24 17:39] – alex | public:computer:vuejs [2023/01/03 09:57] (current) – [Install Vue.js] alex | ||
---|---|---|---|
Line 15: | Line 15: | ||
* Vue Devtool @chrome store | * Vue Devtool @chrome store | ||
* 가상 DOM | * 가상 DOM | ||
+ | |||
Vue.js 다운로드 | Vue.js 다운로드 | ||
Line 20: | Line 21: | ||
* https:// | * https:// | ||
</ | </ | ||
+ | |||
+ | * [[https:// | ||
+ | |||
+ | ==== Install Vue.js ==== | ||
+ | - Vue CLI 설치 <sxh bash> | ||
+ | $ npm install -g @vue/cli | ||
+ | # or | ||
+ | $ yarn global add @vue/cli | ||
+ | # or | ||
+ | $ yarn dlx @vue/clie | ||
+ | |||
+ | $ vue --version | ||
+ | $ npm list -g --depth=0 | ||
+ | </ | ||
+ | - Vue CLI 삭제 <sxh bash> | ||
+ | $ npm uninstall -g vue-cli | ||
+ | </ | ||
+ | - vue 프로젝트 생성 <sxh bash> | ||
+ | $ vue create < | ||
+ | |||
+ | $ cd < | ||
+ | $ npm run serve | ||
+ | </ | ||
+ | - vuetify 패키지 추가 <sxh bash> | ||
+ | $ vue add vuetify | ||
+ | </ | ||
+ | - vue-router 설치 <sxh bash> | ||
+ | $ vue add router | ||
+ | </ | ||
+ | - vuex 설치 <sxh bash> | ||
+ | $ vue add vuex | ||
+ | </ | ||
+ | - axios 설치 <sxh bash> | ||
+ | $ vue add axios | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Getting Started ==== | ||
< | < | ||
Line 149: | Line 188: | ||
* 문자열이나 숫자를 변환할 때는 필터를 권장 | * 문자열이나 숫자를 변환할 때는 필터를 권장 | ||
* 속성에는 사용 불가, 속성에 바인딩 하려면 v-bind 디렉티브 사용 | * 속성에는 사용 불가, 속성에 바인딩 하려면 v-bind 디렉티브 사용 | ||
- | * data 상태 json으로 출력; <pre> < | + | * data 상태 json으로 출력; <pre> < |
* this; 콜백으로 익명 함수를 사용하거나, | * this; 콜백으로 익명 함수를 사용하거나, | ||
* 클래스 이름에 하이픈을 넣을 때는 작은 따옴표(' | * 클래스 이름에 하이픈을 넣을 때는 작은 따옴표(' | ||
Line 349: | Line 388: | ||
+ | |||
+ | ===== Applications ===== | ||
+ | * Vuex; 상태 관리 전용 라이브러리, | ||
+ | * Vue Router; 라우팅 전용 라이브러리, | ||
+ | * Vue CLI; 애플리케이션 개발을 지원하기 위한 명령 라인 인터페이스 | ||
+ | * webpack 번들러; 모듈화한 여러 개의 파일을 모아 주는 번들러 https:// | ||
+ | * SFC(Single File Components); | ||
+ | * 다른 마크업 언어 또는 스타일시트 언어 사용; Pug, Sass 등 <alert type=" | ||
+ | * 공식 스타일 가이드; 파일, 사용자 정의 태그, 컴포넌트 이름 => 파스칼케이스(PascalCase) | ||
+ | |||
+ | ==== Node.js ==== | ||
+ | * https:// | ||
+ | * https:// | ||
+ | |||
+ | <alert type=" | ||
+ | npm install --save vue@2.6.14 | ||
+ | </ | ||
+ | |||
+ | ^ npm 기본 명령어 | ||
+ | ^ 명령어 | ||
+ | | npm install --global | ||
+ | | npm install --save | ||
+ | | npm install --save-dev | ||
+ | |||
+ | * Babel; ECMAScript 표준과 JSX 트랜스파일러 https:// | ||
+ | |||
+ | ==== Vue CLI ==== | ||
+ | * https:// | ||
+ | * Vue CLI 템플릿; https:// | ||
+ | |||
+ | <cli prompt=" | ||
+ | $ npm install -g vue-cli | ||
+ | |||
+ | $ vue --version | ||
+ | |||
+ | # 프로젝트 생성 명령어의 기본 형태 | ||
+ | $ vue init < | ||
+ | $ cd < | ||
+ | $ npm install | ||
+ | </ | ||
+ | |||
+ | <sxh bash; title: 새로운 프로젝트 만들기> | ||
+ | $ vue init webpack my-app | ||
+ | </ | ||
+ | |||
+ | * 프로젝트 루트; 폴더와 파일 구성 | ||
+ | * build 디렉토리; | ||
+ | * config 디렉토리; | ||
+ | * dist 디렉토리; | ||
+ | * **src 디렉토리**; | ||
+ | * **assets 디렉토리**; | ||
+ | * **components 디렉토리**; | ||
+ | * **router 디렉토리**; | ||
+ | * **App.vue 파일**; 애플리케이션 루트가 될 컴포넌트 | ||
+ | * **main.js 파일**; 엔트리 포인트 | ||
+ | * static 디렉토리; | ||
+ | * index.html 파일; SPA의 인덱스가 되는 HTML 템플릿 | ||
+ | |||
+ | <cli prompt=" | ||
+ | $ npm run dev # 개발 서버 실행 | ||
+ | |||
+ | $ npm run build # 프로젝트 빌드 | ||
+ | </ | ||
+ | |||
+ | ==== Vue.js 플러그인 ==== | ||
+ | <sxh javascript; title: 플러그인 등록 예제> | ||
+ | // Vue와 Vuex 모듈 읽어 들이기 | ||
+ | import Vue from ' | ||
+ | import Vuex from ' | ||
+ | |||
+ | // Vue에 Vuex 등록하기 | ||
+ | Vue.use(Vuex) | ||
+ | </ | ||
+ | |||
+ | ===== Vuex ===== | ||
+ | * Vuex; 상태 관리를 위한 확장 라이브러리 | ||
+ | * 여러개의 컴포넌트가 데이터 공유 | ||
+ | * 데이터 상태와 관련된 처리를 공통화 | ||
+ | * 큰 상태 관리도 모듈을 사용해 간단하게 분리 | ||
+ | * https:// | ||
+ | * Vuex는 ES2015의 Promise를 사용하므로, | ||
+ | |||
+ | <cli prompt=" | ||
+ | # 최신 버전 설치 | ||
+ | $ npm install vuex babel-polyfill | ||
+ | |||
+ | # 버전 지정 | ||
+ | $ npm install vuex@3.1.0 babel-polyfill@6.26. | ||
+ | </ | ||
+ | |||
+ | <sxh javascrip; title: vuex를 사용하기 전에 폴리필 import> | ||
+ | import ' | ||
+ | import Vue from ' | ||
+ | import Vuex from ' | ||
+ | |||
+ | // 플러그인으로 등록 | ||
+ | Vue.use(Vuex) | ||
+ | </ | ||
+ | |||
+ | * 스토어; Vuex 상태 관리를 위한 저장소 | ||
+ | |||
+ | <sxh javascript; title: 스토어 만들기> | ||
+ | // 스토어 만들기 | ||
+ | const store = new Vuex.store({ | ||
+ | state: { | ||
+ | count: 0 | ||
+ | }, | ||
+ | mutations: { | ||
+ | // 카운트 업하는 뮤테이션 등록, 매개변수로 전달 | ||
+ | increment(state) { | ||
+ | state.count++ | ||
+ | } | ||
+ | // increment: state => { state.count++ } // 위와 같은 동작을 하는 코드 | ||
+ | } | ||
+ | }) | ||
+ | |||
+ | export default store | ||
+ | </ | ||
+ | |||
+ | <sxh javascript; title: 스토어의 상태에 접근> | ||
+ | import store from ' | ||
+ | console.log(store.state.count) | ||
+ | |||
+ | // 스토어의 상태 변경 | ||
+ | // increment 커밋 | ||
+ | store.commit(' | ||
+ | // 값이 변경된 것을 확인 | ||
+ | console.log(store.state.count) | ||
+ | </ | ||
+ | |||
+ | <sxh javascript; title: src/main.js 스토어를 애플리케이션에 등록> | ||
+ | import store from ' | ||
+ | |||
+ | new Vue({ | ||
+ | el: '# | ||
+ | store, | ||
+ | render: h => h(App) | ||
+ | }) | ||
+ | </ | ||
+ | |||
+ | <sxh javascript; title: 컴포넌트에서 스토어 사용> | ||
+ | export default { | ||
+ | created() { | ||
+ | // 스토어의 상태 확인 | ||
+ | console.log(this.$store.state.count) | ||
+ | // 스토어의 상태 변경 | ||
+ | this.$store.commit(' | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | * 컴포넌트에서 스테이트를 변경하고 싶으면 액션과 뮤테이션을 거쳐야 한다. | ||
+ | * 스테이트(state); | ||
+ | * 게터(getter); | ||
+ | * 뮤테이션; | ||
+ | * state, payload 커밋에서 전달된 매개변수를 받음. 호출을 위해 타입과 핸들러 개념 사용. | ||
+ | * 커밋(commit); | ||
+ | * 액션(action); | ||
+ | * 디스패치(dispatch); | ||
+ | * Vuex의 규칙 | ||
+ | * 애플리케이션 레벨의 상태는 스토어로 관리 | ||
+ | * 상태를 변경하는 것은 뮤테이션 내부에서만 수행 | ||
+ | * 비동기 처리는 커밋하기 전에 완료 | ||
+ | * 컴포넌트에서 스토어 사용 | ||
+ | * 메시지 사용 | ||
+ | * 메시지 변경 | ||
+ | * 상태와 게터에 v-model 사용 | ||
+ | * 컴포넌트와 스토어를 바인드하는 헬퍼 | ||
+ | * 스토어 분할 | ||
+ | * 이름 공간 | ||
+ | * 헬퍼에 이름 공간 지정 | ||
+ | * 모듈 네스트 | ||
+ | * 이름 공간이 있는 모듈에서 외부에 접근 | ||
+ | * 모듈을 파일별로 분할 | ||
+ | * 모듈 재사용 | ||
+ | * 이외의 기능과 옵션 | ||
+ | * 스토어의 상태 감시 | ||
+ | * strict 모드로 개발 | ||
+ | * vuex에서 핫리로딩 사용 | ||
+ | |||
+ | |||
+ | |||
+ | ===== Vue Router로 SPA 만들기 ===== | ||
+ | * Vue Router; 단일 페이지 어플리케이션 구축하기 위한 Vue.js 확장 라이브러리. 컴포넌트와 URL을 연결해 주는 기능. | ||
+ | * SPA(Single-page Application); | ||
+ | * https:// | ||
+ | |||
+ | Vue Router 설치 | ||
+ | <cli prompt=" | ||
+ | $ npm install vue-router | ||
+ | |||
+ | $ npm install vue-router@3.0.6 | ||
+ | </ | ||
+ | |||
+ | <sxh javascript; title: src/ | ||
+ | import Vue from ' | ||
+ | import VueRouter from ' | ||
+ | |||
+ | // 플러그인으로 등록 | ||
+ | Vue.use(VueRouter) | ||
+ | </ | ||
+ | |||
+ | ^ Vue Router 내장 컴포넌트 | ||
+ | ^ 사용자 정의 태그 | ||
+ | | < | ||
+ | | < | ||
+ | |||
+ | < | ||
+ | <col sm=" | ||
+ | <sxh javascript; title: src/ | ||
+ | import Vue from ' | ||
+ | import VueRouter from ' | ||
+ | |||
+ | // 라우트 전용 컴포넌트 읽어 들이기 | ||
+ | import Home from ' | ||
+ | import Product from ' | ||
+ | |||
+ | // Vuex와 마찬가지로 플러그인 등록 | ||
+ | Vue.use(VueRouter) | ||
+ | |||
+ | // VueRouter 인스턴스 생성 | ||
+ | const router = new VueRouter({ | ||
+ | // URL의 경로와 연결할 컴포넌트 맵핑하기 | ||
+ | routes: [ | ||
+ | { path: '/', | ||
+ | { path: '/ | ||
+ | ] | ||
+ | }) | ||
+ | |||
+ | // 생성한 VueRouter 인스턴스 익스포트 | ||
+ | export default router | ||
+ | </ | ||
+ | </ | ||
+ | <col sm=" | ||
+ | <sxh javascript; title: src/ | ||
+ | import router from ' | ||
+ | |||
+ | new Vue({ | ||
+ | el: '# | ||
+ | router, | ||
+ | render: h => h(App) | ||
+ | }) | ||
+ | </ | ||
+ | |||
+ | <sxh html; title: src/ | ||
+ | < | ||
+ | <div id=" | ||
+ | <nav> | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | <!-- 여기에 경로에 일치하는 컴포넌트가 들어감 --> | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | * 해시(Hash), | ||
+ | * URL에 해시 붙이지 않기 | ||
+ | * 아파치 서버; mod_rewrite 설정 추가 | ||
+ | * 라우터 전용 속성; $router, $route | ||
+ | * 라우터 정의와 옵션 | ||
+ | * 이름 있는 라우터 | ||
+ | * 요청 매개 변수 | ||
+ | * 쿼리 | ||
+ | * 메타 필드 | ||
+ | * 리다이렉트 | ||
+ | * 네비게이션 | ||
+ | * 템플릿으로 내비게이션 | ||
+ | * 프로그램으로 내비게이션 | ||
+ | |||
+ | ^ 객체 형식으로 지정 | ||
+ | ^ 객체 | ||
+ | | name | 라우트 이름 | ||
+ | | path | 라우트 경로 | ||
+ | | params | ||
+ | | query | 쿼리 객체 | ||
+ | |||
+ | ^ 액티브 링크 하이라이트 | ||
+ | ^ 클래스 | ||
+ | | .router-link-exact-active | ||
+ | | .router-link-active | ||
+ | |||
+ | ^ 프로그램으로 내비게이션 | ||
+ | ^ 메서드 | ||
+ | | push | 이력 엔트리 추가 | ||
+ | | replace | ||
+ | | go | 브라우저 레벨에서 페이지 이동 | ||
+ | |||
+ | * 매개 변수가 있는 동적 라우트 | ||
+ | * 패턴 매치 라우팅 | ||
+ | * 매개 변수를 props로 컴포넌트에 전달 | ||
+ | * 콘텐츠 출력; 상품 목록 출력, 상품정보 출력 | ||
+ | * 네스트되어 있는 복잡한 페이지 | ||
+ | * 네스트된 라우트 정의 | ||
+ | * 데이터 공유에는 Vuex 사용 | ||
+ | * 부모 라우트 전용 컴포넌트 정의; 매개변수를 가진 링크를 만들 때는 이름 있는 라우트 사용, 네스트 때의 URL | ||
+ | * 내비게이션 가드 | ||
+ | * 내비게이션 가드의 매개변수; | ||
+ | * 라우트 단위 가드 | ||
+ | * 전역가드 | ||
+ | * 컴포넌트 가드 | ||
+ | |||
+ | ^ 내비게이션 가드의 매개변수 | ||
+ | ^ 매개 변수 | ||
+ | | to | 이동 후의 라우트 객체 | ||
+ | | from | 이동 전의 라우트 객체 | ||
+ | | next | 내비게이션 해결 전용 콜백 함수 | ||
+ | |||
+ | ^ 라우트 단위 가드 | ||
+ | ^ 메서드 이름 | ||
+ | | beforeEnter | ||
+ | |||
+ | ^ 전역 가드 | ||
+ | ^ 메서드 이름 | ||
+ | | beforeEach | ||
+ | | beforeResolve | ||
+ | | afterEach | ||
+ | |||
+ | ^ 컴포넌트 가드 | ||
+ | ^ 메서드 이름 | ||
+ | | beforeRoutEnter | ||
+ | | beforeRouteUpdate | ||
+ | | beforeRouteLeave | ||
+ | |||
+ | * 내비게이션 해결 흐름 | ||
+ | - 내비게이션이 트리거됨 | ||
+ | - 비액티브화된 컴포넌트에서 leave 가드를 호출 | ||
+ | - 전역 beforeEach 가드를 호출 | ||
+ | - 재사용되는 컴포넌트에서 beforeRouteUpdate 가드를 호출 | ||
+ | - 라우트 설정 내부의 beforeEnter를 호출 | ||
+ | - 비동기 라우트 컴포넌트를 해결 | ||
+ | - 액티브화된 컴포넌트에서 beforeRouteUpdate를 호출 | ||
+ | - 전역 beforeResolve 가드를 호출 | ||
+ | - 내비게이션이 확정 | ||
+ | - 전역 afterEach 훅을 호출 | ||
+ | - DOM 변경이 트리거 됨 | ||
+ | - beforeRouteEnter의 next로 전달된 콜백 호출 | ||
+ | |||
+ | * 페이지 이동 효과 적용 | ||
+ | * 간단한 트랜지션 | ||
+ | * 비동기 처리를 포함한 트랜지션 | ||
+ | * 자주 사용하는 기능과 옵션 | ||
+ | * 이동 전에 컴포넌트 읽어 들이기 | ||
+ | * 비동기로 컴포넌트 읽어 들이기 | ||
+ | * 라우트 접근 제한 | ||
+ | * 스크롤 동작 조작 | ||
+ | |||
+ | |||
+ | ===== 컴포넌트 데이터 전달 ===== | ||
+ | |||
+ | ==== Props 속성을 이용한 Parent to Child 컴포넌트 데이터 전달 ==== | ||
+ | > Parent는 v-bind, Child는 props를 이용 | ||
+ | |||
+ | < | ||
+ | <col sm=" | ||
+ | <sxh javascript title: parent-component.vue; | ||
+ | < | ||
+ | <div> 하위 컴포넌트에 데이터 값을 알려줍니다. | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | import ChildComponent from " | ||
+ | |||
+ | export default { | ||
+ | name: " | ||
+ | components: { ChildComponent }, | ||
+ | data: function () { | ||
+ | return { | ||
+ | parentVaule: | ||
+ | }; | ||
+ | }, | ||
+ | }; | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | <col sm=" | ||
+ | <sxh javascript title: child-component.vue; | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | export default { | ||
+ | name: " | ||
+ | props: [" | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Child to Parent 컴포넌트 데이터 전달 ==== | ||
+ | > Child에서 $emit, Parent에서 v-on을 이용 | ||
+ | |||
+ | < | ||
+ | <col sm=" | ||
+ | <sxh javascript title: child-component.vue; | ||
+ | < | ||
+ | <button @click=" | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | export default { | ||
+ | name: " | ||
+ | methods: { | ||
+ | updateParentValue() { | ||
+ | this.$emit(" | ||
+ | }, | ||
+ | }, | ||
+ | }; | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | <col sm=" | ||
+ | <sxh javascript title: parent-component.vue; | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | import ChildComponent from " | ||
+ | |||
+ | export default { | ||
+ | name: " | ||
+ | components: { ChildComponent }, | ||
+ | data: function () { | ||
+ | return { | ||
+ | parentVaule: | ||
+ | }; | ||
+ | }, | ||
+ | methods: { | ||
+ | updateParentValue() { | ||
+ | this.parentVaule++; | ||
+ | console.log(this.parentVaule) // 21, 22, 22, 누를때마다 증가하는 것 확인 가능 | ||
+ | }, | ||
+ | }, | ||
+ | }; | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== 기타(Sibling, | ||
+ | > EventBus를 이용, Vuex 이용. | ||
+ | |||
+ | < | ||
+ | <col sm=" | ||
+ | </ | ||
+ | <col sm=" | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | * [[https:// | ||
===== References ===== | ===== References ===== | ||
+ | |||
+ | * SSR를 사용한 고속 초기 렌더링, OGP 대응 | ||
+ | * PWA를 사용한 애플리케이션 형태의 스마트폰 사이트 | ||
+ | * Electron을 사용한 데스크톱 애플리케이션 | ||
+ | * NativeScript를 사용한 스마트폰 애플리케이션 | ||
+ | |||
* [[https:// | * [[https:// | ||
* [[https:// | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[http:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | * [[https:// | ||
+ | |||
+ | |||