-
웹, 앱은 신속하게 반응해야함
-
기존의 방식은 요쳥을 보내고 html 페이지를 새로 받음
-
자바스크립트는 로드된 페이지, 브라우저 내에서 실행됨
-
문서객체모델(DOM) 을 자바스크립트로 조작
-
Vue를 쓰는 이유는 자바스크립트가 완벽하지 않아서
- 바닐라 자바스크립트의 경우 모든 것을 만들어야함.
- 이에따라 성능, 보안이슈, 협업 이슈
- 핵심 비즈니스 로직에만 집
- 서버로부터 새로운 페이지를 받지 않고 현재의 페이지를 동적으로 작성
- SPA에서 HTML, 자바스크립트, CSS 등 모든 코드를 하나의 페이지로 불러오거나, 적절한 자원들을 동적으로 불러들임
- 전통적인 웹 방식은 새로운 페이지를 요청할 때 마다 정적 리소스가 다운로드 되고, 전체 페이지를 다시 렌더링함.
- 이는 변경이 필요없는 부분까지도 렌더링하여 비효율적
- 출발지에서 목적지까지 경로를 결정하는 기능
- 사용자가 화면에서 다른 화면으로 전환할때의 네비게이션 기능
- 요청 URI에 따라 브라우저에서 DOM을 변경하는 방식
- 동적으로 렌더링 되도록 만들면 라우팅에 따라 다른 화면을 구현할 수 있음
- 서버가 할 일을 클라이언트 부담하므로, 서버 부담이 경감
- 모듈화 및 컴포넌트 개발에 용이
- 백엔드와 프론트 개발 영역을 명확하게 구분
- 초기 구동 속도가 느림(처음 접속 시, 사이트 구성과 관련없는 모든 리소스를 한 번에 다 받음)
- 클라이언트에 중요 비즈니스 로직이 노출될 수 있음
- 검색 엔진 최적화가 어려움 => 페이지가 로딩되어야 리소스가 보이므로, 검색에 노출이 안됨
var
선언은 전역 범위 또는 함수 범위이며,let
과const
는 블록 범위이다.var
변수는 범위 내에서 업데이트 및 재선언할 수 있다.let
변수는 업데이트할 수 있지만, 재선언은 할 수 없다.const
변수는 업데이트와 재선언 둘 다 불가능하다.- 세 가지 모두 최상위로 호이스팅된다. 하지만
var
변수만undefined(정의되지 않음)
으로 초기화되고let
과const
변수는 초기화되지 않는다. var
와let
은 초기화하지 않은 상태에서 선언할 수 있지만,const
는 선언 중에 초기화해야한다.
<section id="user-goal">
<h2>My Course Goal</h2>
<p></p>
</section>
const app = Vue.creatApp();
app.mount('#user-goal');
let message = 'Hello'
let longMessage = message + 'World'
console.log(longMessage) // Hello World
let mesasge = 'Hello!!!!'
console.log(longMessage) // Hello World
/자바스크립트는 반응형이 아니다.
const data ={
message: 'Hello!',
longMessage: 'Hello! World!'
};
const handler = {
set(target, key, value){
console.log(target)
console.log(key)
console.log(value)
}
}
const proxy = new Proxy(data, handler);
proxy.message = 'Hello!!!!!'
//{message: 'Hello!', longMessage: 'Hello! World!'}
//message
//Hello!!!!!
/Vue는 이러한 프록시를 내장하여 반응형 변수를 만든다.
<body>
<section id="app">
</section>
<section id="app2">
</section>
</body>
const app = Vue.createApp()
app.mount('#app');
const app2 = Vue.createApp();
app.mount('#app2')
<<<<<<< HEAD
const app2 = Vue.createApp({
template : `<p>{{ favoriteMeal }}</p>`,
data(){
return {
favoriteMeal: 'Pizza'
}
}
});
app2.mount('#app2')
- 이런식으로 템플릿을 내보낼 수 있음.
- 다만 가독성이 떨어짐
- ref 속성은 기본 HTML 속성이 아님
- Vue는 ref를 감지하고 내부에 이를 저장함
- 받을때는 $ 를 사용하면 내장 프로퍼티를 감지함
<section id="app">
<h2>How Vue Works</h2>
<input type="text" ref="userText">
<button @click="setText">Set Text</button>
<p>{{ message }}</p>
</section>
const app = Vue.createApp({
data() {
return {
currentUserInput: '',
message: 'Vue is great!',
};
},
methods: {
saveInput(event) {
this.currentUserInput = event.target.value;
},
setText() {
//this.message = this.currentUserInput;
this.message = this.$refs.userText
},
},
});
-
인풋에 값을 넣고 변경했을 때 페이지 전부가 렌더링 되는 것이 아니라 해당 부분만 변경됨
-
이는 Vue가 DOM을 업데이트 하는 방식에 따른 것임
-
Vue는 가상 DOM을 생성하고, 이를 메모리에서 업데이트하는 것이 실제 DOM을 업데이트 하는 것보다 효율적임
-
순서
- 텍스트가 변경
- Vue가 해당 텍스트 변경 사항을 감지
- 새로운 가상 DOM을 생성해서 기존 가상 DOM과 비교
- 변화를 감지한 부분을 변화가 감지된 실제 DOM에 업데이트 함
- 최적화 방식에는 여러가지가 있음 이는 그 중 하나
createApp({....})
beforeCreate()
created()
(이 이후에 Vue가 프로퍼티를 인식)
Compile template
- 모든 동적 플레이스 홀더와 보간 등이 제거된 후 사용자에게 표시될 구체적인 값으로 대체되는 단계
beforeMount()
- 화면에 무언가 표시하기 직전 단계
화면 표시
mounted()
- Vue가 화면에 표시할 대상을 인지하고 브라우저에 지시 사항을 넘겨서 브라우저가 Vue앱이 정의한 대로 모든 컨텐츠가 있는 HTML 요소를 추가함
Mounted Vue Instance
- 마운트 된 Vue 앱, 즉 마운트된 Vue 인스턴스가 완성
Data Changed
beforeUpdate()
- 앱 내에서 업데이트를 완전히 처리하지 않았을 때에 대한 단계
- 렌더링이 되지 않음
updated()
- 해당 처리가 완료되었을 때에 대한 단계
- 업데이트 이후에는 변경 사항만 처리된 후 화면에 렌더링됨.
- Instance Unmounted
- 종종 Vue가 마운트되지 않을 때가 있음
- 앱의 마운트가 삭제되면 화면의 모든 콘텐츠가 삭제되며 앱 사용이 불가능함
beforeUnmount()
- 콘텐츠 삭제 직전에 실행되는 단계
unmounted()
- 콘텐츠 삭제 후 실행되는 단계
const app = Vue.createApp({
beforeCreate(){
console.log('beforeCreate()')
},//화면이 마운트되기전
created(){
console.log('created()')
},//화면이 마운트되기전
beforeMount(){
console.log('beforeMount()')
},//화면이 마운트되기전
//=========화면에서 보임
mounted(){
console.log('mounted()')
},//화면이 마운트되고난후
beforeUpdate(){
console.log('beforeUpdate()')
},//dom이 변화하기 전
updated(){
console.log('updated()')
},//dom이 변화하고 난 후
beforeUnmount(){
console.log('beforeUnmount()')
},//dom이 unmount되기전
unmounted(){
console.log('unmounted()')
}//dom이 unmount되고난 후
});
- app.comonent() 선언
- 식별자, 구성 객체 필요
- app.component('friend-contact') 대시기호 포함
- 공식 내장 HTML 요소와 충돌되는 일을 막기 위함
- 컴포넌트는 기본적으로 커스텀 HTML 요소이기 때문
- app.component('friend-contact') 대시기호 포함
- 컴포넌트는 미니 Vue 앱
app.component('friend-contact', {
template: `
<li>
<h2>{{ friend.name }}</h2>
<button @click="toggleDetails()">
{{ detailsAreVisible ? 'Hide' : 'Show' }} Details
</button>
<ul v-if="detailsAreVisible">
<li><strong>Phone:</strong> {{ friend.phone }}</li>
<li><strong>Email:</strong> {{ friend.email }}</li>
</ul>
</li>
`,
data() {
return {
detailsAreVisible: false,
friend: {
id: 'manuel',
name: 'Manuel Lorenzo',
phone: '01234 5678 991',
email: 'manuel@localhost.com',
},
};
},
methods: {
toggleDetails() {
this.detailsAreVisible = !this.detailsAreVisible;
},
},
});
-
강의 3("Vue의 다양한 활용 방법")에서 배웠듯이, Vue.js를 사용하여 페이지 일부(여러 HTML)를 제어하거나 소위 "싱글 페이지 애플리케이션(SPA)"을 구축할 수 있습니다.
-
HTML 페이지의 여러 독립적인 부분을 제어하는 경우 여러 Vue 앱으로 작업하는 경우가 많습니다(예:
createApp()
를 두 번 이상 호출하여 여러 앱을 만듭니다). -
반면에 SPA를 구축하는 경우 일반적으로 **하나의 "루트 앱"**으로 작업하고(즉,
createApp()
은 전체 코드베이스에서 한 번만 사용됨) 대신 여러 컴포넌트로 사용자 인터페이스를 구축합니다. -
여러 Vue 앱이 있는 경우에도 컴포넌트를 사용할 수 있지만, 하나로 연결된 큰 사용자 인터페이스를 구축하는 경우 일반적으로 여러 Vue 앱을 사용하지 않습니다.
왜일까요?
-
Vue 앱은 서로 독립적이므로 서로 통신할 수 없기 때문입니다. 통신할 수 있게 하는 비공식적인 방법이 존재할 수 있지만, 앱 간에 데이터를 공유하고 앱 B에서 문제가 발생하는 경우 앱 A에서 업데이트하는 마땅한 공식적인 방법이 없습니다.
-
반면에 곧 배우게 될 컴포넌트는 컴포넌트 간에 데이터를 교환할 수 있는 특정 통신 메커니즘을 제공합니다. 따라서 여러 컴포넌트를 포함하는 하나의 루트 앱으로 작업하는 경우 하나로 연결된 UI를 구축할 수 있다는 것을
-
강의 전체에서 볼 수 있습니다. 특히 강의 프로젝트에서요!
- 수정시 새로고침
- 새로고침시 기존에 정보들 초기화
- vscode로 자동완성 한계