본 문서는 스프링 부트(Spring Boot) 기반의 백엔드와 프론트엔드가 분리된 시스템 개발 시 유용하게 활용될 수 있는 팁들을 다룹니다.
백엔드 개발 팁
서버 포트 변경
백엔드 애플리케이션의 포트는 주로 application.properties 또는 application.yml 파일 내에서 설정할 수 있습니다. 예를 들어, application.yml 파일에서는 다음과 같이 변경합니다.
server:
port: 8081 # 원하는 포트 번호로 변경
특정 요청에 대한 인증 불필요 설정
스프링 시큐리티(Spring Security)를 사용하는 경우, 특정 API 경로에 대해 인증 없이 접근하도록 설정할 수 있습니다. 이는 주로 WebSecurityConfigurerAdapter를 상속받은 설정 클래스에서 antMatchers와 permitAll()을 사용하여 구성합니다.
API 문서(Swagger/OpenAPI) 접근 경로
Swagger 또는 OpenAPI 3을 사용한다면, API 문서 인터페이스는 일반적으로 다음 주소를 통해 접근할 수 있습니다. 시스템 설정에 따라 포트 번호는 달라질 수 있습니다.
http://localhost:8081/swagger-ui/index.html
로컬 파일 또는 JAR 내 리소스 읽기
JAR 파일로 패키징된 애플리케이션에서는 일반적인 파일 경로를 통한 접근이 어렵습니다. 이 경우 InputStream을 활용하여 리소스에 접근해야 합니다.
다음은 파일 내용을 읽고 쓰는 간단한 유틸리티 클래스입니다.
package com.example.utils.io;
import java.io.*;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
public class ResourceReadWriteUtil {
/**
* InputStream으로부터 내용을 읽어 문자열로 반환합니다.
* @param inputStream 읽을 InputStream
* @param charsetName 사용할 문자 인코딩 이름
* @return 읽은 문자열 내용
* @throws IOException 입출력 오류 발생 시
*/
public static String readFromStream(InputStream inputStream, String charsetName) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, Charset.forName(charsetName)))) {
StringBuilder content = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
content.append(line);
}
return content.toString();
}
}
/**
* 파일에서 내용을 읽어 문자열로 반환합니다.
* @param targetFile 읽을 파일 객체
* @param charsetName 사용할 문자 인코딩 이름
* @return 읽은 문자열 내용
* @throws IOException 입출력 오류 발생 시
*/
public static String readFromFile(File targetFile, String charsetName) throws IOException {
long fileSize = targetFile.length();
if (fileSize > 1024 * 1024 * 5) { // 5MB 제한 예시
throw new IOException("파일 크기가 너무 큽니다: " + fileSize + " bytes");
}
byte[] buffer = new byte[(int) fileSize];
try (FileInputStream fileStream = new FileInputStream(targetFile)) {
fileStream.read(buffer);
return new String(buffer, charsetName);
}
}
/**
* 파일에 문자열을 작성합니다.
* @param targetFile 작성할 파일 객체
* @param content 작성할 문자열 내용
* @param charsetName 사용할 문자 인코딩 이름
* @throws IOException 입출력 오류 발생 시
*/
public static void writeToFile(File targetFile, String content, String charsetName) throws IOException {
try (FileOutputStream fileStream = new FileOutputStream(targetFile)) {
fileStream.write(content.getBytes(charsetName));
}
}
}
JAR 내 리소스에 접근하는 예시:
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
// ...
ResourcePatternResolver resourceLoader = new PathMatchingResourcePatternResolver();
Resource[] resources = resourceLoader.getResources("classpath:data/config/application_data.json");
if (resources.length > 0) {
Resource configResource = resources[0];
try (InputStream dataStream = configResource.getInputStream()) {
String jsonData = ResourceReadWriteUtil.readFromStream(dataStream, StandardCharsets.UTF_8.name());
System.out.println("설정 데이터: " + jsonData);
} catch (IOException e) {
System.err.println("데이터 로딩 중 오류 발생: " + e.getMessage());
}
}
새로운 모듈 추가
새로운 기능을 담당하는 모듈을 생성하고 기존 애플리케이션에 통합하는 과정입니다.
- 부모
pom.xml에 모듈 추가: 프로젝트의 루트pom.xml파일의<modules>섹션에 새 모듈의 이름을 추가하여 Maven이 해당 모듈을 인식하도록 합니다. - 기존 애플리케이션 모듈에 의존성 추가: 새 모듈의 기능을 사용해야 하는 기존 백엔드(예:
admin) 모듈의pom.xml에 새 모듈에 대한 의존성을 추가합니다.<dependency> <groupId>com.example</groupId> <artifactId>new-module-name</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> - 컴포넌트 스캔 설정: 만약 새 모듈의 패키지 경로가 기존 애플리케이션의 기본 스캔 경로(예:
com.example) 외부에 있다면,@SpringBootApplication어노테이션에scanBasePackages속성을 추가하여 해당 패키지를 명시적으로 스캔하도록 설정해야 합니다. 또한, 새 모듈에 Mapper 인터페이스가 있다면@MapperScan어노테이션도 함께 설정합니다.import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }, scanBasePackages = { "com.example.main", "com.example.newmodule" }) @MapperScan("com.example.newmodule.mapper") // 새 모듈의 Mapper 패키지 public class ApplicationMain { public static void main(String[] args) { SpringApplication.run(ApplicationMain.class, args); } } - 캐시 정리: 변경 사항이 적용되지 않는 경우, IDE의 캐시를 정리하고 Maven 프로젝트를 다시 로드합니다.
MyBatis-Plus 연동
MyBatis-Plus는 MyBatis를 확장하여 CRUD 작업을 간소화하는 프레임워크입니다. 프로젝트에 이미 MyBatis가 설정되어 있다면, MyBatis-Plus 의존성을 추가하고 관련 설정을 적용하여 쉽게 연동할 수 있습니다.
개발 중 핫 리로드(Hot Reload)
대부분의 스프링 부트 프로젝트는 개발 편의를 위해 개발 도구(DevTools) 모듈을 포함하여 핫 리로드 기능을 지원합니다. 코드를 수정한 후 IDE에서 재컴파일(예: Ctrl+Shift+F9)하면 변경 사항이 자동으로 반영됩니다.
커스텀 예외 처리 구현
애플리케이션에서 일관된 방식으로 예외를 처리하기 위해 커스텀 예외 클래스와 에러 코드 열거형을 정의할 수 있습니다.
1. 응답 코드 열거형 정의:
package com.example.common.api;
/**
* API 응답 코드를 정의하는 열거형
*/
public enum ApiResponseCode {
OK(2000, "성공적으로 처리되었습니다."),
BAD_REQUEST(4000, "잘못된 요청 파라미터입니다."),
UNAUTHORIZED(4010, "인증되지 않은 사용자입니다."),
ACCESS_DENIED(4030, "접근 권한이 없습니다."),
RESOURCE_NOT_FOUND(4040, "요청한 리소스를 찾을 수 없습니다."),
INTERNAL_SERVER_ERROR(5000, "서버 내부 오류가 발생했습니다."),
PROCESSING_FAILED(5001, "요청 처리 중 오류가 발생했습니다.");
private final int code;
private final String message;
ApiResponseCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
2. 커스텀 비즈니스 예외 클래스 수정:
기존 비즈니스 예외 클래스에 ApiResponseCode를 인자로 받는 생성자를 추가하여 예외 발생 시 코드와 메시지를 함께 전달할 수 있도록 합니다.
package com.example.common.exception;
import com.example.common.api.ApiResponseCode;
public class BusinessException extends RuntimeException {
private final int errorCode;
private final String errorMessage;
public BusinessException(ApiResponseCode apiResponseCode) {
super(apiResponseCode.getMessage()); // RuntimeException의 message로 설정
this.errorCode = apiResponseCode.getCode();
this.errorMessage = apiResponseCode.getMessage();
}
public BusinessException(ApiResponseCode apiResponseCode, String customMessage) {
super(customMessage);
this.errorCode = apiResponseCode.getCode();
this.errorMessage = customMessage;
}
// ... 다른 생성자 및 getter 메서드 ...
public int getErrorCode() {
return errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
}
3. 예외 사용 예시:
import com.example.common.api.ApiResponseCode;
import com.example.common.exception.BusinessException;
// ...
if (user == null) {
throw new BusinessException(ApiResponseCode.RESOURCE_NOT_FOUND, "사용자를 찾을 수 없습니다.");
}
// ...
로그 파일 경로 문제 해결
애플리케이션 시작 시 로그 파일 경로를 찾지 못하는 오류가 발생한다면, 로그 설정 파일(예: logback-spring.xml)에서 로그 경로를 상대 경로로 지정합니다. 이렇게 하면 JAR 파일 실행 시 로그가 JAR 파일과 같은 디렉터리에 생성됩니다.
<property name="LOG_HOME" value="./logs" />
단위 테스트(Unit Test)
스프링 부트 애플리케이션의 단위 테스트는 spring-boot-starter-test 의존성을 통해 쉽게 설정할 수 있습니다.
1. pom.xml 의존성 추가:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
2. 테스트 클래스 작성 예시:
package com.example.test.config;
import com.example.ApplicationMain;
import com.example.common.utils.io.ResourceReadWriteUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test; // JUnit 5 사용
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
/**
* 애플리케이션 설정 데이터 로딩 테스트
*/
@ExtendWith(SpringExtension.class) // JUnit 5에서 Spring 테스트 컨텍스트를 사용하기 위한 어노테이션
@SpringBootTest(classes = {ApplicationMain.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class ApplicationConfigTest {
static class SampleConfigData {
public String configName;
public int value;
// Getter, Setter 생략
}
@Test
void testConfigDataLoading() throws IOException {
String filePath = "src/test/resources/sample_config.json"; // 테스트 리소스 경로
// 테스트용 JSON 파일 생성 (실제 테스트 시에는 이미 존재하는 파일을 사용하거나, 임시 파일을 생성)
// new File(filePath).createNewFile();
// ResourceReadWriteUtil.writeToFile(new File(filePath), "{\"configName\":\"TestConfig\",\"value\":123}", StandardCharsets.UTF_8.name());
String jsonContent = ResourceReadWriteUtil.readFromFile(new File(filePath), StandardCharsets.UTF_8.name());
ObjectMapper mapper = new ObjectMapper();
SampleConfigData config = mapper.readValue(jsonContent, SampleConfigData.class);
System.out.println("Config Name: " + config.configName);
System.out.println("Config Value: " + config.value);
// 여기에서 Assertions.assertEquals 등으로 검증 로직 추가
}
}
페이징 쿼리
스프링 부트와 MyBatis/JPA를 사용하면 페이징 처리를 쉽게 구현할 수 있습니다. 예를 들어, MyBatis-Plus나 PageHelper와 같은 라이브러리는 쿼리 실행 전에 페이징 조건을 자동으로 추가하는 기능을 제공합니다. 백엔드에서 startPage()와 같은 메서드를 호출하여 페이징을 적용하고, 프론트엔드에서는 pageNum, pageSize와 같은 파라미터를 전달하여 페이징 쿼리를 수행합니다.
로그 레벨 설정
애플리케이션의 로그 수준은 application.properties 또는 application.yml에서 설정할 수 있습니다. 기본적으로 DEBUG 레벨로 설정되어 있어 상세한 SQL 실행 로그 등이 출력될 수 있습니다. 운영 환경에서는 INFO, WARN, ERROR 등으로 로그 레벨을 높여 불필요한 로그 출력을 줄이는 것이 좋습니다.
logging:
level:
root: INFO
org.springframework.web: INFO
com.example: DEBUG # 특정 패키지는 DEBUG 유지 가능
이미지 업로드 및 표시
표시 원리: 스프링 부트 애플리케이션에서 업로드된 이미지를 표시하는 방식은 정적 리소스 매핑을 활용합니다. 특정 URL 경로(예: /images)를 실제 서버의 파일 시스템 경로(예: /app/uploads/images)에 매핑하여, 프론트엔드에서 해당 URL로 이미지를 요청하면 서버가 정적 파일을 제공합니다.
상대 경로로 저장: 이미지가 애플리케이션 배포 경로 내에 저장되도록 설정하여, 배포 환경에 독립적으로 경로를 관리할 수 있습니다. 예를 들어, application.yml에서 파일 업로드 경로를 상대 경로로 지정합니다.
file:
upload-path: ./uploaded_files
사용자 등록 기능 활성화
사용자 등록 기능은 일반적으로 애플리케이션 설정에서 활성화/비활성화할 수 있습니다. 데이터베이스에 저장된 설정 값이나 설정 파일에서 관련 옵션을 true로 변경해야 합니다. 등록 페이지는 기본적으로 사용자 ID, 비밀번호, 보안 코드 등을 요구하며, 필요한 경우 RegisterRequest(또는 유사한 이름) 클래스에 필드를 추가하고 AuthService.register()(또는 유사한 이름) 메서드를 구현하여 커스텀 등록 로직을 추가할 수 있습니다.
Redis 캐시 키 접두사 설정
여러 프로젝트가 동일한 Redis 서버를 공유하는 경우, 캐시 키 충돌을 방지하기 위해 각 프로젝트별로 고유한 키 접두사를 설정하는 것이 좋습니다. 스프링 데이터 Redis에서는 application.yml 파일에 다음과 같이 설정할 수 있습니다.
spring:
redis:
cache:
key-prefix: project-a:
프론트엔드 개발 팁
백엔드 API 접근 주소 변경
프론트엔드 애플리케이션에서 백엔드 API에 접근하는 주소는 환경 설정 파일(예: .env.development, .env.production)에 정의됩니다. 개발 및 배포 환경에 맞춰 적절한 백엔드 URL과 포트 번호를 설정합니다.
# .env.development
VUE_APP_BASE_API = 'http://localhost:8081/api'
# .env.production
VUE_APP_BASE_API = 'http://your-production-domain.com/api'
프론트엔드 배포(Bundling)
프론트엔드 애플리케이션을 배포할 때는 프로덕션 환경 설정을 사용하여 번들링합니다. 예를 들어 Vue CLI 프로젝트에서는 npm run build 명령어를 실행하기 전에 .env.production 파일의 설정을 확인합니다.
배포 후 페이지 새로고침 시 404 오류
Vue.js, React와 같은 SPA(Single Page Application)는 클라이언트 측 라우팅을 사용하기 때문에, 특정 서브 경로에서 페이지를 새로고침하면 웹 서버가 해당 경로의 실제 파일을 찾지 못해 404 오류를 반환할 수 있습니다. 이를 해결하려면 웹 서버(Nginx, Apache 등) 설정에서 모든 요청을 index.html로 리다이렉트하도록 설정해야 합니다.
Nginx 설정 예시:
server {
listen 80;
server_name your-domain.com;
location / {
root /path/to/your/frontend/dist; # 프론트엔드 빌드 결과물의 경로
index index.html;
try_files $uri $uri/ /index.html; # 핵심 설정
}
}
코드 생성 도구로 생성된 코드 수정
자동 코드 생성 도구를 사용했을 때, 생성된 프론트엔드 코드에 Vue.js 버전 호환성이나 권장 사항에 맞지 않는 부분이 있을 수 있습니다. 예를 들어:
:visible.sync대신v-model사용 권장.- 버튼 컴포넌트의 크기 속성(예:
mini)은 최신 버전에서small등으로 변경될 수 있습니다. - Vue 2의
slot-scope="scope"는 Vue 3에서#default="scope"로 변경됩니다.
글로벌 컴포넌트 등록
자주 사용되는 컴포넌트는 전역으로 등록하여 각 페이지에서 별도로 임포트하지 않고 사용할 수 있습니다. 이는 main.js(또는 유사한 엔트리 파일)에서 Vue.component()를 사용하여 수행합니다.
프론트엔드 페이징 쿼리
프론트엔드에서 백엔드로 페이징 요청을 보낼 때는 pageNum (페이지 번호)과 pageSize (페이지당 항목 수)와 같은 파라미터를 쿼리 스트링에 포함하여 전달합니다.
// 사용자 목록 조회 API 예시
export function fetchUserList(params) {
return request({
url: `/api/users?pageNum=${params.pageNum}&pageSize=${params.pageSize}`,
method: 'get'
});
}
이전 페이지로 이동
사용자가 이전 페이지로 돌아갈 수 있도록 UI에 "뒤로 가기" 기능을 추가할 수 있습니다. 이는 Vue Router의 this.$router.back() 메서드를 통해 간단히 구현할 수 있습니다.
<template>
<el-tooltip content="이전 페이지로 돌아가기" effect="dark" placement="bottom">
<div class="nav-item hover-effect" @click="navigateToPrevious">
<svg-icon icon-class="arrow-left" style="width: 20px; height: 20px;" />
</div>
</el-tooltip>
</template>
<script>
export default {
methods: {
navigateToPrevious() {
this.$router.back();
}
}
}
</script>
모듈 로딩 오류 해결
프론트엔드 개발 시 모듈을 찾을 수 없다는 오류가 발생한다면, 주로 컴포넌트나 라우트 정의에서 경로 문제가 원인일 수 있습니다. 특히 require를 사용하여 동적으로 컴포넌트를 로딩하는 경우, 경로가 올바른지 확인합니다.
// 예시: 라우트 정의에서 컴포넌트 로딩 경로 수정
{
path: 'user-details/:id',
component: (resolve) => require(['@/views/user/UserDetails'], resolve),
meta: { title: '사용자 상세' }
}
// 또는 동적 임포트 함수에서
function loadView(view) {
return () => import(`@/views/${view}.vue`)
}
메뉴에 커스텀 아이콘 사용
UI 메뉴에 커스텀 SVG 아이콘을 사용하려면, 해당 아이콘 파일을 프로젝트의 적절한 SVG 아이콘 디렉터리(예: src/assets/icons/svg)에 추가해야 합니다. 이 디렉터리에 추가된 아이콘은 빌드 시스템에 의해 처리되어 애플리케이션 내에서 사용할 수 있게 됩니다.
홈페이지나 특정 고정 메뉴 아이콘은 라우터 설정 파일(예: router/index.js)에 직접 정의되어 있을 수 있으므로, 해당 파일을 수정해야 합니다.
애플리케이션 로고 교체
애플리케이션의 로고 이미지는 일반적으로 src/assets 폴더 내에 위치합니다. 새로운 로고 이미지 파일로 기존 파일을 덮어쓰거나, 새로운 로고를 추가하고 관련 컴포넌트(예: Sidebar/index.vue)에서 경로를 업데이트하여 교체할 수 있습니다.
내비게이션 바(Navbar)에 추가 아이콘 표시
내비게이션 바에 추가 기능을 위한 아이콘을 표시하려면, SVG 아이콘 파일을 적절한 경로(예: src/assets/icons/svg)에 추가한 후, 내비게이션 바 컴포넌트(예: components/Navbar/index.vue)의 템플릿에 <svg-icon> 컴포넌트를 사용하여 배치합니다.
Vuex 스토어를 통한 상태 관리
Vuex 스토어를 사용하여 애플리케이션의 전역 상태를 관리할 수 있습니다. 이는 여러 컴포넌트 간에 데이터를 공유하고 일관된 상태를 유지하는 데 유용합니다.
1. Vuex 모듈 생성 (예: taskStatus.js):
// src/store/modules/taskStatus.js
const taskStatus = {
state: {
// 진행 중인 작업 목록
activeTasks: [],
// 완료된 작업 수
completedTaskCount: 0,
},
mutations: {
SET_ACTIVE_TASKS: (state, tasks) => {
state.activeTasks = tasks;
},
SET_COMPLETED_TASK_COUNT: (state, count) => {
state.completedTaskCount = count;
},
},
actions: {
// 진행 중인 작업 목록 업데이트 액션
updateActiveTasks({ commit }, data) {
commit('SET_ACTIVE_TASKS', data);
},
// 완료된 작업 수 증가 액션
incrementCompletedTaskCount({ commit, state }) {
commit('SET_COMPLETED_TASK_COUNT', state.completedTaskCount + 1);
},
// 완료된 작업 수 설정 액션
setCompletedTaskCount({ commit }, count) {
commit('SET_COMPLETED_TASK_COUNT', count);
},
},
getters: {
getActiveTasks: (state) => state.activeTasks,
getCompletedTaskCount: (state) => state.completedTaskCount,
}
};
export default taskStatus;
2. index.js에 모듈 등록:
// src/store/index.js
import Vue from 'vue';
import Vuex from 'vuex';
import taskStatus from './modules/taskStatus';
import user from './modules/user'; // 기존 사용자 모듈
Vue.use(Vuex);
const store = new Vuex.Store({
modules: {
taskStatus,
user,
},
// ... 기타 설정 ...
});
export default store;
3. 컴포넌트에서 상태 업데이트 (예: App.vue):
// App.vue 예시
import { mapActions, mapGetters } from 'vuex';
import { fetchCurrentlyRunningTasks } from '@/api/task'; // API 호출 예시
export default {
// ...
methods: {
...mapActions('taskStatus', ['updateActiveTasks', 'incrementCompletedTaskCount']),
// 현재 진행 중인 작업 목록을 가져와 스토어 업데이트
loadActiveTasks() {
fetchCurrentlyRunningTasks().then(response => {
this.updateActiveTasks(response.data);
}).catch(error => {
console.error("Failed to load active tasks:", error);
});
},
// 작업 완료 시 호출하여 카운트 증가
onTaskFinished() {
this.incrementCompletedTaskCount();
}
},
mounted() {
this.loadActiveTasks(); // 초기 로드
// WebSocket 메시지 수신 시 this.loadActiveTasks() 또는 this.onTaskFinished() 호출
}
}
4. 컴포넌트에서 상태 사용 (예: Navbar.vue):
// Navbar.vue 예시
import { mapGetters } from 'vuex';
export default {
// ...
computed: {
...mapGetters('taskStatus', ['getActiveTasks', 'getCompletedTaskCount']),
// 컴포넌트에서 쉽게 접근할 수 있는 속성으로 매핑
runningTasks() {
return this.getActiveTasks;
},
finishedTaskTotal() {
return this.getCompletedTaskCount;
}
},
// ...
}
5. 템플릿에서 상태 값 사용:
<div class="nav-item hover-effect position-relative" @click="fetchActiveTasks">
<svg-icon icon-class="gear" style="width: 21px;height: 21px;"/>
<div class="badge position-absolute" v-if="finishedTaskTotal > 0">{{ finishedTaskTotal }}</div>
</div>
Vuex 스토어에 사용자 정보 저장
사용자 로그인 후 사용자 이름과 같은 정보를 Vuex 스토어에 저장하여 애플리케이션 전반에서 쉽게 접근할 수 있습니다.
1. 사용자 모듈에 상태 추가:
// src/store/modules/user.js 예시
const user = {
state: {
token: null,
username: '', // 사용자 이름
// ...
},
mutations: {
SET_USERNAME: (state, name) => {
state.username = name;
},
// ...
},
actions: {
// 로그인 액션 내에서 사용자 이름을 설정
login({ commit }, userInfo) {
return new Promise((resolve, reject) => {
// API 호출 및 성공 시
commit('SET_TOKEN', userInfo.token);
commit('SET_USERNAME', userInfo.name);
// ...
resolve();
});
},
// ...
},
getters: {
username: state => state.username,
token: state => state.token,
// ...
}
};
export default user;
2. 컴포넌트에서 사용자 정보 사용:
// 컴포넌트 예시
import { mapGetters } from 'vuex';
export default {
computed: {
...mapGetters([
'username', // 스토어의 `username` getter를 이 컴포넌트의 `this.username`으로 매핑
'token'
]),
},
mounted() {
console.log('현재 로그인한 사용자:', this.username);
}
}
this.username을 통해 스토어에 저장된 사용자 이름에 접근할 수 있으며, 스토어의 값이 변경되면 컴포넌트에서도 자동으로 업데이트됩니다.