목록Development Experience/Web (12)
KorSA
부모 컴포넌트에서 자식 컴포넌트로 함수를 전달하고 싶어서 Function Props에 대해 찾아보았다. https://maxkim-j.github.io/posts/function-props-vuejs/ 김맥스 블로그 | function props는 Vue의 안티패턴일까? React에서 상위 컴포넌트의 state를 하위 컴포넌트에서 업데이트하기 위해서는 해당 state를 갱신하는 함수를 상위 컴포넌트에서 함께 props로 넘겨야 합니다. 이 방식이 Vue에서도 가능할지 궁금했습 maxkim-j.github.io 이 글을 보면 Vue.js에서 Function Props를 사용하는 게 안티 패턴인지에 대해 의견이 분분한 듯 하다. 간략히 요약해보면, React의 경우 데이터 전달이 단방향(부모->자식)이라 역..
Vue나 React, 혹은 그냥 Javascript로 개발할 때 콘솔로 객체를 찍어야할 상황이 종종 찾아온다. var obj = {"id": 1, "name": "korsa"} console.log(obj); 하지만 객체를 바로 찍으면 내부 데이터 대신 [object Object] 로 표시된다. 출력> [object Object] 이 때 객체를 JSON.stringify() 로 감싸주면 내부 데이터를 볼 수 있다. console.log(JSON.stringify(obj)); 출력> {"id": 1, "name": "korsa"}
Vue 3 에서 Vuex를 Store 역할로 사용할 때 헷갈리는 부분이 Mutation과 Action의 차이였다. 우선, 가장 큰 차이점은 비동기 연산을 하느냐 마느냐 하는 것이다. Vuex Store는 크게 4가지 속성이 있다. state, getters, mutations, 그리고 actions. state는 말 그대로 현재 상태를 담고 있는 변수이다. getters도 말 그대로 state의 값을 얻어오는 역할이다. mutations은 state를 변경할 수 있게 해주는 유일한 녀석이다. '변이' 라는 뜻 그대로 state의 상태를 변화시키는 것이다. 이쯤이면 필요한 건 다 있는 것 같은데 actions라는 속성이 하나 더 있다. actions는 state와 관련한 비동기 연산을 담당한다. 그리고 비..
Vue Composition API를 사용하면서 store 데이터를 watch 하는 방법이 손에 익지 않아 기록으로 남겨본다.. 우선.. 내가 구현하고 싶던 기능은 사용자가 웹사이트의 메뉴를 변경할 때 메뉴목록의 하이라이트 지점도 바뀌게 하는 것이었다. 이를 위해선 사용자와 인터랙션하는 Component와 메뉴목록을 관리하는 Component 간의 데이터 전달이 필요했다. Vue에서 상태 관리 등 전역으로 다루어야 할 데이터는 vuex의 store 기능을 사용하기에 store의 데이터를 조작하여 Component들 간의 데이터 전달을 하고자 하였다. 작업은 다음의 3 단계로 진행하였다. 1. Store에 변수 생성 // @/module/common.js import { createNamespacedHel..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/bXyg04/btrMyhHfmwz/8PtSt2KfkJoKlKorBAHic0/img.png)
여러 HTML 태그를 겹치게 (overlay) 하고 싶을 땐 CSS의 position 속성의 aboslute, relative 사용을 고려해보자 회사에서 vue3용 open-layers 라이브러리를 사용하여 지도를 표출하고 그 위에 버튼을 구현해야 하는 작업이 있었다. 버튼이당 그냥 태그 두 개를 나열하면 화면이 겹치지 않고 map이 표출된 영역 아래에 button이 표출된다. display: flex; 를 이용하는 방법이 있지 않을까 해서 검색해보았지만 찾지 못했다. 아마 flex는 레이아웃을 컨트롤하는 게 목적이어서 그러지 않을까 싶었다. 결국 찾은 방법은 태그의 position속성을 absolute로 지정하면 된다. 버튼이당 이렇게 하면 지도에 겹쳐져서 버튼이 표시된다. 그런데 또 하나의 난관에 부..
![](http://i1.daumcdn.net/thumb/C150x150/?fname=https://blog.kakaocdn.net/dn/n3l3G/btrKejOO9jU/jfTlkwOiMcKQCGQvBxDKmk/img.png)
이번에 시작한 Vue 프로젝트에서는 각 항목별로 제목을 달아준다. 그 제목을 좀 예쁘게 표시해보고자 아래와 같은 디자인을 구상해보았다. 구글느님의 도움을 받아 canvas 태그를 사용하여 저런 사각형을 그릴 수 있었다. 헌데.. 보는 기기에 따라 달라지는 canvas의 width, height가 마음에 걸렸다. 그래서 pixel로 width, height를 고정하는 대신 vw, vh를 사용해보았다. (참고로, vw랑 vh가 적용되려면 css에 {dsiplay: block; }을 넣어주어야 한다. 헌데 막상 모니터 크기에 따라 이상한 모양으로 변하곤 했다. 이렇게 잘 나오게 맞춰 놓아도 모니터 크기가 달라지면 위처럼 이상하게 변해버렸다. vw,vh 대신 %를 사용해보아도 마찬가지였다. 어느 모니터에서든 자..
JAVA에서 Null을 처리하기 위한 방법으로 Optional을 사용한다. Null 대신 Optional 이라는 객체를 반환함으로써 NullPointerException 이 발생하는 걸 방지하기 위해서이다. 회사에서 개발을 하면서 Optional.of() 함수를 썼는데 NullPointerException이 발생했다. 코드를 보니 아래와 같은 느낌으로 작성되어 있어서 of()의 전달인자로 null이 전달된 것이었다. Object myName = null; Optional.of((String)myName); Optional.of()를 호출하려면 null이 아닌 값만 전달되어야 한다. 만일 null이 "될수도" 있는 값이 전달된다면 Optional.ofNullable()을 호출해야 한다. Object myN..
# JAVA 객체 -> gRPC Proto 객체 JAVA 객체를 gRPC proto 객체로 컨버팅을 할 때 ObjectMapper 클래스를 사용할 수 있다. 이 ObjectMapper로 JAVA 객체를 Serialize하여 JSON String을 만들고 다시 이 JSON String을 gRPC proto 객체로 해석하는 것이다. MyJavaObj javaObj = new MyJavaObj(); ObjectMapper mapper = new ObjectMapper(); # JAVA 객체 -> JSON String json = mapper.writer().writeValueAsString(javaObj); # gRPC proto 객체의 builder를 얻어옴 Builder builder = MyGrpcPro..
Spring-Web-Application 개발을 진행하면서 회사 공통으로 쓰고 있는 JAR 파일을 첨부하게 되었다. 이 JAR 파일에는 우리 개발팀이 공통으로 쓰는 모듈들이 들어가있는데 주로 DB, gRPC, Util 등의 기능들이 포함되어 있다. 공통된 기능을 내가 따로 개발할 필요없이 이미 만들어진 것을 가져다 씀으로써 편리함과 DRY(Don't Repeat Yourself) 를 얻었지만 예상 못한 문제가 있었다. 바로 MyBatis를 포함한 프로젝트는 어딘가에 Mapper 클래스가 존재해야 한다는 것이었다. 헐? 지금 개발하고 있는 Spring-Web-Application은 DB 기능을 사용하지 않는데? 이 Application은 사용자에게 REST API 인터페이스를 제공하고 요청이 들어오면 다른..
postman으로 POST 요청을 보낼 때 받는 쪽 Controller에서 DTO가 null인 상황이 나왔다. 처음엔 통신 쪽에 문제가 있나 싶었는데 결국 원인은 postman으로 DTO를 만들어서 보낼 때 JSON 형식이 제대로 되어있지 않았던 것이다. 클래스 명으로 묶을 필요가 없었는데 나는 클래스명으로 데이터를 한번 더 묶은 게 잘못된 형식의 원인이었다. { "id": 1, "title": "mi", "content": "con" } 위와 같이 보내면 JSON 타입으로 잘 변환되는데 { "MyDTO": { "id": 1, "title": "mi", "content": "con" } } 이렇게 감싸버려서 문제가 발생했었다.