📃 요약
Html 1 페이지로 웹 사이트를 개발하는 라이브러리임, SPA(Single Page Application)이라고 함, html첫페이지에서 변경되는 부분만 .js 소스(컴포넌트)로 불여서 개발하는 방식이 흡사 레고블럭을 연결해서 하나의 완성본을 만드는 것과 같다고 해서 컴포넌트 개발이라고도 함, 과거 코딩방식보다 일부 변경된 부분만 바꾸어 끼우는 방식이라서 성능이 비약적으로 증가함, 현대 프론트 코딩방식은 SPA 개발로 바뀌고 있으며 비슷한 계열로 React / Angular 가 있음
요소 기술 :
– Basic : Vue
📃 기술 구현
스펙 :
- vscode - js (es6) - vue
📃 Vue
- 컴포넌트 프로그래밍 : 페이지를 컴포넌트로 분리해서 레고 블럭처럼 조립해서 코딩하는 방식을 채택함, Vue, React 등이 적용하고 있음 - Vue 프레임워크라고 하고, 필수 라이브러리들이 대체로 설치되어 있고 제어문/반복문이 쉬워 초보자가 접근하기 쉬움 - 리액트는 라이브러리라고 하며 필수 라이브러리들을 추가적으로 설치해야 하고 제어문/반복문이 모던js 를 기반으로 다양하게 사용되기때문에 배워야 하는 기술이 많아 초보자가 접근하기에는 어려운 측면이 있음
1) Vue 사용법 : cdn 사용법과 vue-cli 를 이용한 사용법 2가지가 있음
아래는 vue cdn 사용법으로 초급자가 이해를 위한 예제임, 프로젝트는 vue-cli 툴을 이용함
– hello.vue : cdn 사용법
예) <html> <head> <title>Vue Instance Lifecycle</title> </head> <body> <div id="app"> <!-- vue 콧수염 표기법 --> {{ message }} </div> <!-- vue cdn --> <script src="https://cdn.jsdelivr.net/npm/vue@2.5.2/dist/vue.js"></script> <script> // vue 생성 new Vue({ el: "#app", // vue 영역 data: { message: "Hello Vue.js!", // vue 데이터 바인딩 변수 }, }); </script> </body> </html>
– vue-cli :
주로 개발은 vue-cli 를 이용해 개발이 이루어짐 아래 예제들은 vue-cli 기반으로 설명함
vue-cli 설치 : 컴퓨터에 1번만 설치하면 됨
사용법 : npm install -g @vue/cli
프로젝트 만들기
사용법 : vue create 프로젝트명
프로젝트 실행
사용법 : npm run serve
- 프로젝트 종료 ```bash 사용법 : ctrl + c (키보드 타이핑 2번)
- node_modules : 뷰 설치파일이 있는곳 , 사이즈가 큼
1) 사이즈가 큼
2) 주로 다른 팀원에게 뷰 소스를 줄때 삭제후 전달하고, 팀원이 인터넷에서 다사 설치파일을 내려받아 재생성함
3) 재생성 명령어 : npm install사용법 : npm install
2) MVVM :
모델(데이터), 뷰(화면), 뷰모델(데이터/화면 중간역할)을 각각 분리하여 역할 별로 코딩하는 기법, 주로 데이터바인딩기술을 이용함
– 데이터 바인딩 기술 : 뷰모델에서 데이터와 뷰가 서로 변경될때 자동으로 갱신될 수 있게 연결하는 기술
1. 모델의 값이 변경되면 자동으로 화면이 갱신됨 2. 화면의 값이 변경되면 자동으로 모델(데이터)이 갱신됨 3. 장점 : 코딩 효율성 향상 , js DOM 접근함수가 필요없음(querySelector, $() 등) 4. 뷰(vue)에서는 {{}} 표기법, v-bind, v-on 지시자를 이용해서 데이터 바인딩을 함
0) 바인딩 기술 : 콧수염 표기법 : {{}}
1. 뷰(vue)에서는 {{}} 표기법 2. 콧수염 표기법 사용 : js 자료형 모두 사용가능하고, 간단한 산술연산, 함수 사용도 가능, 3항 연산자 가능 3. 콧수염 표기법 사용 불가 : if 조건문/for 반복문 사용 불가
<template> <div class="home"> <!-- {/* 주석 : ctrl + / */} --> <!-- {/* 1) 문자열 출력 : O */} --> <!-- {/* 사용법 : {"문자열"} */} --> {{ "문자열 출력되나요!!!" }} <br /> <!-- {/* 2) 숫자 출력 : O */} --> {{ 1 * 2 + 3 - 2 }} <br /> <!-- {/* 3) 문자열 붙이기 : + */} --> {{ "abc" + "가나다" }} <br /> </div> </template> <script> // @ is an alias to /src export default { }; </script>
1) 컴포넌트 프로그래밍
- 컴포넌트 : 독립적으로 실행되는 코드 - 여러개의 컴포넌트들을 조립해서 한개의 페이지를 만드는것을 컴포넌트 프로그래밍이라고 하고 프론트엔드에서는 대표적으로 vue, react, angular 가 있음 - 마치 레고블럭들을 조립해서 한개의 작품을 만드는 것과 같음 - vue 1개가 1개의 컴포넌트를 의미하고 vue 코드 안에 자식컴포넌트 끼워넣기가 가능 - 장점 : 1) 코딩 생산성 향상 : 코드 수정시 일부만 찾아서 수정하면 되어서 코딩 생산성이 증대됨 - 2) 유지 보수성 증대 : 최초 개발되고 이후에 기능 추가/수정이 일어날때 해당 컴포넌트만 찾아서 수정하면 되니 유지보수하기가 쉬움
App.vue
- 사용법 : <template> <div id="app"> <자식컴포넌트 /> <router-view/> </div> </template> <script> import 자식컴포넌트 from "@/components/자식컴포넌트.vue"; export default { components: { 자식컴포넌트, } } </script> 예) <template> <div id="app"> <HeaderCom /> <router-view/> </div> </template> <script> import HeaderCom from "@/components/B_HeaderCom.vue"; export default { components: { HeaderCom, } } </script> <style lang="scss"> </style>
HeaderCom.vue
- 사용법 : <template> <div> 실행문 </div> </template> <script> export default { } </script> 예) <template> <div> 머리말 입니다. </div> </template> <script> export default { } </script> <style lang=""> </style>
2) 라우트(Router) :
- 프로젝트에서는 페이지 이동을 위한 메뉴들이 있음, 뷰(Vue)에서는 라우트라고 메뉴의 url 을 정의하는 기능이 있음 - 뷰(Vue) 에서는 메뉴를 클릭하면 이동할 페이지 대신 실행될 컴포넌트를 정의함 - 페이지 이동은 router-link 태그를 사용함 : 부분 새로고침이 가능 - a 태그는 전체 새로고침이 일어나서 페이지내 큰 이미지가 있으면 화면 로딩 속도가 저하됨
Router/index.js
- 사용법 : import Vue from 'vue' import VueRouter from 'vue-router' // 메뉴에 정의할 자식 컴포넌트 import import 컴포넌트 from '../views/컴포넌트.vue' Vue.use(VueRouter) const routes = [ // 뷰가 생성될때 컴포넌트가 생성됨 { path: '/url', name: '라우터명', component: 컴포넌트 }, // 메뉴 스플리팅 기능 : 클릭시 컴포넌트가 생성됨 : 초기 화면 로딩 속도 향상 { path: '/url2', name: '라우터명2', // import 함수를 이용해서 정의 component: () => import('../views/컴포넌트2.vue') } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router 예) import Vue from 'vue' import VueRouter from 'vue-router' import A_HomeView from '../views/A_HomeView.vue' Vue.use(VueRouter) const routes = [ { path: '/', name: 'home', component: A_HomeView }, { path: '/binding', name: 'binding', component: () => import('../views/C_BindingView.vue') } ] const router = new VueRouter({ mode: 'history', base: process.env.BASE_URL, routes }) export default router
App.vue
- 사용법 : <template> <div id="app"> <nav> <!-- vue 전용 페이지 이동 태그 : router-link --> <!-- 사용법 : <router-link to="/url">메뉴</router-link> --> <router-link to="/url">메뉴</router-link> | <router-link to="/url2">메뉴2</router-link> | </nav> <!-- 메뉴를 클릭하면 컴포넌트의 내용이 router-view 위치에 보임 --> <router-view/> </div> </template> <script> export default { } </script> <style lang="scss"> </style> 예) <template> <div id="app"> <HeaderCom /> <nav> <router-link to="/">Home</router-link> | <router-link to="/binding">BindingView</router-link> | </nav> <!-- 메뉴를 클릭하면 컴포넌트의 내용이 router-view 위치에 보임 --> <router-view/> <FooterCom /> </div> </template> <script> export default { } </script> <style lang="scss"> </style>
3) {{}} : 콧수염 표현식
- 화면의 특정 위치와 데이터 바인딩을 하는 vue 의 표현식 (콧수염 표현식) - {{}} 안에 들어갈 수 있는 것 : 문자열(“”), 숫자, 배열, 자바스크립트함수, 간단한 수학 계산, 문자열 붙이기, 3항 연산자 등이 들어갈 수 있음
BindingView.vue
- 사용법 : {{변수명}} // 변수의 값이 화면에 표시됨a <template> {{변수명}} </template> <script> export default { data() { return { 변수명: "값", }; }, }; </script> 예) <template> <div> <h3>데이터 바인딩1(기본)</h3> <span>{{ message }}</span> <br /> </div> </template> <script> export default { data() { return { message: "바인딩 테스트1", }; }, }; </script> <style lang=""></style>
4) v-bind:변수명 :
- html 속성에 데이터 바인딩을 하는 vue 지시자(directive) - 주로 입력양식 태그를 제외한 거의 모든 태그에 적용할 수 있음 - 상대경로 : 현재경로를 기준으로 파일 찾기 - 절대경로 : 기준 위치에서 파일 찾기 , 뷰는 src/ 가 기준임 1) src/ === @ 로 대체될 수 있음 1) 사용법 : "@/경로/파일명"
attributeView.vue
- 사용법 : <태그 v-bind:속성="값">글자</태그> <!-- v-bind 키워드는 생략가능 --> <태그 :속성="값">글자</태그> <!-- imgSrc : 이미지 넣기 --> 속성: require('이미지경로') 예) <template> <div> <p v-bind:class="classA">클래스 바인딩 : {{ classA }}</p> <p :id="idA">아이디 바인딩 : {{ idA }}</p> <img v-bind:src="imgSrc" /> </div> </template> <script> export default { data() { return { classA: "container", idA: 10, imgSrc: require('@/assets/img/amsterdam.jpg') }; }, }; </script> <style lang=""></style>
5) v-model:변수명
- 입력 양식태그에 적용하는 데이터 바인딩 지시자(directive)
formView.vue
사용법 : <!-- input 사용법 --> <!-- 바인딩변수 = 값 : 화면에 최초로 보여지는 값 --> <input v-model="바인딩변수" type="text" /> <!-- select 사용법 --> <!-- 바인딩변수 = 값 : 화면에 최초로 보여지는 값(옵션태그 값 중에 1개여야 정상적으로 보임) --> <select v-model="바인딩변수"> <option>값</option> </select> <!-- checkbox --> <!-- 바인딩변수 = 값 : value="값" 인 입력양식이 체크가 되어 보여짐 --> <input type="checkbox" v-model="바인딩변수" value="값" /> <!-- radio --> <!-- 바인딩변수 = 값 : value="값" 인 입력양식이 체크가 되어 보여짐 --> <input type="radio" v-model="바인딩변수" value="값" /> <input type="radio" v-model="바인딩변수" value="값2" /> 예) <template> <div> <!-- input --> <div> <label for="userId">아이디</label> <input id="userId" v-model="userId" type="text" name="userId" /> </div> <!-- select --> <div> <label for="">좋아하는 음식</label> <select v-model="food" > <option>햄버거</option> <option>탕수육</option> <option>김밥</option> </select> <!-- checkbox --> <input type="checkbox" v-model="hobby" />여행 <!-- radio --> <input type="radio" v-model="gender" value="남" />남 <input type="radio" v-model="gender" value="여" />여 </div> </div> </template> <script> export default { data() { return { userId: null, food: "불고기", hobby: true, gender: "남", }; }, }; </script> <style lang=""></style>
6) Vue 의 생명주기(Life Cycle) 함수 :
- Vue 컴포넌트 생성 ~ 소멸까지의 함수, - 각 시점에 자동으로 생명주기 함수가 실행됨
사용법 : created() { 실행문; // 화면이 없고 단지 Vue 만 생성되는 시점에 실행됨}, mounted() { 실행문; // 화면이 생겼고 Vue 와 연결될 때 실행됨 }, updated() {실행문; // 화면에서 바인딩된 변수가 갱신될때 실행됨 }
HelloCom.js :
예) <template> <div>{{message}}</div> </template> <script> export default { data() { return { message: "Hello Vue.js!", }; }, created() { console.log("created"); }, mounted() { console.log("mounted"); }, updated() { console.log("updated"); }, }; </script>
7) v-if=”조건문” : 조건문
- 뷰(vue)에서 사용하는 조건문 지시자(directive), 태그에 속성으로 추가해서 사용함 - 참이면 태그가 화면에 보이고, 거짓이면 태그가 화면에 보이지 않음 - 유사한 것으로 v-show 가 있음 : css display 속성으로 화면에 보였다가 안보였다하는 지시자로 v-if 대용으로 사용 가능 - v-if/v-else-if/v-else 로 이루어져 있음
ifView.vue
사용법 : 조건문이 참이면 실행문이 보임, 조건문2가 참이면 실행문2가 보임, 둘 모두 참이 아니면 실행문3이 화면에 보임 <태그 v-if="조건문">실행문</ㅌ> <태그 v-else-if="조건문2">실행문2</ㅌ> <태그 v-else>실행문3</ㅌ> 예 ) <template> <div> <h3>v-if directive를 이용한 조건처리</h3> <!-- 순차적으로 1st 가 true 이면 1st 만 보임(2nd true 이더라도) --> <p v-if="first === true" class="first-p">1st p 가 보입니다.</p> <p v-else-if="second === true" class="second-p">2nd 가 보입니다.</p> <p v-else class="third-p">3rd p 가 보입니다.</p> </div> </template> <script> export default { data() { return { first: false, second: true, }; }, }; </script> <style> </style>
8) v-for=”(data, index) in 배열” : 반복문
- 뷰(vue)에서 사용하는 반복문 지시자(directive), 태그에 속성으로 추가해서 사용함 - 배열값이 화면에 순차적으로 보임 - data 는 배열의 값, index 는 배열의 인덱스번호임
forView.vue
사용법 : <태그 v-for="(data, index) in 바인딩배열변수" :key="index">{{data}}</태그> 예) <template> <div> <ul> <li v-for="(data, index) in fruits" :key="index">{{data}}</li> </ul> </div> </template> <script> export default { data() { return { fruits : ['딸기', '오렌지', '사과', '포도'] }; }, }; </script> <style> </style>
9) methods 함수 / v-on: :
- 뷰(vue)에서 이벤트가 일어날때 사용되는 함수를 정의함 - 예를 들어 클릭시 뷰에서 실행될 함수를 정의 등등을 말함 - html 태그의 클릭이벤트 속성앞에 v-on: 붙여 사용함
사용법 : 이벤트(click, keydown, keyup, mouseover 등) <template> <div> <button v-on:이벤트="함수명">내용</button> <!-- v-on => @ 변경가능 : 축약식 --> <button @이벤트="함수명2">내용</button> </div> </template> <script> export default { data() { return {}; }, methods: { 함수명() { 실행문; }, 함수명2() { 실행문; }, }, }; </script> 예) <template> <div> <button v-on:click="clickBtn">clickBtn클릭</button> <br /> <button @click="clickBtn2(10)">clickBtn2 클릭</button> </div> </template> <script> export default { data() { return { message: "Hello Vue.js!", }; }, methods: { clickBtn() { alert("clicked"); }, clickBtn2(num) { alert("clicked " + num); }, }, }; </script> <style></style>
10) computed 함수 / {{}} :
- 뷰(vue)에서 콧수염 표기법({{}})으로 화면에 값을 나타내는데 값 뿐만아니라 간단한 코딩을 할수도 있음 - 주로 간단한 코딩은 함수로 정의해서 사용하는 것이 가독성이 좋은데 이때 computed 함수를 사용함 - 특징 : 매개변수는 없고, return 값만 존재하는 함수 형태만 사용가능
사용법 : <template> <div> <h4>{{ 함수명 }}</h4> </div> </template> <script> export default { data() { return { }; }, computed: { 함수명() { return 간단한코딩; // 간단한 코딩 }, }, }; </script> 예) <template> <div> <h4>백분율 : {{ percentAmount }}</h4> </div> </template> <script> export default { data() { return { }; }, computed: { percentAmount() { return this.num/100; } } }; </script> <style></style>
11) 객체 배열의 반복문 사용 :
- 프로젝트나 실무에서는 일반 배열보다 객체배열을 사용해서 화면에 출력함 - 객체배열 : 배열안에 객체가 있는 형태, 객체는 속성과 값으로 이루어져 있음
<template> <div> <태그 v-for="(data,index) in 객체배열" :key="index"> {{ data.속성 }} {{ data.속성2 }} </태그> </div> </template> <script> export default { data() { return { 객체배열: [ { 속성 : "값", 속성2: "값2" }, { 속성 : "값", 속성2: "값2" } ], }; }, }; </script> 예) <template> <div> <div class="imgdiv" v-for="data in images" :key="data.text"> <a :href="data.url">{{ data.text }}</a> <img :src="data.src" /> </div> </div> </template> <script> export default { data() { return { images: [ { text: "암스테르담", src: require("@/assets/img/amsterdam.jpg"), url: "http://www.raileurope.co.kr/place/amsterdam-centraal", }, { text: "파리", src: require("@/assets/img/paris.jpg"), url: "https://www.louvre.fr/en/homepage", }, { text: "프라하", src: require("@/assets/img/praha.jpg"), url: "https://www.prague.eu/en", }, { text: "비엔나", src: require("@/assets/img/vienna.jpg"), url: "https://www.belvedere.at/en", }, ], }; }, }; </script> <style> </style>
12) props :
- 컴포넌트는 독립적으로 동작이 가능하도록 다른 컴포넌트와 연결점이(의존성 등) 없음 - 코딩을 하다보면 컴포넌트간에 데이터 전달이 필요한 경우가 있음, 이때 props 속성을 이용해서 전달함 - 물이 위에서 아래로 흐르듯, 부모컴포넌트에서 자식컴포넌트으로 데이터 전달만 가능, 반대는 불가(단방향 데이터 전달)
PropsView.vue : 부모컴포넌트
사용법 : <template> <div> <자식컴포넌트 :props속성="바인딩변수"> </자식컴포넌트> </div> </template> <script> import 자식컴포넌트 from "@/components/자식컴포넌트" export default { data() { return { 바인딩변수: "값" }; }, components: { 자식컴포넌트 } }; </script> 예) PropsView.vue <template> <div> <TodoItem :groceryList="groceryList"> </TodoItem> </div> </template> <script> import TodoItem from "@/components/K_TodoItem" export default { data() { return { groceryList: "삽겹살" }; }, components: { TodoItem } }; </script> <style> </style>
TodoItem.vue : 자식컴포넌트
사용법 : <template> <div> {{ props속성 }} </div> </template> <script> export default { // props속성 가져오기 props: ['props속성'], } </script> 예) PropsView.vue <template> <div> Props : {{ groceryList }} </div> </template> <script> export default { props: ['groceryList'], } </script> <style lang=""> </style>
13) emit :
- 자식컴포넌트에서는 데이터 전달은 못하고, 부모컴포넌트의 함수를 실행할 수 있는데 $emit 함수로 실행할 수 있음
EmitView.vue : 부모컴포넌트
사용법 : <template> <div> <자식컴포넌트 @자식함수="부모함수"> </자식컴포넌트> </div> </template> <script> import 자식컴포넌트 from "@/components/자식컴포넌트"; export default { components: { 자식컴포넌트, }, methods: { 부모함수() { 실행문; }, }, }; </script> <style></style> 예) PropsView.vue <template> <div> <ChildCom @receiveMessage="receiveMessage"> </ChildCom> </div> </template> <script> import ChildCom from "@/components/L_ChildCom"; export default { components: { ChildCom, }, methods: { receiveMessage() { alert("안녕하세요") }, }, }; </script> <style></style>
ChildItem.vue : 자식컴포넌트
사용법 : <template> <div class="box"> <button @click="자식함수()">부모 컴포넌트로 신호 전달</button> </div> </template> <script> export default { methods: { 자식함수() { this.$emit("부모함수"); // 부모함수 호출 }, }, }; </script> <style lang=""></style> 예) PropsView.vue <template> <div class="box"> <button @click="receiveMessage()">부모 컴포넌트로 신호 전달</button> </div> </template> <script> export default { methods: { receiveMessage() { this.$emit("receiveMessage"); }, }, }; </script> <style lang=""></style>