Programming Language/Vue

[Vue] 09)Vue Advanced

Sergemeow 2023. 5. 15. 15:10

Local Storage

상태 유지하기

  • 개발자 도구 > Application > Local Storage에서 확인

Window.localStorage

  • 브라우저의 내장 객체 중 하나
  • Key-Value 형태로 데이터를 저장할 수 있는 저장소
  • localStorage에 저장된 데이터는 브라우저를 종료해도 계속해서 유지 됨
    • 다른 탭에서도 동일한 데이터를 공유할 수 있는 반면, 다른 도메인에서는 접근할 수 없음
    • 보안과 관련된 정보를 저장하기에는 적합하지 않음
  • setItem(key, value) - key, value 형태로 데이터 저장

  • getItem(key) - key 값으로 저장된 데이터 불러오기

JSON.stringify

  • JSON(JavaScript Object Notation) 객체의 메서드
  • 자바스크립트 객체를 JSON 형식의 문자열로 변환하여 반환

JSON.parse

  • JSON 형식의 문자열을 자바스크립트 객체로 변환하여 반환


// App.vue

export default {
  name: 'App',
  components: {
  },
  create(){
    this.$store.dispatch('loadMessage')
  },
// index.js

mutations: {
    CHANGE_MESSAGE(state, message){
      // console.log(state)
      // console.log(message)
      state.message = message
    },
    LOAD_MESSAGE(state){
      // localStorage에서 데이터를 꺼내옴
      const parsedMessage = JSON.parse(localStorage.getItem('message'))
      state.message = parsedMessage ? parsedMessage : ''
    },
  },
  actions: {
    changeMessage(context, message){
      // console.log(context)
      // console.log(message)
      context.commit('CHANGE_MESSAGE', message)
      // Save at local Storage
      context.dispatch('messageSaveToLocalStorage')
    },
    messageSaveToLocalStorage(context){
      const message = JSON.stringify(context.state.message)
      localStorage.setItem('message', message)
    },
    loadMEssage(context){
      context.commit('LOAD_MESSAGE')
    }
  },

plugins

  • Vuex store에 추가적인 기능을 제공하는 확장 기능
  • 일반적으로 state의 변화를 감지해, 어플리케이션의 성능을 최적화하는 목적을 가짐

vuex-persistedstate

  • Vuex store의 상태를 브라우저 local storage에 저장해주는 plugin
  • 페이지를 새로고침하거나 브라우저를 종료하였다가 다시 열었을 때, 이전 상태를 유지할 수 있도록 해줌

  • 설치
$ npm i vuex-persistedstate
  • 적용
// index.js

import createPersistedState from 'vuex-persistedstate'

Vue.use(Vuex)

export default new Vuex.Store({
	plugins: [
		createPersistedState(),
	],
  • 메시지 입력 후, local storage 확인

Vuex Binding Helper

Vuex Binding Helper

  • Vuex store의 state, mutations. actions 등을 간단하게 사용할 수 있도록 만들어진 헬퍼 함수
  • mapState, mapActions와 같은 형식으로 사용
  • 사용하기 위해서는 import
import { mapState, mapActions } from 'vuex'

mapState

  • Vuex store의 상태를 컴포넌트의 데이터에 매핑할 때 사용
  • 객체 혹은 배열 형태로 상태를 매핑하여 사용할 수 있음
  • 객체 형태로 매핑
    • mapState를 import
    • Spread operator를 사용하여 mapState를 전개
    • mapState 내부에 불러오고자하는 값을 정의. 화살표 함수를 사용하여 message key에 state의 message 값을 할당
    • key 값은 컴포넌트에서 사용하고자 하는 다른 이름으로 변경하여 사용할 수 있음
// 1
message() {
  return this.$store.state.message
},

// 2
...mapState(['message']),

// 3 
...mapState({
  message: state => state.message
}),

// 1, 2, 3 동일하게 작동
  • 배열 형태로 매핑
    • mapState를 import
    • Spread operator를 사용하여 mapState를 전개
    • vuex store의 상태 중, 불러오고자 하는 대상을 배열의 원소로 정의
<script>
import { mapState } from 'vuex'

export default {
	...
	computed: {
		...mapState(['message'])
	},
}
</script>
  • 컴포넌트에서 this.$store.dispatch()를 호출하는 대신, 액션 메서드를 직접 호출하여 사용 할 수 있음
  • mapState와 같이 객체 혹은 배열 형태로 매핑가능
  • 배열 형태로 매핑
  1. mapState와 동일한 형식으로 사용
    1. 단, 이 경우 changeMessage에 넘겨주어야 할 inputData를 changeMessage 호출 시 인자로 직접 값을 넘겨주어야 함
<template>
	<div id="app">
		<h1>{{ message }}</h1>
		<input
			type="text"
			@keyup.enter="changeMessage(inputData)"
			v-model="inputData">
	</div>
</template>

<script>
....
	methods: {
		...mapActions(['changeMessage'])
	},
}
</script>
  • 객체 형태로 매핑
  1. Actions의 changeMessage를 actionsChangeMessage에 매핑
  2. this.actionsChangeMessage 형식으로 사용
  3. payload를 넘겨주거나 추가적인 로직 작성 가능
<template>
	<div id="app">
		<input
			type="text"
			@keyup.enter = "onSubmit"
			v-model="inputData">
	</div>
</template>

<script>
import { mapActions } from 'vuex'
export default {
	...
	methods: {
		...mapActions({
			actionsChangeMessage: 'changeMessage'
		}),
		onSubmit(){
			const newMessage = this.inputData
			this.actionsChangeMessage(newMessage)
			this.inputData = ''
		}
	}
}
</script>

mapGetters

  • mapState, mapActions와 동일한 방식으로 사용가능
<template>
	<div id="app">
	<h1>길이 {{ messageLength }}의 메시지 {{ message }}를 입력 받음</h1>
		<h3>x2: {{ doubleLength }}</h3>
	</div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
	...
	computed: {
		...mapGetters(['messageLength', 'doubleLength'])
	},
}
</script>

modules

  • Vuex store를 여러 파일로 나눠서 관리할 수 있게 해주는 기능
  • Vuex store와 동일한 구성을 가진 별도의 객체를 정의하여 modules 옵션에 작성한 객체를 추가하여 사용
  • 별개의 .js 파일에 정의하고 import 하는 방식으로도 사용가능
  • Store의 가독성을 향상시킬 수 있음

  • 별도의 js 파일에 객체 정의
// store/modules/myModule.js

const myModule = {
	state: {
		age: 30
	},
	mutations: {
		INCREMENT_AGE(state){
			state.age += 1
		}
	},
	actions: {
		incrementAge(context){
			context.commit(INCREMENT_AGE)
		}
	}
}
export default myModule
  • 정의한 js 파일의 객체를 import
  • Store의 modules 옵션에 추가
import Vue from 'vue'
import Vuex from 'vuex'
import myModule from './modules/myModule'

Vue.use(Vuex)

export default new Vuex.Store({
	modles: {
		myModule
	}
})