목차
목차1. Vue 6화 (day39)1.플러그인 (14m, 2배속 필기최소화)1-1. 플러그인 정의1-2. 플러그인 사용1-3. fetch 예제2.믹스인 (14m + 32m, 2배속 필기최소화)2.1 믹스인 기본2.2 믹스인 심화3. Teleport (42m, 생략, 추후 듣기)4. Provide, inject (16m, 2배속 필기최소화)5. Vuex(Store) (26m + 29m + 33m, 2배속 필기최소화)5.1 Vuex 도입 전 핵심 개념 구현해보기5.2 Vuex 문서 살펴보기5.3 vuex 모듈 방식으로 사용하기 (여러개의 store)
1. Vue 6화 (day39)
1.플러그인 (14m, 2배속 필기최소화)
전역에서 사용가능한 기능(함수)들을 정의하는 기능install()
속성을 통해 정의할 수 있다.
1-1. 플러그인 정의
- install 속성 내부에서
app.config.globalProperties.플러그인함수이름 =(()⇒{})
으로 정의 - install속성은 기본적으로 두 개의 인자를 받는데, 전역 app과 options로 사용한다.
(
install(app, options){ ... }
)
1-2. 플러그인 사용
- 전역 App에 등록하기
- 정의한 플러그인을 import 하여, main.js에서 app.use() 메소드로 mount전에 등록하여 준다.
app.use(fetcjPlugin)
- 특정 컴포넌트에서 사용하기
- 정의할 때 사용한 플러그인 함수이름을 통해, 전역컴포넌트에서 해당 함수를 사용할 수 있다.
this.$fetch("https://jsonplaceholder.typicode.com/todos/1")
- options 설정가능
- app.use를 통해 전역에 등록할 때 2번째 인자를 객체형태로 하여 option을 지정해줄 수 있다.
pluginName
: 함수의 이름 바꾸기
코드예시
// main.js app.use(fetchPlugin, { pluginName: "$myName", }); // fetch.js install(app, options) { app.config.globalProperties[options.pluginName || "$fetch"] = (()=>{ 해당 플러그인 함수 내용... }) } // App.vue this.$myName("...")
1-3. fetch 예제
코드보기
- fetch.js 에서 플러그인 정의하기
export default { install(app, options) { app.config.globalProperties.$fetch = (url, opts) => { return fetch(url, opts).then((res) => res.json()); }; }, };
- main.js에서 등록하고 App.vue에서 사용하기
// main.js import fetchPlugin from '@/plugins/fetch' const app = Vue.createApp(App); app.use(fetchPlugin) app.mount("#app"); // App.vue created() { this.$fetch("https://jsonplaceholder.typicode.com/todos/1") .then((res) => console.log(res)); },
2.믹스인 (14m + 32m, 2배속 필기최소화)
재사용 가능한 기능 단위를 의미 mixin으로 공통된 기능을 만들고, 컴포넌트가 mixin을 등록하여 여러 컴포넌트에서 사용가능하도록 함
2.1 믹스인 기본
- 믹스인은 기본적으로
옵션 단위
로 가지고 있음 data()
,methods()
,created()
,mounted()
등...
- 옵션병합
- 컴포넌트의 옵션과 mixin의 옵션이 중복되는 경우 설정이 가능 (
default는 컴포넌트 옵션 우선
) 라이프사이클 훅
같은 경우는 덮어씌어지는 것이 아니라 병합되어, 둘 다 발생하게 된다!methods()
는 컴포넌트 우선으로 병합되어짐
- 전역 믹스인 (필기 생략- 문서참고)
2.2 믹스인 심화
설문조사 form 선택하여 제출하는 예제
- 여러 컴포넌트에서 공통적인 옵션을 사용하고 있을 때 mixin을 통해 간략화 하기
- input의 양방향 바인딩 연습
- textField와 RadioSelector의 컴포넌트화
- 공통 옵션인 props(modelValue, title, items), emits 의 mixin화
- index.js를 통한 import 가독성 증대
3. Teleport (42m, 생략, 추후 듣기)
4. Provide, inject (16m, 2배속 필기최소화)
React의 contextAPI 와 비슷한 개념으로, 중첩된 구조에서 하위컴포넌트와 부모컴포넌트의 데이터 교환을 위한 옵션
주의
기본 형식으로 사용한다면, inject된 data는 반응성을 가지지 않는다.computed
와 함께 사용하여, 반응성을 가지도록 한다.
- computed는 computed 객체를 리턴하므로, 사용시에는 computed.value를 통해 사용해야한다
- 중첩이 깊은 특수한 경우의 사용
provide
는 하나의 옵션속성으로 data를 리턴하는 방식으로 사용 (export 비슷한 개념)
provide() { return { msg: computed(()=>this.msg) } }
inject
는 data를 받아 명시한 후 바로 사용
html사용 시: {{msg.value}} js의 옵션 : inject: ['msg']
- provide-inject는 단순 장거리props의 역할만 하고, emit을 통한 자식→부모 수정이 안되기 때문에, 이를 해결하는
전역스토어인 Vuex 라이브러리
를 주로 사용한다.
5. Vuex(Store) (26m + 29m + 33m, 2배속 필기최소화)
redux와 같이 전역에 상태를 정의하고, 관리하도록 하는 뷰의 상태관리 라이브러리
5.1 Vuex 도입 전 핵심 개념 구현해보기
필요성
- 조손요소에서 부모요소로 data를 전달하고 싶을 때
- 여러 곳에서 변화가 발생하는 state(data)를 관리하기 위해서
mutations
- 컴포넌트의 사용처에서 store의 data를 바꿔줄 수 도 있지만, 변경에 대한 책임을 한 곳에 두기 위해 생겨난 상태변경을 위한 함수모음
state의 반응성 가지도록 하기
- mutation에서 직접적으로 data를 변경하면, 반응성을 줄 수 없다.
- vue 패키지에서 반응성을 부여하기 위해 reactive 패키지를 사용한다.
const state = reactive({ msg: "Hello Vue?!", count: 1 });
actions
- 데이터의 변경 이외의 모든 작업을 진행
- actions에서 fetch 받아온 데이터로 직접적으로 수정할 수 있지만, 데이터의 관리,추적이 어려워지기 때문에, 데이터의 변경은 무조건 mutations의 함수를 통해 변경하도록 한다.
5.2 Vuex 문서 살펴보기
Vuex는 Vue.js 애플리케이션에 대한 상태 관리 패턴 + 라이브러리 입니다. 중앙 집중식 저장소 역할을 통해 예측 가능한 방식으로 상태를 변경
- 상태(state)는 앱을 작동하는 데이터이다.
- 뷰(view)는 상태에 대한 선언적 매핍이다
- 액션(action)은 뷰에서 사용자 입력에 대해 반응성을 갖는 상태를 바꾸는 방법이다.\
문제의식
: 공통의 상태를 공유하는 여러 컴포넌트가 있는 경우해결
- actions와 mutation의 구분
actions
는 비동기처리를 포함하여 데이터 변경 이외의 모든 작업을 처리하고,mutation
은 데이터변경과 관련한 동기적 처리만을 담당한다.

주의
- store에서는 context 객체에 접근할 수 있는데,
context객체
는 state, getters, commit, dispatch에 각가 접근 할 수 있다. commit
은 mutaion을 실행하기 위한 함수 (commit(’updateMsg’, todo.title)
)dispatch
는 actions를 실행하기 위한 함수 (dispatch(”fetchTodo”)
)
코드
vuex에서의 state, getters, mutations, actions 사용예제
// store import { createStore } from "vuex"; export default createStore({ state() { return { msg: "Hello vuex", count: 1, }; }, getters: { reversedMsg(state) { return state.msg.split("").reverse().join(""); }, }, mutations: { increaseCount(state) { state.count += 1; }, updateMsg(state, newMsg) { state.msg = newMsg; }, }, actions: { async fetchTodo({ commit }) { const todo = await fetch( "https://jsonplaceholder.typicode.com/todos/1" ).then((res) => res.json()); console.log(todo); commit("updateMsg", todo.title); }, }, });
5.3 vuex 모듈 방식으로 사용하기 (여러개의 store)
- 예제 코드만 첨부
주의
getters를 통해 store에서 꺼내올 때 점표기법이 아닌 [] 로 접근하고, store의이름을 (/
)로 표기하여 가져온다는 것-
return this.$store.getters["message/reversedMsg"];
count와 message store로 분리하기
store코드
// store.index.js import { createStore } from "vuex"; import message from "./message"; import count from "./count"; export default createStore({ modules: { message, count, }, }); // store.count.js export default { namespaced: true, state() { return { count: 1, }; }, mutations: { increaseCount(state) { state.count += 1; }, decreaseCount(state) { state.count -= 1; }, updateMsg(state, newMsg) { state.msg = newMsg; }, }, }; // store.message.js export default { namespaced: true, state() { return { message: "Hello message Module Store", }; }, getters: { reversedMsg(state) { return state.message.split("").reverse().join(""); }, }, mutations: { updateMsg(state, newMsg) { state.message = newMsg; }, }, actions: { async fetchTodo({ commit }) { const todo = await fetch( "https://jsonplaceholder.typicode.com/todos/1" ).then((res) => res.json()); console.log(todo); commit("updateMsg", todo.title); }, }, };
사용 컴포넌트 (Hello.vue)
export default { data() { return {}; }, computed: { count() { return this.$store.state.count.count; }, message() { return this.$store.state.message.message; }, reversedMsg() { return this.$store.getters["message/reversedMsg"]; }, }, methods: { increaseCount() { this.$store.commit("count/increaseCount"); }, decreaseCount() { this.$store.commit("count/decreaseCount"); }, fetchTodo() { this.$store.dispatch("message/fetchTodo"); }, }, };
중요
vuex의 ‘mapState, mapGetters, mapMutations, mapActions’ 사용하기mapState(’store이름’, [가져올 state, ... , ])

before
export default { computed: { count() { return this.$store.state.count.count; }, message() { return this.$store.state.message.message; }, reversedMsg() { return this.$store.getters["message/reversedMsg"]; }, }, methods: { increaseCount() { this.$store.commit("count/increaseCount"); }, decreaseCount() { this.$store.commit("count/decreaseCount"); }, fetchTodo() { this.$store.dispatch("message/fetchTodo"); }, }, };
after
import { mapState, mapGetters, mapMutations, mapActions } from "vuex"; export default { computed: { ...mapState("count", ["count"]), ...mapState("message", ["message"]), ...mapGetters("message", ["reversedMsg"]), }, methods: { ...mapMutations("count", ["increaseCount, decreaseCount"]), ...mapActions("message", ["fetchTodo"]), }, };