// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App).use(store).use(router).mount('#app');
// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
}
]
const router = createRouter({
history: createWebHistory(process.env.BASE_URL),
routes
})
export default router
이렇게 하면, router
에 저장해둔 경로들과 경로에 따른 컴포넌트 생성을 편하게 할 수 있다.
beforeCreate
단계에선 data() {}
에만 접근 가능하다.
update
쪽은 mounted
단계가 끝나야 실행된다.
v-bind
= v-model
watch
v-
가 붙으면 디렉티브 라고 한다.
v-if
는 ok일때 참 구문을 실행하고, v-show
는 참일때 display하고, 거짓일땐 사라진다.<template>
<div class="hello">
<h1>{{ msg }}</h1>
<hr>
<h1>{{ message }}</h1>
<h1>{{ message.split('').reverse().join('') }}</h1>
<h1>{{ reverse_message }}</h1>
<input type="text" v-model="name"/>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
data () {
return {
message: 'Hello World Vue js',
name: 'lee',
}
},
props: {
msg: String
},
watch: {
name(val) {
console.log(val);
}
},
computed: {
reverse_message() {
return this.message.split('').reverse().join('');
}
}
}
</script>
computed
속성을 이용하여 특정 연산이 처리된 변수를 만들 수도 있다. 로딩을 할 떄 이미 연산이 다 되어 있는 상태로 캐싱해 놓게 된다. 다시 로딩해도 변동사항이 없다면, 그냥 있는거 그대로 사용한다.
Vue의 MVVM: View(action 전달) -> ViewModel(데이터 요청) -> Model (응답) 이후 역순 전달
store
를 만들어서 사용해야 한다.// store/index.js
import { createStore } from 'vuex'
export default createStore({
state: {
// vue component의 data 역할
message: 'hello',
},
getters: {
// 캐싱이 가능하고, 변동 사항이 있을때만 동작한다.
// 그런 면에서 vue 컴포넌트에서 computed 속성과 유사하다.
getMsg(state) {
return `${state.message} => Length: ${state.message.length}`;
}
},
mutations: { // setter
// state를 변경하는 속성
// 일종의 setters 역할을 한다.
changeMessage (state, newMsg) {
state.message = newMsg;
}
},
actions: {
// 외부 접근 가능
// 액션으로 뮤테이션 함수를 콜해서 스테이트 정보를 변경한다.
callMutation ({ state, commit }, { newMsg }) {
commit('changeMessage', newMsg);
}
},
modules: {
}
})
// AboutView.vue
<template>
<div class="about">
<h1>This is an about page</h1>
<h1>{{ getStateMessage }}</h1>
<button @click="fn_changeMsg">Click</button>
</div>
</template>
<script>
export default {
name: 'AboutView',
data() {
return {
flag: true,
}
},
methods: {
fn_changeMsg () {
console.log('asdfadf');
this.$store.dispatch('callMutation', { newMsg: 'hello lee' });
}
},
computed: {
getStateMessage() {
return this.$store.getters.getMsg;
}
}
}
</script>
대충 이렇게 표현한다. 실무에서는 actions
파트에 axios
콜이 들어간다.
view
-> action
-> mutation
에서 state
바꿈 -> 외부에서 가져갈 수 있게 getter
url이 바뀌지 않아도 컴포넌트 뷰만 바뀐다. -> spa. 비동기로 받아놓고 컴포넌트별로 처리만 한다. 모든 응답이 왔을 때, dom을 변경 시키는 방식으로 바꿔준다.
// store/modules/book.js
import { createStore } from 'vuex'
const state = {
title: '동물왕국',
}
const mutations = {
changeTitle (state, newTitle) {
state.title = newTitle;
}
}
const actions = {
callBookMutation({ state, commit }, { newTitle }) {
commit('changeTitle', newTitle);
}
}
const getters = {
getTitle(state) {
return `${state.title} + ${state.title.length}`;
}
}
export default {
state,
getters,
mutations,
actions,
}
// modules/index.js
import { createStore } from 'vuex'
import Book from '@/store/modules/book';
export default createStore({
...
modules: {
// 프로그램 규모가 클 수록, 하나의 store에 state 관리가 힘들다.
// 그래서 module별로 분리해서 관리해주게 된다.
// 1. 스토어용 js파일 생성
// 2. index.js에 임포트
// 3. modeuls에 등록
book: Book,
}
})