안녕하세요 상훈입니다.

Nuxt.js 프로젝트를 생성하고 구동시키려는데, 아래와 같은 오류가 출력되면서 정상동작하지 않았습니다.

Error:0308010C:digital envelope routines::unsupported

그래서 확인을 해보니 Node 명령어를 변경하여 처리하라고 작성되어있더군요. 
결과는 실패. 

그래서 Node.js의 버전 자체를 낮추어 구동시키는 방법이 있다고 합니다.

현재 버전과 바꿀 버전은 아래와 같습니다.

현재는 18.12.1 버전을 사용하고있습니다. 
(2022-11-11 기준 안정(최신) 버전)

16버전에서만 Nuxt가 정상적으로 돌아간다는 말도 있었거든요.

처음에는 14버전도 깔아서 구동해보니 정상동작하였습니다. 
아무튼 16버전으로 깔도록하겠습니다.

 

아래의 사이트에서 

 

 

Releases · coreybutler/nvm-windows

A node.js version management utility for Windows. Ironically written in Go. - coreybutler/nvm-windows

github.com

 

nvm-setup.zip (윈도우 기준) 을 다운로드 + 설치 해주세요.

그리고 vscode등을 재실행해줍니다. 

$ nvm

nvm 명령어를 쳤을 때 출력

이렇게 되면 정상적으로 설치가된것입니다.

그리고 다운로드 > 리스트 확인 > 항목 사용을 눌러주세요.

// 16.13.0 버전 다운로드
nvm install 16.13.0

// 리스트 확인
nvm list  

// 16버전 사용하기
nvm use 16.13.0

설치가 완료되었고, 사용처리까지 하셨으면 이제 프로젝트 구동해주세요.

감사합니다.

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

 

 

 

 

 

[JavaScript] NVM 설치하기(for Windows)

NVM이란? NVM은 Node Version Manager의 약자이고 여러 버전의 Node.js 설치 및 버전 변경을 관리해주는 도구입니다. NVM을 사용하면 상황에 맞게 Node.js를 원하는 버전으로 설치하거나 변경할 수 있습니다.

kjchoi.co.kr

 

반응형

안녕하세요 상훈입니다.

 

Vue.js 3 + Vue Router 를 사용하여 페이지를 넘기고 params에 원하는 값을 전달하는 경우를 포스팅하도록 하겠습니다.

List 화면. Title 항목을 클릭하면, 해당 객체를 가지고 상세페이지로 이동하도록 설정

 

이렇게 컨텐츠 한개가 객체(Object)로 적용하겠습니다.

item : {
	title: 'asdasdasdas',
	content: 'asgasfasf',
	date: new Date()
}

이런식으로 객체는 구성되어있습니다.

string만 데이터를 전달하는것과 거의 동일합니다.

 

1. 데이터를 전달할 Vue파일

//List.vue
<template>
<div v-for="(item, index) in itemList" class="w-full flex">
        <div class="w-8 h-7">{{ index++ }}</div>
        <div class="flex-1" @click="moveToDetail(item)">{{ item.title }}</div>
        <div class="w-32 h-7">{{ item.date }}</div>
</div>
</template>

<script>
...
 methods: {
    moveToDetail(item) {
      this.$router.push({
        name: "ContentDetail",
        params: { item: JSON.stringify(item) },
      });
    },
  },
 ...
 </script>

title을 클릭하면 item 객체를 전달하는 것으로 선언하였습니다.

저기서 item 객체를 문자화 하였는데요.
이유인즉슨, 파라미터를 넘겨줄 때 그냥 넘기게되면 이도저도 안되는 [Object object] 가 넘어옵니다. 
그래서 stringify로 문자화한 후에 내용을 넘깁니다.

 

2. route.js (/route/index.js) -브릿지 역할

 //routes
 
 {
    path: "/ContentDetail/:item",
    name: "ContentDetail",
    component: () => import("../components/Contents/ContentDetail.vue"),
    props: true,
  },
1. path 속성에 :item이라는 key의 이름으로 값을 전달할 것을 지정.
2. props: true  > props를 true로 설정하여 props를 전달할 수 있게 설정하였습니다.

 

3. 전달받을 Vue 파일

<template>
<div>
      <div"> Title: {{ paramObj.title }} </div>
      <div> Content: {{ paramObj.content }} </div>
      <div> date: {{ paramObj.date }} </div>
</div>
</template>

<script>
...

props: {
    item: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      paramObj: {},
    };
  },
  mounted() {
    this.paramObj = JSON.parse(this.$route.params.item);
  },
 
 ...
</script>
1.props로 params를 전달받을 것을 명시
2. item 키를 가진 문자를 받아올 것으로 명시 (JSON.parse를 통해 객체화 실시예정)
3. item 객체를 할당할 ref 선언(data)
4. 컴포넌트가 마운트 완료되고, params 로 받아온 객체를 할당.

 

 

List > Detail 화면
querystring 내용

 

짧지만 긴 포스팅을 마치겠습니다.

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다. 

모달팝업을 만드는 방법을 포스팅하려고 합니다.

추가적으로 바깥 영역을 클릭했을 때 모달이 사라지게 하고 싶습니다.

이렇게 말이죠

1) Modal Show 버튼을 클릭 시 Modal Popup 출력.
2) 바깥영역, close 버튼을 클릭 시 Modal Popup 숨김.

이 두 가지 동작이 가능하게 하려고합니다.

// App.vue > 모달 창을 포함하고 있는 메인 뷰
<template>
  <div>
    <button type="button" @click="showModal">Modal Show</button>
    <ModalView
      v-show="showStatus"
      v-model="showStatus"
      @closeModal="closeModal"
    />
  </div>
</template>

<script>
import ModalView from "./Modal.vue";

export default {
  components: {
    ModalView,
  },
  data() {
    return {
      showStatus: false,
    };
  },
  methods: {
    showModal() {
      this.showStatus = true;
    },
    closeModal() {
      this.showStatus = false;
    },
  },
};
</script>

showStatus 라는 ref 를 기본 값으로 false 로 놓고, true가 되었을 때만 팝업이 뜨도록 처리하려고 합니다.

이벤트 핸들러가 호출하는 메서드로 showModal() 과 closeModal() 을 생성하였습니다.

직관적으로 show는 show를, close는 close를 작성하여 shoStatus 의 값을 true/false로 변경하겠습니다.

 

// Modal.vue
<template>
  <div class="modal-view" @click="closeModal">
    <div class="modal-view-area" @click.stop="">
      <h2 class="modal-text-header">Modal View</h2>
      <div class="block-content"></div>
      <div class="modal-bottom">
        <button class="modal-btn" @click="closeModal">Close</button>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: { showStatus: Boolean },
  methods: {
    closeModal() {
      this.$emit("closeModal");
    },
  },
};
</script>

props로 showStatus를 전달받아 바깥영역, 닫기 버튼을 클릭하면 $emit을 통해 closeModal 이벤트를 발생시킵니다. 

그리고 App.vue에서 closeModal 메서드를 호출하게 되어 모달 팝업을 숨김처리합니다.

 

다른건 다 그렇다고 치고, 코드를 자세히 살펴보시면, 특별한 처리를 하지 않았는데, 모달창의 영역을 클릭하였을 때는 팝업이 안닫히지만, 그 외의 영역을 클릭하였을 때는 닫히는 것을 볼 수 있습니다.

처음에는 css의 z-index 를 설정하면 영역 컨트롤이 가능한줄 알고 열심히 z-index를 설정했었죠.

그러나 vue.js 공식 문서에 숨겨져있는 한 내용을 확인하게되었습니다.

 

바로 이 부분입니다.

<div class="modal-view" @click="closeModal">
    <div class="modal-view-area" @click.stop="">

바로 @click.stop 입니다. 이게 바로 핵심.

@click.stop을 작성해준 부분의 영역은 클릭이벤트 전부를 멈추게 만듭니다. 

추가적으로 button에 @click 이벤트 핸들러를 제공한것처럼 명시하지 않는다면 말이죠.

 

이렇게 작성해주시면,  모달 영역을 클릭해도 닫히지 않는 모습을 보여줍니다. 

 

이상입니다.

 

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다. 

뷰에서 props를 계속 내려주고 또 내려주고 끝없이 내려주면 정신적으로 피폐해질 수 있습니다.

물론 간단한 토이 프로젝트일 때에는 굳이 Vuex 혹은 Reactive 를 사용할 필요가 없습니다.

그러나 어느 정도 규모가 점점 커질 수록, props를 관리하기가 힘들어지고, 그에 따라 오류가 쉽게 발생하게됩니다.

그 때 필요한것이 Reactive 입니다. Vuex의 기초단계기도 하지요.

 

1. Reactive.vue
2. component1.vue
3. component2.vue
4. store.js

이렇게 4가지 파일을 준비하겠습니다. (component2 는 값의 변화가 동시에 적용되는지 확인용입니다.)

이런 형태로 짜도록 하겠습니다.

1. Reactive.vue

//Reactive.vue == Main vue
<template>
  <div>
    <h2>Reactive</h2>
    <br />
    <h3>Component01</h3>
    <Component01 />
    <br />
    <h3>Component02</h3>
    <Component02 />
  </div>
</template>
<script>
import Component01 from "./Component01.vue";
import Component02 from "./Component02.vue";

export default {
  components: {
    Component01,
    Component02,
  },
};
</script>

 

 

2. component1.vue

// Component01.vue
<template>
  <div>
    <h2>this is comp1</h2>
    <p>{{ store.count }}</p>
    <button type="button" @click="store.increment()">+</button>
  </div>
</template>
<script>
import { store } from "./store.js";
export default {
  data() {
    return {
      store,
    };
  },
};
</script>

 

3. component2.vue

<template>
  <div>
    <h2>this is comp2</h2>
    <p>{{ store.count }}</p>
    <button type="button" @click="store.decrement()">-</button>
  </div>
</template>
<script>
import { store } from "./store.js";
export default {
  data() {
    return {
      store,
    };
  },
};
</script>

 

4. store.js

import { reactive } from 'vue';

export const store = reactive({
    count: 0,
    increment() {
        this.count++;
    },
    decrement() {
        this.count--;
    }
})

 

 

각 컴포넌트에서 props로 내려주는것 없이  > 불편함에서 해방

바로 store.jsimport 해주시고 store 객체 내의 값을 사용합니다.

1) store.count
2) store.increment()
3) store.decrement()

 

보시다시피 Reactive.vue (Main vue) 에서 props로 내려주는 것 하나 없이 컴포넌트 선언만으로도 가져와서 사용하였습니다! 🤲

 

이상입니다.

 

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

안녕하세요 상훈입니다. 아주 예전에 이와같은 내용을 작성하긴했었던 것 같은데, 아예 뷰를 안쓰다보니 완전히 까먹어서.. 다시 공부해서 다시 글을 작성하게 되었습니다!

사전지식은 다음과 같습니다.

1. 컴포넌트의 관계를 이해한다.
2. 자식 컴포넌트 → 부모 컴포넌트로 데이터를 전달하고싶다.

 

Vue.js Todolist 를 구현할 때 Add의 한 부분을 담당하고 있습니다.

 

1. 부모 컴포넌트 Parent Component

//부모컴포넌트 : Todo.vue
<template> 
  <div>
    <h3>Greeting!</h3>
    <TodoInput @addNewTodo="checknew" />
  </div>
</template>
<script>
import TodoInput from "./TodoInput.vue";

export default {
  components: {
    TodoInput,
  },
  methods: {
    checknew(newItem) {
      this.newTodo = newItem;
    },
  },
};
</script>

 

2. 자식 컴포넌트 Child Component

//자식 컴포넌트 : TodoInput.vue
<template>
  <div>
    <input
      type="text"
      maxlength="20"
      v-model="newItem"
      @keyup.enter="addTodo"
    />
    <button type="button" @click="addTodo">Add</button>
  </div>
</template>
<script>
export default {
  data() {
    return {
      newItem: "",
    };
  },
  methods: {
    addTodo() {
      this.$emit("addNewTodo", this.newItem);
    },
  },
};
</script>

3. 위 코드를 보고서 이해가 잘 안되셨을 때 봐주세요.

핵심은 $emit@이벤트 핸들러입니다.

자식 컴포넌트에서 
1) addTodo 라는 메서드를 실행합니다.
2) $emit을 통해 addNewTodo 라는 Props로 전달합니다.

부모 컴포넌트에서
1) addNewTodo 라는 Props가 있습니다.
2) 그리곤 newTodo 라는 메서드로 값을 받아옵니다.

부모 > 자식의 관계는 전부 Props 입니다.

addNewTodo 의 props 명으로 이벤트를 지정해놓는 것이죠

그런데, 자식에서 이벤트가 발생 → $emit으로 메서드 newTodo 를 콜백함수처럼 받아온다고 생각하면, 이해하시기 수월해집니다. 

 

Vanila Javascript 

//부모 컴포넌트
parent (function (ret) {
    //자식 컴포넌트에서 보낸 값을 ret으로 받아옴
    console.log(ret);
});

물론 parent라는 함수를 선언해주지 않았기 때문에 위 함수는 오류지만, 요점은 콜백함수처럼 생각하면된다는 겁니다.

반응형

안녕하세요, 상훈입니다.

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

 

ReactNative + Expo, 구글 혹은 카카오 로그인을 구현하려고 하는데, 안드로이드 연동을 위해선

sha-1 인증서 디지털 지문

 이 필요합니다.

현상태

저렇게 SHA-1 인증서 디지털 지문이 필요한데요, 어떻게 하면 얻을 수 있는지 포스팅하도록 하겠습니다.

 

빌드를 해야한다.

1. 로그인
2. 빌드
3. 빌드 완료 확인, 내용 체크
4. SHA-1 지문 입력

순서로 소개하도록하겠습니다.

 

1. 로그인

eas 를 전역(-g)으로 설치

npm install -g eas-cli

로그인

eas login

정상적으로 로그인되었을 때

 

로그인이 되었지만, 혹시 모르니 확인을 한 번 더 해주기.

eas whoami

로그인 확인완료

로그인이 정상적으로 되었음을 확인할 수 있습니다.

 

2. 빌드 시작

 빌드 환경설정을 해줍니다.

eas build:configure

빌드 과정

저는 All 을 선택하였습니다. 궁극적으로 android뿐 아니라 ios도 해줄 것이기 때문이죠.

eas.json

그러면 eas.json이 생성된것을 확인하실 수 있습니다.

 

이제 BUILD를 해봅시다

eas build --platform all

빌드 과정

 

3. 빌드 완료 확인, 내용 체크

성공적으로 빌드되었다면, 확인을 해봅시다

eas build:list

빌드 리스트

첫 빌드가 된 앱의 형태입니다! 

 1.0.0 으로 따끈따끈한 최신 녀석이죠 (RAW FISH 급)

 

이제 EXPO 로 이동하여 확인해보시죠

 

Expo

Expo is an open-source platform for making universal native apps for Android, iOS, and the web with JavaScript and React.

expo.dev

 

DashBoard > Configure > Credentials 를 클릭해보시면

프로젝트의 이름

아까 빌드할 때 만들어놓았던 내용이 이곳에 출력됩니다.   클릭해서 들어가주세요

 

SHA-1 Certificate Fingerprint

라는 항목 아래에 써져있는것을 확인하실 수 있습니다. 

해당 내용을 구글의 경우

입력해주세요!

 

이상입니다.

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

안녕하세요, 상훈입니다.

 

리액트 네이티브(React Native)를 통해 expo를 실행할 때 이렇게 오류가 출력되었습니다.

 

No Android connected device found, and no emulators could be started automatically.

안드로이드 디바이스와 연결된 에뮬레이터가 없어서 그렇습니다.

일단 안드로이드 스튜디오를 깔아줍시다.

오류 안내 문구에서 

Please connect a device or create an emulator (https://docs.expo.dev/workflow/android-studio-emulator).

이렇게 작성된 내용이 있을 텐데, 해당 링크를 클릭해서 들어가시고, 다운로드 해주세요.

 

Expo Android Download Link btn
Android Studio Download btn

 

설치 후 안드로이드 스튜디오를 시작하면 아래와 같은 화면을 보실 수 있습니다.

 

안드로이드 스튜디오를 여는게 아니라 에뮬레이터만 띄우고 싶으시다면, [ Virtual Device Manager] 를 눌러서 설치해주세요. (오른쪽에 점3개 눌러주세요)

virtual device manager click info

 

설치가 다 된 모습은 아래와 같습니다. 

 

이상입니다.

안드로이드 디바이스 환경설정 방법은 흐름대로 따라가시면 쉽게 가능합니다.

 

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

 

반응형

안녕하세요 상훈입니다!

구글 애드센스가 끊긴지도.... 어언 2주가 되어가네요! 하하 빌어먹게도 멋진 녀석 같으니라고^^7

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

 

자바스크립트로 데이터를 받아왔는데, 숫자만 출력하고 싶습니다. 어떻게 해야할까요?

let str = "안녕하세요1239입니다.";

str = replaceAll(/[^0-9]/g, "");

로 간단하게 처리가 가능합니다.

 

사용 방법은 아래와 같습니다.

str.replaceAll(없애고싶은내용, 바꿀내용);

 

사용 예시를 작성해보겠습니다!

 

숫자의 데이터가 필요한 상황인데, 애석하게도 숫자만 온게 아니라 문자가 포함된 문자열로 출력되었다는 가정입니다.

function changeLetter (str, successCallback) {
	str = str.replaceAll(/[^0-9]/g, "");
    successCallback(str); //str을 반환
}

changeLetter("안녕하세요12395", function (ret) { //성공 콜백함수와 데이터
	
    //ret이 변경된 새로운 str이 되는것이죠.
    $("#여기에작성해주세요").text(ret); //12395
    
});

결과적으로, id: 여기에작성해주세요 라는 아이디를 가진 태그의 텍스트에 숫자만 출력되는 내용이 될겁니다.

콘솔창에 작성해본 예시

이렇게 함수로 쓰면 언제든지 함수만 호출해서 꺼내올 수 있게 작성할 수 있습니다!

 

다만 이것의 문제는 문자열이라는 것에 있죠.

 

조금 더 나아가서 저 문자열을 1)숫자로 변경하고, 2) 뒤에 원을 붙여서 출력하도록 하겠습니다.

function changeLetter (str, successCallback) {
	str = str.replaceAll(/[^0-9]/g, "");
    successCallback(str);
}

changeLetter("안녕하세요12395", function (ret) { //성공 콜백함수와 데이터
	
    //ret이 변경된 새로운 str이 되는것이죠.
    ret = parseInt(ret);
	console.log(ret + "원");
});

typeof 도 함께 출력하여 숫자로 변경되었음을 확인

이렇게  parseInt 혹은 Number... 등을 이용해서 숫자로 변경하고,

출력할 때 "원" 문자까지 합쳐서 출력하는 방식을 알아보았습니다. 

 

감사합니다.

 

도움이 되셨다면 광고 한번 클릭해주세요. 블로그 운영에 큰 힘이 됩니다. 감사합니다.

반응형

+ Recent posts