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

안녕하세요 상훈입니다.

✔ 환경

Nuxt.js 3 에서 npm을 이용하여 pinia를 설치하는데 바로 오류가 출력되었습니다.

에러문구

code ERESOLVE
ERESOLVE could not resolve
while resolving: undefined@undefined
....

 

✔ 해결방법부터...!

//package.json

"overrides": {
    "vue": "latest"
  },

이에 해당하는 내용을 추가해주시고, npm 을 이용하여 pinia재설치해주시면 됩니다!

설치 성공!

 

✔ 서사

이번엔 Nuxt.js 3 에서 store 를 사용해보고자 pinia를 사용하게 되었습니다. 기존 Vue.js3 프로젝트에서는 그냥 vueStore를 사용했었는데, 그때 알게된 store 대체 라이브러리 PINIA🍈이번에는 사용해보자, 라고 생각해서 설치를 시작해보았습니다.

 

그리고 등장하게된 위의 에러.

 

예전에도 그렇고 이것과 유사하게 생긴 에러가 자주 등장하였었는데, 해결을 못하고 프로젝트를 지우곤 했었습니다 😢

그런데 우연찮게 Pinia 공식 문서에서 이에 대한 문구가 살짝 있는게 보이더라구요? (뭐지.. 다른데도 있나?)

 

감동😢

pinia 공식 문서

 

 

 

Pinia 🍍

Intuitive, type safe, light and flexible Store for Vue

pinia.vuejs.org

반응형

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

안녕하세요 상훈입니다.

✔ 목표

Nuxt.js 3 - Vue.js3 에서 routing 하기 (페이지 전환)

 

✔ 환경

Nuxt.js3, Vue.js3

 

✔ 하는방법(결론) - 결론부터 말하기

// app.vue
<template>
  <div>
    <div class="header-area">
      <NuxtLink to="/">Main</NuxtLink>
      <NuxtLink to="/login">Login</NuxtLink> 
      <NuxtLink to="/register">Register</NuxtLink>
    </div>
    <NuxtPage />
  </div>
</template>

/app.vue (루트 경로) 에서 NuxtLinkNuxtPage를 사용하기.

 

// /pages/index.vue
<template>
  <div>
    this is index view from pages
  </div>
</template>

/pages/index.vue 라는 파일이 있을 때 app.vue의 NuxtPage 가 /pages/index.vue 가 되는 것 입니다.

root 경로 확인

 

 

✔ Vue.js3 와 Nuxt.js 의 차이점

일반 Vue 프로젝트에서는 

1) main.js - route 사용 선언
2) App.vue - RouteLink, RouteView 로 작성

반면에 Nuxt 에서는 조금 다르더라구요.

처음에는 NuxtPage 말고  Nuxt  태그만 작성했다가 페이지 출력이 되지 않아서 왜 자꾸 안되지??? (여러 기술 블로그를 염탐했을 때) 하다가,
아래의 Nuxt.js3 강의를 올려주신 익숙하신 Vue 유튜버 링크(맨 아래 링크 첨부)에 들어가 빠르게 감아서 NuxtLink 부분만 보고 고치게되었습니다.

 

✔ 조금 더 나아가기 🚀

그렇다면 /pages/directory/directory/... 이런식으로 하위 폴더가 있을 때는 어떻게 해야할지 잠깐 생각해보았고,

Nuxt 프로젝트 특유의 경로 자동 감지를 생각하게 되어, 간단하게 구현하였습니다.

/pages/inside/insidePage.vue
/app.vue

이렇게 슬래쉬로 하위 디렉터리 구분을 할 수 있었습니다. 

 

😎 마치며 

왜 이런 간단한 것 하나조차 Vue.js 프로젝트와 달라서 이렇게 애를 먹이는 것인지,,,
하나씩 그래서 설정하고 확인하고... 라우팅까지 신경쓰면서 살고 있네요.
기존에는 1분 걸릴게 Nuxt로 하니 10분도 넘게 찾고 있었네요.

어제는 프로젝트 만들고 띄우지도 못해서ㅋㅋㅋㅋ 지웠다가 새로운 프로젝트 생성하고 난리였습니다.

 

친숙한 얼굴의 형님. (어두운 밤에 보면 무서운 상)

 

이상입니다.

 

반응형

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

안녕하세요 상훈입니다.

 Vue.js3 composition AP(scirpt setup) 에서 버튼(button)을 클릭 시 원하는 링크를 클립보드에 복사가 되게하는 기능을 구현하려고 합니다. (Optional 도 가능합니다! - 문서 참조 부탁드립니다)

 

✅ 바쁘신 분들을 위한 결과만! 

npm i vue-clipboard3

1) npm으로 위 vue-clipboard3 를 설치해주세요.
2) 아래의 코드를 사용해주시면 됩니다! 
3) 저 자세한건 npm 링크를 남겨놓도록 하겠습니다.

<script>
import useClipboard from 'vue-clipboard3'
import {ref} from 'vue'

const text = ref('안녕하세요?') //복사할 내용
const { toClipboard } = useClipboard()

// 버튼클릭 (@click="copy")
const copy = async () => {
  try {
    await toClipboard(text.value) //복사할 내용을 text라는 ref로 선언하였으므로.
  } catch (e) {
    console.error(e)
  }
}
</script>

1) reactive value(ref) 로 text 값을 선언 (변경할 수 있게 input으로 v-model 처리 가능)
2) useClipboard 함수를 toClipboard 상수에 할당
3) toClipboard 내 파라미터로 text 값을 넣어준다.
4) 복사 완료!

링크버튼(왼쪽)
복사내용

 

 

vue-clipboard3

Easily copy to clipboard with Vue 3. Latest version: 2.0.0, last published: 10 months ago. Start using vue-clipboard3 in your project by running `npm i vue-clipboard3`. There are 41 other projects in the npm registry using vue-clipboard3.

www.npmjs.com


 

✅ 구현하게 된 배경?

저는 공유링크 복사 기능을 만들고 싶어서 해당 라이브러리를 사용하게 되었습니다.

링크버튼(왼쪽)

버튼을 클릭하게 되면 원하는 링크의 주소를 클라이언트의 클립보드에 저장되게요.

 

1. 처음에는 JavaScript 의  document.exacCommand() 

를 사용하려고 했습니다. 그런데 해당 기능이 동작하지 않더라구요.
+ mdn 에서 depercated, 조만간 권장되지 않는다고 써져있었기에 사용하기에 불편하다는 인식이 생겼습니다.

https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand

 

그래서 Javascript 말고, React.js의 클립보드 라이브러리처럼,
Vue의 라이브러리가 있을 것 같다? 라는 생각에 Vue.js 라이브러리를 검색하던 와중

 

2. vue-clipboard2 를 찾게되었습니다.  > 그런데 요것도...문제가..

저는 Vue.js3Compositon API 혹은 Optional 를 사용하는데, 해당 내용에는 Vue.js2 에 대한 기술만 되어있는겁니다.

vue2에 대한 기술만 되어있음.

그래서 더 검색해보아서 vue-clipboard3를 찾아 사용하게 되었습니다.

 

제가 작성해놓은 내용은 Vue.js3 - compositionAPI 인데요, 만약 Optional 를 사용하시는 분이시라면, 아래의 링크로 들어가서 NPM 에서 작성해놓은 가이드를 확인해주시기 바랍니다.

 

vue-clipboard3

Easily copy to clipboard with Vue 3. Latest version: 2.0.0, last published: 10 months ago. Start using vue-clipboard3 in your project by running `npm i vue-clipboard3`. There are 41 other projects in the npm registry using vue-clipboard3.

www.npmjs.com

 

 

 

vue-clipboard2

A Vuejs2 & Vuejs3 binding for clipboard.js. Latest version: 0.3.3, last published: a year ago. Start using vue-clipboard2 in your project by running `npm i vue-clipboard2`. There are 554 other projects in the npm registry using vue-clipboard2.

www.npmjs.com

 

반응형

[2023.01.07 의 기록]

안녕하세요 상훈입니다.

 

✅ 에러 발생 환경

1) Node.js : 18.13.0
2) Vue.js : @vue/cli 4.5.15

Vue.js3 프로젝트에서 프로젝트를 git에서 pull 받아 npm i 를 통해  package.json 내부 내용을 다운로드 하였을 때 발생한 오류입니다.

npm ERR! code ERESOLVE
npm ERR! ERESOLVE could not resolve npm ERR!
npm ERR! While resolving: @vue/eslint-config-standard@6.1.0
npm ERR! Found: eslint-plugin-vue@8.7.1
npm ERR! node_modules/eslint-plugin-vue
npm ERR! dev eslint-plugin-vue@"^8.0.3" from the root project
npm ERR! npm ERR! Could not resolve dependency:
npm ERR! peer eslint-plugin-vue@"^7.0.0" from @vue/eslint-config-standard@6.1.0
npm ERR! node_modules/@vue/eslint-config-standard
npm ERR! dev @vue/eslint-config-standard@"^6.1.0" from the root project
npm ERR! npm ERR! Conflicting peer dependency: eslint-plugin-vue@7.20.0
npm ERR! node_modules/eslint-plugin-vue
npm ERR! peer eslint-plugin-vue@"^7.0.0" from @vue/eslint-config-standard@6.1.0
npm ERR! node_modules/@vue/eslint-config-standard
npm ERR! dev @vue/eslint-config-standard@"^6.1.0" from the root project
npm ERR! npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

에러 내용

✅ 에러 해결

npm에서 설명한 내용처럼,
eslint-plugin-vue 의 버전이 npm resolve를 할 때 충돌한 것 같아 eslint의 버전을 7.20.0으로 낮추었습니다.

(왜 7.20.0 으로 바꾸었는지는 아래에서 설명하도록 하겠습니다.)

[ package.json > devDependencies > eslint-plugin-vue 항목 변경]

package.json

그리고 이제  npm i 

이게 정답이 될지는 모르겠습니다. 
왜냐하면 최신 버전의 node.js 에서 추가된 기능 혹은 호환성이 존재하니까요.
( 사실 많은 버전을 낮추는게 아니라 그렇게 걸리지는 않습니다.)

만약, npm i 를 하였는데, 저처럼 audit fix 문구가 뜨신다면 해당 명령어를 진행하셔도 무방합니다. 

프로젝트를 정상적으로 돌려보았는데, 확인 부탁드립니다.

 

 


✅ Why eslint-plugin-vue 7.20.0 ??

기존에 버전은 8.0.3 이었습니다. 

그리고 기존에는 npm i -f / peer-deep~ 을 통해 무시하거나 강제로 설치해서 사용하고 있었습니다. 

에러 문구를 처음으로 자세히 읽고....... 버전을 바꾸었다....

에러 문구에서는 peer를 7.2.0으로 설명하기에 해당 버전과 호환되는 것으로 생각하여 이 버전으로 다운 그레이드를 해보았습니다.

 

 

이곳에서 에러를 보다가 스스로 해결하긴 했고, 댓글을 남겨놓은 상태입니다. HoonHub~

 

Peer dependency conflict when creating projects using NPM 8 · Issue #24 · vuejs/eslint-config-standard

In reference to the following issue: vuejs/vue-cli#7189 It looks like this library at the default install of version 6.1.0 when using the Vue CLI has incompatible peer dependencies with the eslint-...

github.com

 

반응형

안녕하세요 상훈입니다.

Vue.js 혹은 React.js (프론트 프레임워크) 에서 카카오로그인을 구현하려고 합니다.
그런데 401 에러가 자꾸 뜨면서 코드 값을 줬는데도 토큰을 내뱉지 않더라구요. 그래서 찾아보다가 KakaoDeveloper 에서 작성된 내용중에 저와 같은 케이스가 있는지 여러 사례들을 확인할 수 있었습니다. 
+ 어떤 블로그를 보면서 진행하고있었는데, 거기서는 code만 보내는 걸로 해서 계속 나오는 에러였습니다.
+ axios를 사용하고있었는데, 지속적인 오류가 출력되어 성공하지 못하고 fetch 방식으로 변경하였습니다.


✔ 사전 환경 체크!

- Backend(Spring)을 거치지 않고 JS 프론트 프레임워크 (Vue.js, React.js) 에서 전부 처리하려고 합니다.
- 현재는 2단계(token 가져오기)입니다.
   (1단계는 code를 가져오는 단계입니다.)
- 결과 데이터로 [token_type, access_token...] 을 얻어옵니다.

 

✔ 시작!!

일단 필요요소는 다음 사진과 같습니다.

필요요소

const bodyData = {
    grant_type: 'authorization_code',
    client_id: KAKAO_REST_API_KEY,
    redirect_uri: DEV_REDIRECT_URI,
    code: payload,  // 1단계에서 발급받은 코드
    client_secret: CLIENT_ID
  }

1) client_id : 내 어플리케이션 > 앱설정 > 요약정보 > REST API 키
2) redirect_uri :  내 어플리케이션 > 제품설정 > 카카오로그인 > Redirect URI
3) code : 1단계에서 받아온 code의 값
4) client_secret :  내 어플리케이션 > 제품설정 > 카카오로그인 > 보안 > ClientSecret :  코드

 

2) redirect_uri
3) code value
4) client_secret - code


 

이렇게 body에 들어갈 내용들을 전부 가지고 REST API (비동기 통신) 으로 값을 요청하고 받아옵니다.

const bodyData = {
    grant_type: 'authorization_code',
    client_id: KAKAO_REST_API_KEY,
    redirect_uri: DEV_REDIRECT_URI,
    code: payload,
    client_secret: CLIENT_ID
}

const queryStringBody = Object.keys(bodyData)
    .map(k => encodeURIComponent(k) + '=' + encodeURI(bodyData[k]))
    .join('&')


fetch('https://kauth.kakao.com/oauth/token', {
    method: 'POST',
    headers: {
      'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
    },
    body: queryStringBody
})
.then(res => res.json())
.then((data) => {
  console.log(data)
})

 

저 같은 경우는 Vuex-store를/을 사용하여 action에서 이 내용을 처리하였습니다.

actions: {
	async KakaoLogin ({state, commit}, payload) {
	  const bodyData = { ... }
        
	  const queryStringBody = Object ...
        
	  fetch(... )
	    .then(
	      commit() // 여기서 결과 받아서 처리
	    )
	}
}

 

✔ 결과

성공적으로 값을 받았습니다

console 로 출력하도록 일단 설정하였는데요, 해당 내용은 이제 성공하였습니다.

 

 

 

Kakao Developers

카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.

developers.kakao.com

 

반응형

안녕하세요 상훈입니다.

React-Remix 프로젝트에서 개별 css 파일(스타일 적용)을 삽입하는 방법에 대해 포스팅하겠습니다.

폴더구조

app
ㄴcomponents
   ㄴNewNote.css
   ㄴNewNote.jsx
ㄴroutes
   ㄴindex.jsx
   ㄴnotes.jsx
ㄴstyles
   ㄴhome.css
   ㄴmain.css

파일 트리가 이렇게 되어져 있을 경우,

1. 기본 형태 
2. Surfacing Styles

두 가지를 작성하도록 하겠습니다.

 

1. 기본 형태 ✔

routes/index.jsx

routes/index.jsx 의 경로에서 스타일(css)을 삽입해보도록 하겠습니다.

이미지

2가지만 적용해주시면 됩니다.

1️⃣ import
2️⃣ function declare
// 1
import homeStyles from '~/styles/home.css';

// 2
export function links() {
  return [{ rel: 'stylesheet', href: homeStyles }];
}

특별히 설정해줄 것?  - 없습니다.

links 라는 함수명을 remix <Links> 에서 감지하여 하위 요소로 끌고가줍니다.

root.jsx

root.jsx 파일에서 보시면,  @remix-run/react  에서 import 한 Link 컴포넌트가 있습니다.

그리고 이 컴포넌트는 html > head 태그 내에 들어가있습니다.

 

마치 html 에서 기본적으로 삽입하는 link, script 태그들 처럼요. (이해가 딱 되셨을겁니다😎)

 

 

그러면 곧바로 2번째 surfacing styles. 시작해보겠습니다.

2. Surfacing Styles - 개별 파일에서 import 하기 ✔

NewNote : 자식 컴포넌트
NotesPage : 부모 컴포넌트

자식 컴포넌트에서 선언한 스타일을 부모컴포넌트에서도 사용하려면 다음과 같습니다.

 

✔ 자식컴포넌트-NewNote 에서 export 한 links 를 부모에서 별칭으로 import 하여 links 함수 내에 넣습니다.

✔ 그리고 links 함수에서 spread연산자로 links를 return 시켜줍니다.

 

주절주절 이야기가 길어졌지만 내용은 생각보다 매우 간단했습니다. 흥미롭고 특이한 점(Surfacing😎)도 있었고요.

이상으로 포스팅을 마치도록 하겠습니다.

 

REMIX

 

 

Remix | Styling

Styling The primary way to style in Remix (and the web) is to add a to the page. In Remix, you can add these links via the Route Module links export at route layout boundaries. When the route is active, the stylesheet is added to the page. When the route i

remix.run

 

반응형

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

React.js + remix + typeScript 에서 dataload 하는 내용을 포스팅 (이라 쓰고 기록을 한다.)을 하도록 하겠습니다.

 

<Link to="/"> </Link>

태그에 관한 내용을 반복문 map을 이용하여 목록으로 표시하려고합니다.

 

전체적인 설명은 아래 이미지있는 곳에서 하도록하겠습니다.

 

전체코드1. 

import type { LoaderFunction } from '@remix-run/node';
import { json } from '@remix-run/node'
import { Link, useLoaderData } from '@remix-run/react'
import { getLists, getPosts } from "~/models/posts.server"

//type 선언
type LoaderData = {
  posts: Awaited<ReturnType<typeof getPosts>>,
  lists: Awaited<ReturnType<typeof getLists>>
}

export const loader: LoaderFunction = async () => {
  const posts = await getPosts()
  const lists = await getLists()
  return json<LoaderData>({posts, lists})
}

export default function PostRoute () {
  const { posts,lists } = useLoaderData() as LoaderData

  return (
    <main>
      <h1>Posts!</h1>
      {posts.map((post) => (
        <li key={post.slug}>
          <Link to={post.slug} className="text-blue-600 underline">
            {post.title}
          </Link>
        </li>
      ))}
      
      {lists.map((list) => (
        <li key={list.mapper}>
          <Link to={list.mapper}>
            {list.title}
          </Link>
        </li>
      ))}
    </main>
  )
}

 

전체코드2 - data

import {prisma} from '~/db.server'
export async function getPosts () {
  const posts = [
    {
      slug: 'my-first-post',
      title: 'My First Post!'
    },
    {
      slug: 'trail-riding-with-onewheel',
      title: 'Trail Riding with Onewheel'
    }
  ]
  return posts
}

export async function getLists () {
  const lists = [
    {
      title: 'First Title',
      mapper: 'frist-title',
    },
    {
      title: 'Second Title',
      mapper: 'second-title',
    }
  ]
  return lists
}

 

기존 영상(Remix Tutorial 영상)을 참고하여 리스트를 출력해보았습니다.
(대신 하나 추가해서 따라해봤어요.)

data
내용 간단요약

Remix 에서 데이터를 컴포넌트에 불러오는 방식을 위와같이 합니다.

loader 함수는 클라이언트가 볼 수 없는 함수가 됩니다. ==> remix의 장점

 

1) useLoaderData 라는 remix 훅을 import 합니다.
2) loader 라는 이름의 함수를 생성하여 그 내부에서 데이터를 불러옵니다. (async await 부분)
3) LoaderData 라는 형식을 선언해줍니다. (type LoaderData)
4) loader 함수 내에서 LoaderData 타입으로 데이터를 반환한다고 말합니다.
(--- json 이라는 라이브러리를 import 합니다.)
5) 데이터를 호출할 때 useLoaderData 함수를 LoaderData 형식으로 선언한다고 합니다.

 

엄청 왔다갔다 했네요. 이제 다 왔습니다. 
데이터만 뿌려주면 되네요.

map 이용하여 데이터를 loop 돌리도록 하겠습니다.

 

사이드 프로젝트를 하게되어 remix, react.js, typescript를 하게되었는데... 뭔소린지 하나도 모르겠어서 열심히 공부중입니다.....

화이팅.

반응형

안녕하세요 상훈입니다.

 

Nuxt 3 (+Vue 3)Tailwindcss, typeScript로 프로젝트 생성시 정상적으로 안되는 경우가 있어 정상구동을 확인한 간단한 기초 내용을 포스팅하려고 합니다.

1) Nuxt.js 3
2) Vue.js 3
3) TailwindCss
4) TypeScript
5) Vue Router
6) Vuex
7) gh-pages

를 기본적으로 사용하려고 합니다. ( *5,6,7 은 선택사항 입니다.)

 

1. 디렉터리 구조

디렉터리 구조

 

2. nuxt.config.ts

//nuxt.config.ts

export default defineNuxtConfig({
  css: ["~/assets/css/tailwind.css"],
  postcss: {
    plugins: {
      tailwindcss: {},
      autoprefixer: {},
    },
  },
});

 

3. postcss.config.js

//postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
};

 

4. tailwind.config.js

// tailwind.config.js

module.exports = {
  content: [
    "./components/**/*.{js,vue,ts}",
    "./layouts/**/*.vue",
    "./pages/**/*.vue",
    "./plugins/**/*.{js,ts}",
    "./nuxt.config.{js,ts}",
    "./app.vue",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
};

 

5. tailwind.css (기호에 따라 파일명 설정 index.css, main.css 등)

// assets/css/tailwind.css

@tailwind base;
@tailwind components;
@tailwind utilities;

 

이렇게 설정하고 구동시 정상출력을 확인하였습니다.

정상구동 확인

 

반응형

+ Recent posts