vite는 현재 사용하는 프론트엔드 개발에서 웹팩을 중심으로 개발 환경과 배포 시스템이 구축되어 있는데, 이 웹팩을 사용할 때 보다 훨씬 더 빠르게 개발하고 배포할 수 있기 때문에 등장한 javascript 네이티브 모듈을 기반으로 한 dev server이다.
웹팩은 하나 하나 다 설정을 해줘야 하는 반면 vite를 이용하면 어느정도 기본 세팅이 되어 있기 때문에 사용하기 편리하다.
npm create vite@latest 폴더이름
현재 vue만 진행 중이므로 vue만 연속 2번 선택
이후 만든 폴더 이름으로 들어가서 code . -r
로 프로젝트를 연다.
실행은 npm run dev
로 되게끔 세팅이 되어 있다.
option을 설정하려면 아래의 사이트에 가서 어떻게 사용하는지 확인을 해서 사용을 하면 된다.
vite.config.js파일에 들어가서 option을 설정하면 된다.
예를들어 경로를 ./
가 아닌 ~/
로 사용하기 위해 아래와 같이 resolve.alias를 설정 해보자.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [
{ find: '~', replacement: `${__dirname}/src` }
]
}
})
이후 추가적으로 eslint를 사용하려면
npm i -D eslint eslint-plugin-vue
로 설치해준다."editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.alwaysShowStatus": true
그리고 .eslintrc.json(rc는 숨김 파일)에 옵션을 설정해 주면 된다.
아래는 수업 때 사용하는 예시이다. (코드 뒤에 세미콜론 사용x 등..)
{
"env": {
"browser": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended"
],
"rules": {
"semi": ["error", "never"],
"quotes": ["error", "single"],
"eol-last": ["error", "always"],
"vue/html-closing-bracket-newline": ["error", {
"singleline": "never",
"multiline": "never"
}],
"vue/html-self-closing": ["error", {
"html": {
"void": "always",
"normal": "never",
"component": "always"
},
"svg": "always",
"math": "always"
}],
"vue/comment-directive": "off",
"vue/multi-word-component-names": "off"
}
}
추가적으로 Vue 문법을 이해하기 위해 Vue Language Features(Volar) 확장 프로그램을 설치하면 보기가 편해진다.
※ Vue Vite를 이용하여 사용한다.
vuex는 store를 사용하기 위해 쓰는 plugin이다.
npm install vuex
import { createStore } from 'vuex'
를 통해 createStore
를 불러와서 실행을 한다.
그리고 app.use(store)
(플러그인)로 연결하여 사용한다.
사용시 편리성을 위해 모듈로 분리(별도의 파일로 만들기)하여 사용하는 것이 좋다.
store를 연결하기 위해 main.js에 다음과 같이 코드를 작성 해준다.
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
createApp(App)
.use(store)
.mount('#app')
vuex에서는 Core Concepts가 5개가 있다.
Core Concepts | 매칭 되는 것 |
---|---|
State | data(반응형) |
Getters | computed(계산된 상태) |
Mutations | methods, state의 데이터 수정 권한 |
Actions | methods |
이들을 Modules(모듈화)를 별도로 한다.
src폴더 안에 store폴더를 만들고 그 안에 index.js 파일을 만들어 사용하자.
import { createStore } from 'vuex'
export default createStore({
state() {
count
},
getters: {
},
mutations: {
increment(state) {
state.count++
}
},
actions: {
increment(context) {
commit('increment')
})
ex) 호출 시
store.commit('increment')
store.dispatch('increment')
const { state, getters, commit, dispatch } = context
Core Concepts | 매칭 되는 것 |
---|---|
State | state |
Getters | getters |
Mutations | commit |
Actions | dispatch |
mutations: {
increment (state, payload) {
state.count += payload.amount
}
}
ex) 호출 시
store.commit('increment', {
amount: 10
})
store파일에 있는 index.js에서 state(data부분)에 여러 값들이 있고, 이 때문에 메소드들이 복잡해져서 나누고 싶어졌다. 다른 module을 만들고 싶다면 어떻게 할까?
먼저 store내부에 다른 module을 js파일로 만들어주어 모듈화를 한다.
이 module들은 위에 import없이 export default로 작성해주면 된다.
★ 이때 중요한 것은 module화 시킨 파일에 namespaced: true
를 꼭 추가해 줘야 한다!
아래의 예시를 보면서 이해해보자!
index.js
import { createStore } from 'vuex'
import module1 from './module1'
import module1 from './module2'
export default createStore({
modules: {
module1,
module2
})
각 module들 파일 작성 방법: module1
// module1
export default {
namespaced: true,
state() {
// 관련 데이터
},
getters() {
},
mutations: {
// 관련 권한들
},
actions: {
// 관련 메소드
}
}
각 module들 파일 작성 방법: module2
// module2
export default {
namespaced: true,
state() {
// 관련 데이터
},
getters() {
},
mutations: {
// 관련 권한들
},
actions: {
// 관련 메소드
}
}
store에서 데이터, 함수 등을 가져오는건 간단하다.
this.$store
를 이용해서 가져오면 된다!
위에 배운 내용을 토대로 아래의 예시를 보며 이해를 해보자!
import { createStore } from 'vuex'
export default createStore({
state() {
return {
count: 0
}
},
getters: {
},
mutations: {
// 내부에서 사용하는 것을 권장한다!
// 예시를 위해 actions와 mutations에서 사용을 해본다!
increase(state) {
// state객체를 받는데 이는 위에 있는 state이다.
// state객체를 매개변수로 받아 접근을 하는 것이다!
// 수정 권한을 준 것이다!
state.count += 1
}
},
actions: {
increase({ commit }) {
//const { state, getters, commit, dispatch } = context
commit('increase')
}
})
// vue 파일의 script부분
export default {
computed: {
data() {
// store에서 count를 가져옴
return this.$store.state.count
}
},
methods: {
increase() {
// 1. mutation에서 호출
// commit: mutations을 호출해 줘라의 메소드!
this.$store.commit('increase')
// 2. actions에서 호출
// dispatch: actions을 호출 해줘라 메소드!
this.$store.dispatch('increase')
}
}
}
★ 여기서 모듈화를 이용했을 때 접근하는 방법을 알아보자!
module화에서 쓴 예시를 예로 들어 보겠다.
export default createStore({
modules: {
module1,
module2
})
// module1
export default {
namespaced: true,
state() {
return {
count: 1
}
},
getters() {
},
mutations: {
increase(state) {
state.count += 1
}
},
actions: {
increase({ commit }) {
commit('increase')
}
}
// module2
export default {
namespaced: true,
state() {
return {
count: 2
}
},
getters() {
},
mutations: {
increase(state) {
state.count += 1
}
},
actions: {
increase({ commit }) {
commit('increase')
}
}
// vue 파일의 script부분
export default {
methods: {
increase() {
// module1 호출!
this.$store.commit('module1/increase')
// module2 호출!
this.$store.dispatch('module2/increase')
}
}
}
vue파일에서 가져오려면 바로 위의 예시처럼 modules에 명시한 이름을 앞에 작성해주고 '/'을 작성 후 메소드를 입력하면 해당 module의 메소드를 실행하게 된다!
vuex에서는 mutations가 데이터 수정 권한을 가지고 있었다.
이 경우 안정적이지만 mutations에 코드를 만드는게 복잡하고 불편하다.
pinia는 불안하지만 mutations처럼 코드로 만들지 않아도 된다.
pinia의 자세한 사항은 아래 링크의 문서를 참고하면 된다.
npm install pinia
pinia를 연결하기 위해 main.js에 다음과 같이 코드를 작성 해준다.
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia'
createApp(App)
.use(createPinia())
.mount('#app')
pinia에서는 State, Getters, Actions 3가지로 줄어들었다.
Core Concepts | 매칭 되는 것 |
---|---|
State | data |
Getters | computed(계산된 상태) |
Actions | state의 수정 권한 |
Modules(모듈화)는 기본이다.
pinia에서는 vuex와 다르게 module화 할 때, namespaced를 작성할 필요가 없다!
메세지를 반전시키는 간단한 예제로 확인해보자!
주석을 잘 읽어보면 확인해 보면 도움이 될 것이다!
// store파일 안의 module.js
import { defineStore } from 'pinia'
export const useMessageStore = defineStore({
state: () => ({
// data
message: 'Hello world!'
}),
getters: {
// 계산된 데이터(computed data)
reversedMessage(state) {
return state.message.split('').reverse().join('')
}
},
actions: {
reverseMessage() {
// vuex에서는 context를 통하여 접근했지만 pinia에선 this로 접근한다!
this.message = this.message.split('').reverse().join('')
}
}
})
// vue 파일의 script부분
import { mapState } from 'pinia'
import { useMessageStore } from './store/message'
export default {
computed: {
...mapState(useMessageStore, [
'message'
])
}
}