묻고 답해요
156만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
github 주소 어디서 확인가능한가요?
소스코드 올라온 github 주소 어디서 확인이 가능할까요?
-
해결됨Vue js와 UI를 한번에 학습/Nuxt3 + OpenWeatherMap 으로 실시간 날씨 앱 제작
27강에서 진행이 안됩니다.
잘 따라서 했는데제대로 했는데, type오류가 나옵니다.그건 그렇다 치고 밑에 오류때문에 더이상 진행이 안됩니다.CityView가 작동안하는 이유인데 prop 문제인듯합니다.
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
안녕하세요 선생님
혹시 다음 강의도 준비 중이신가요 ? 준비 중이시라면 어떤 강의 인지 알 수 있을까요
-
해결됨카카오,구글 SNS 로그인(springboot3, vue3)
application.yml에 동일 OAuth2 제공업체의 redirect-uri를 여러 개 등록할 수 있을지 궁금합니다.
안녕하세요.application.yml에 동일 OAuth2 제공업체의 redirect-uri를 여러 개 등록할 수 있을지 궁금합니다. 현재 OAuth 제공업체에 개발 및 테스트용과 배포용으로 redirect-uri를 여러 개 등록하였습니다.해당 redirect-uri를 application.yml에 복수로 등록하여 사용할 수 있을까에 대한 의견이 궁금합니다.
-
미해결Vue 3 & Firebase 10 커뮤니티 만들기 풀스택 - "활용편" (with Pinia, Quasar, Tiptap, VueUse)
무한 스크롤링 질문
<div v-intersectionObserver="handleIntersectionObserver" class="bg-primary"></div>여기 div에 height 100px 했을때는 스크롤해서 하단에 닿이면 6개씩 잘보였는데 style 부분을 지우니까 스크롤 해서 하단에 닿였을때 나머지 게시물이 6개씩 보이는게 아니라 loadMore() 이 연속적으로 실행되어 전체가 다 보이게 됩니다 height가 0이 되면서 계속 노출이 돼서 그렇게 되는건가요?
-
미해결Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
title,content값이 비어서 저장되는데 제가 혹시 어떤 부분을 잘못 작성했는지 ㅜㅜ 알고싶습니다.
<template> <div> <h2>게시글 등록</h2> <hr class="my-4" /> <PostForm v-model.title="form.title" v-model.content="form.content" @submit.prevent="savePost" > <template #actions> <div class="pt-4"> <button type="button" class="btn btn-outline-dark me-2" @click="goPostListPage" > 목록 </button> <button class="btn btn-primary">저장</button> </div> </template> </PostForm> <!-- <form> <div class="mb-3"> <label for="title" class="form-label">제목</label> <input v-model="form.title" type="text" class="form-control" id="title" /> </div> <div class="mb-3"> <label for="content" class="form-label">내용</label> <textarea v-model="form.content" class="form-control" id="content" rows="3" ></textarea> </div> --> <!-- <div class="pt-4"> <button type="button" class="btn btn-outline-dark me-2" @click="goPostListPage" > 목록 </button> <button type="button" class="btn btn-primary" @click="goPostListPage"> 저장 </button> </div> </form>--> </div> </template> <script setup> import { useRouter } from "vue-router"; import { createPost } from "@/api/posts"; import { ref } from "vue"; import PostForm from "@/components/posts/PostForm.vue"; const router = useRouter(); const form = ref({ id: 0, title: "", content: "", createAt: Date.now(), }); const savePost = () => { try { // const data = { ...form.value, createAt: Date.now() }; createPost({ ...form.value }); goPostListPage(); // console.log("savePost data", data); } catch (err) { console.log("err", err); } }; // 목록이동 const goPostListPage = () => { router.push({ name: "PostList", }); }; </script> <style lang="scss" scoped></style> <template> <form> <div class="mb-3"> <label for="title" class="form-label">제목</label> <!-- v-model을 사용하지 않고, v-bind와 @input 이벤트를 사용하여 양방향 데이터 바인딩 --> <input :value="title" @input="$emit('update:title', $event.target.value)" type="text" class="form-control" id="title" /> </div> <div class="mb-3"> <label for="content" class="form-label">내용</label> <textarea :value="content" @input="$emit('update:content', $event.target.value)" class="form-control" id="content" rows="3" ></textarea> </div> <!-- <div class="pt-4"> <button type="button" class="btn btn-outline-dark me-2" @click="goPostListPage" > 목록 </button> <button type="button" class="btn btn-primary" @click="goPostListPage"> 저장 </button> </div> --> <slot name="actions"></slot> </form> </template> <script setup> defineProps({ title: String, content: String, }); // update:props데이터명 // 양방향 데이터 바인딩을 위해 사용 : 부모에게 내려받은 props를 업데이트 // update 접두사는 v-model과 함께 사용되는 이벤트 이름 defineEmits(["update:title", "update:content"]); </script> <style lang="scss" scoped></style>{ "posts": [ { "id": 2, "title": "제목2", "content": "내용2", "createAt": "2021-01-02" }, { "id": 3, "title": "제목3", "content": "내용3", "createAt": "2021-01-03" }, { "id": 4, "title": "제목4", "content": "내용4", "createAt": "2021-01-04" }, { "title": "제목8", "content": "내용83333333", "createAt": "2021-01-08", "id": 8 }, { "id": 9, "title": "", "content": "", "createAt": 1750817841654 }, { "id": 10, "title": "", "content": "", "createAt": 1750828553704 } ] }title,content값이 비어서 저장되는데 제가 혹시 어떤 부분을 잘못 작성했는지 ㅜㅜ 알고싶습니다.
-
미해결퀘이사(Quasar) 완벽 마스터: Vue 프론트 웹을 빠르게 만들고 싶다면! (Based Vue3)
ComboBox 관련해서 질문 드립니다.
강의에서는 emit-value 옵션을 사용하여 Text, Value로 넣은 값을 표시해주는 부분에서 Combo Box에서 선택했을떄 보여지는 값이 Value로 표시되던데 이때 선택한 값 보여주는건 Text로 보여주고 선택한 데이터를 뽑아올때 Value로 값을 가져오는 옵션이 따로 있나요?
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
안녕하세요 섹션2. 인가코드(프론트에서 발급) 부분에서 질문 있습니다.
안녕하세요 먼저 좋은 강의 정말 감사드립니다.섹션2 인가코드(프론트에서 발급) 강의와 강의 자료에서 get 요청을 통해 인가코드 전달을 한다고 설명하셨는데, 프론트엔드 코드에서는 post로 요청하고 있고, http body로 jwt 토큰을 받으려면 post로 요청해야하는게 맞는 것 같은데, 제가 잘못 이해하고 있는건지 잘못 설명하신건지 헷갈려서 질문글 남깁니다. const response = await axios.post("http://localhost:8080/member/google/doLogin", {code});
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
filterchain 구성에서 포스트맨으로 테스트시
안녕하세요 레디스 강의에 이어 잘 수강하고 있습니다!filterchain 구성에서 포스트맨으로 테스트 시에 raw password가 그대로 컨트롤러에 전달되는데, 실무에서는 (Q.1) 이렇게 하는 방식이 허용되는지 궁금합니다. (Q.2) 안된다면 어떤식으로 해결하는지 궁금하네요!
-
미해결Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
_title_like: "", 문의드려요 해당 값을 설정하면 list가 아에 안나옵니다.
<template> <div> <h2>게시글 목록</h2> <hr class="my-4" /> <form @submit.prevent> <div class="row g-3"> <div class="col"> <input v-model="params._title_like" type="text" class="form-control" /> </div> </div> </form> <hr class="my-4" /> <!-- list : row 가로 정렬 --> <div class="row g-3"> <div v-for="post in posts" :key="post.id" class="col-4"> <PostItem :title="post.title" :content="post.content" :create-at="post.createAt" @click="goPage(post.id)" ></PostItem> </div> </div> <!-- list --> <!-- 페이지네이션 --> <nav class="mt-4 d-flex justify-content-center" aria-label="Page navigation example" > <ul class="pagination"> <li class="page-item" :class="{ disabled: params._page <= 1 }"> <a class="page-link" href="#" aria-label="Previous" @click.prevent="--params._page" > <span aria-hidden="true">«</span> </a> </li> <li v-for="pageNum in pageCount" :key="pageNum" class="page-item"> <a class="page-link" href="#" @click.prevent="params._page = pageNum"> {{ pageNum }}</a > </li> <li class="page-item" :class="{ disabled: params._page >= pageCount }"> <a class="page-link" href="#" aria-label="Next" @click.prevent="++params._page" > <span aria-hidden="true">»</span> </a> </li> </ul> </nav> <hr class="my-4" /> <AppCard v-if="posts.length > 0"> <PostDetailView :id="posts[0].id" /> </AppCard> <!-- <router-view></router-view> --> <!-- <PostDetailView></PostDetailView> --> </div> </template> <script setup> import PostItem from "@/components/posts/PostItem.vue"; import PostDetailView from "./PostDetailView.vue"; import AppCard from "@/components/AppCard.vue"; import { computed, ref, watchEffect } from "vue"; import { getPosts } from "@/api/posts"; import { useRouter } from "vue-router"; const router = useRouter(); const posts = ref([]); const params = ref({ _sort: "createAt", _order: "desc", _page: 1, _limit: 3, _title_like: "", }); // 페이지네이션 데이터 const totalCount = ref(0); const pageCount = computed(() => Math.ceil(totalCount.value / params.value._limit), ); const fetchPosts = async () => { try { const { data, headers } = await getPosts(params.value); console.log("params.value", params.value); console.log("결과:", data); posts.value = data; // console.log("posts.value", posts.value); totalCount.value = headers["x-total-count"]; } catch (err) { console.log("err", err); } // getPosts() // .then(res => { // console.log("res", res); // }) // .catch(err => { // console.log("err", err); // }); }; watchEffect(fetchPosts); // fetchPosts(); const goPage = id => { // router.push(`posts/${id}`); router.push({ name: "PostDetail", params: { id, }, }); }; </script> <style lang="scss" scoped></style>기본값을 "" 을 주니 안나오는데 코드에 문제가 있을까요 ㅜㅜ?
-
미해결Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
@click.prevent="params._page = pageNum"> 에 .value를 안쓰는 이유가 궁금합니다.
ref로 선언한 객체(params)는 일반적으로 params.value._limit처럼 .value로 접근해야 하는데,왜 <a @click.prevent="params._page = pageNum">와 같은 템플릿 안에서는 .value 없이도 작동하는건가요?그런데 위처럼 .value를 사용하면 오히려"Cannot set properties of undefined (setting '_page')" 에러가 나는 이유는 무엇인가요?
-
미해결Vue.js 중급 강좌 - 웹앱 제작으로 배워보는 Vue.js, ES6, Vuex
Chrome 개발자 모드 확장이 안됨
Vue 3 시작하기 강의에서 알려주신 legacy 버전 설치해도 개발자 모드에서 vue 탭이 안보이고 아래와 같은 에러가 발생합니다.
-
미해결Vue 3 & Firebase 10 커뮤니티 만들기 풀스택 - "활용편" (with Pinia, Quasar, Tiptap, VueUse)
짐코딩님..! unplugin-vue-router/vite 적용 최근방식 부탁드령요 ㅜㅜ
unplugin-vue-router/vite를 다운받고 공식문서 참고해서 설정했는데 pages의 index.vue가 오토라우팅이 되지않습니다. router.index.jsimport { defineRouter } from '#q-app/wrappers' import { createRouter, createMemoryHistory, createWebHistory, createWebHashHistory } from 'vue-router/auto' import routes from './routes' /* * If not building with SSR mode, you can * directly export the Router instantiation; * * The function below can be async too; either use * async/await or return a Promise which resolves * with the Router instance. */ export default defineRouter(function (/* { store, ssrContext } */) { const createHistory = process.env.SERVER ? createMemoryHistory : (process.env.VUE_ROUTER_MODE === 'history' ? createWebHistory : createWebHashHistory) const Router = createRouter({ scrollBehavior: () => ({ left: 0, top: 0 }), routes, // Leave this as is and make changes in quasar.conf.js instead! // quasar.conf.js -> build -> vueRouterMode // quasar.conf.js -> build -> publicPath history: createHistory(process.env.VUE_ROUTER_BASE) }) return Router }) quasar.config.js// Configuration for your app // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file import VueRouter from 'unplugin-vue-router/vite' import { defineConfig } from '#q-app/wrappers' export default defineConfig((/* ctx */) => { return { // https://v2.quasar.dev/quasar-cli-vite/prefetch-feature // preFetch: true, // app boot file (/src/boot) // --> boot files are part of "main.js" // https://v2.quasar.dev/quasar-cli-vite/boot-files boot: [ ], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#css css: [ 'app.scss' ], // https://github.com/quasarframework/quasar/tree/dev/extras extras: [ // 'ionicons-v4', // 'mdi-v7', // 'fontawesome-v6', // 'eva-icons', // 'themify', // 'line-awesome', // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both! 'roboto-font', // optional, you are not bound to it 'material-icons', // optional, you are not bound to it ], // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#build build: { target: { browser: [ 'es2022', 'firefox115', 'chrome115', 'safari14' ], node: 'node20' }, vueRouterMode: 'hash', // available values: 'hash', 'history' // vueRouterBase, // vueDevtools, // vueOptionsAPI: false, // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup // publicPath: '/', // analyze: true, // env: {}, // rawDefine: {} // ignorePublicFolder: true, // minify: false, // polyfillModulePreload: true, // distDir // extendViteConf (viteConf) {}, // viteVuePluginOptions: {}, vitePlugins: [ ['vite-plugin-checker', { eslint: { lintCommand: 'eslint -c ./eslint.config.js "./src*/**/*.{js,mjs,cjs,vue}"', useFlatConfig: true } }, { server: false }, ], // 자동 라우터 플러그인 사용하기 VueRouter({ }), ] }, // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#devserver devServer: { // https: true, open: true // opens browser window automatically }, // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#framework framework: { config: {}, // iconSet: 'material-icons', // Quasar icon set // lang: 'en-US', // Quasar language pack // For special cases outside of where the auto-import strategy can have an impact // (like functional components as one of the examples), // you can manually specify Quasar components/directives to be available everywhere: // // components: [], // directives: [], // Quasar plugins plugins: [] }, // animations: 'all', // --- includes all animations // https://v2.quasar.dev/options/animations animations: [], // https://v2.quasar.dev/quasar-cli-vite/quasar-config-file#sourcefiles // sourceFiles: { // rootComponent: 'src/App.vue', // router: 'src/router/index', // store: 'src/store/index', // pwaRegisterServiceWorker: 'src-pwa/register-service-worker', // pwaServiceWorker: 'src-pwa/custom-service-worker', // pwaManifestFile: 'src-pwa/manifest.json', // electronMain: 'src-electron/electron-main', // electronPreload: 'src-electron/electron-preload' // bexManifestFile: 'src-bex/manifest.json // }, // https://v2.quasar.dev/quasar-cli-vite/developing-ssr/configuring-ssr ssr: { prodPort: 3000, // The default port that the production server should use // (gets superseded if process.env.PORT is specified at runtime) middlewares: [ 'render' // keep this as last one ], // extendPackageJson (json) {}, // extendSSRWebserverConf (esbuildConf) {}, // manualStoreSerialization: true, // manualStoreSsrContextInjection: true, // manualStoreHydration: true, // manualPostHydrationTrigger: true, pwa: false // pwaOfflineHtmlFilename: 'offline.html', // do NOT use index.html as name! // pwaExtendGenerateSWOptions (cfg) {}, // pwaExtendInjectManifestOptions (cfg) {} }, // https://v2.quasar.dev/quasar-cli-vite/developing-pwa/configuring-pwa pwa: { workboxMode: 'GenerateSW' // 'GenerateSW' or 'InjectManifest' // swFilename: 'sw.js', // manifestFilename: 'manifest.json', // extendManifestJson (json) {}, // useCredentialsForManifestTag: true, // injectPwaMetaTags: false, // extendPWACustomSWConf (esbuildConf) {}, // extendGenerateSWOptions (cfg) {}, // extendInjectManifestOptions (cfg) {} }, // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-cordova-apps/configuring-cordova cordova: { // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing }, // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-capacitor-apps/configuring-capacitor capacitor: { hideSplashscreen: true }, // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/configuring-electron electron: { // extendElectronMainConf (esbuildConf) {}, // extendElectronPreloadConf (esbuildConf) {}, // extendPackageJson (json) {}, // Electron preload scripts (if any) from /src-electron, WITHOUT file extension preloadScripts: [ 'electron-preload' ], // specify the debugging port to use for the Electron app when running in development mode inspectPort: 5858, bundler: 'packager', // 'packager' or 'builder' packager: { // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options // OS X / Mac App Store // appBundleId: '', // appCategoryType: '', // osxSign: '', // protocol: 'myapp://path', // Windows only // win32metadata: { ... } }, builder: { // https://www.electron.build/configuration/configuration appId: 'vue3-quasar-firebase-app' } }, // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex bex: { // extendBexScriptsConf (esbuildConf) {}, // extendBexManifestJson (json) {}, /** * The list of extra scripts (js/ts) not in your bex manifest that you want to * compile and use in your browser extension. Maybe dynamic use them? * * Each entry in the list should be a relative filename to /src-bex/ * * @example [ 'my-script.ts', 'sub-folder/my-other-script.js' ] */ extraScripts: [] } } }) 기존의 라우터를 냅두면 MainLayout 으로 가고 주석처리해버리면 빈화면입니다. const routes = [ { path: '/', component: () => import('layouts/MainLayout.vue'), children: [ { path: '', component: () => import('pages/IndexPage.vue') } ] }, // Always leave this as last one, // but you can also remove it { path: '/:catchAll(.*)*', component: () => import('pages/ErrorNotFound.vue') } ] export default routes
-
미해결호돌맨의 요절복통 개발쇼 (SpringBoot, Vue.JS, AWS)
깃헙 collaboator 초대 관련
당연히 구글링 해보셨져? 원하는 결과를 못찾으셨나요? 어떤 검색어를 입력했는지 알려주세문제가 발생한 코드(프로젝트)를 Github에 올리시고 링크를 알려주세요.안녕하세요 호돌맨님.덕분에 강의 잘 듣고있습니다.깃헙 collaboator로 초대받을 수 있을까요?깃헙 아이디는 dudfo6425@gmail.com 입니다!감사합니다.
-
미해결Vue 3 & Firebase 10 커뮤니티 만들기 풀스택 - "활용편" (with Pinia, Quasar, Tiptap, VueUse)
Quasar를 강의 버전 그대로 맞추면 실행할 때 에러가 발생해서, 다른 버전만 맞추니 잘 작동합니다.
현재 Quasar는 강의에서 안내한 버전 그대로 맞추면 실행 시 에러가 발생해서, 핵심 버전만 맞추니 정상적으로 실행됩니다.혹시 에러 생기시는 분 참고하세요~
-
해결됨카카오,구글 SNS 로그인(springboot3, vue3)
프론트엔드에서 Auth.js를 사용했을 때, 질문 있습니다.
안녕하세요. 좋은 품질의 강의를 제작해주셔서 감사합니다. 프론트엔드 부분을 vue.js에서 Next.js로 변경하여 프로젝트를 진행하고 있습니다. 해당 과정에서 막힘이 있어 질문을 드립니다. Next.js를 기반으로 Auth.js 라이브러리를 사용하여 프론트엔드 소셜 로그인을 구현하고 있습니다.소셜 로그인 흐름을 다음과 같이 생각하고 있습니다.1. 유저가 소셜 로그인 버튼을 누른다. 2. 프론트엔드에서 해당 소셜 로그인 화면을 리다이렉트 시킨다. 3. 유저는 소셜 로그인을 진행한다. 4. 소셜 로그인 성공 시, 프론트엔드 서버는 인증 코드를 소셜 서버로부터 받은 후, 백엔드로 소셜 로그인 API를 인증 코드 첨부하여 요청한다. 5. 백엔드 서버에서 인증 코드를 가지고 액세스 토큰 발급, 엑세스 토큰으로 유저 정보를 받아서 JWT를 만들어 프론트엔드로 반환해준다. 하지만 다음 피드백을 받았습니다. "Auth.js를 사용하면 소셜 서버로부터 인가코드를 직접 받아올 수 없어 백엔드 서버로 인가코드 요청을 할 수 없다."위 의견이 맞다면, 백엔드 서버에서 소셜 로그인 전 과정을 진행하고 JWT 값만 프론트엔드로 반환하는 방법 밖에 없는걸까요? 강의에서 사용되지 않은 기술에 대해서 질문하여 죄송합니다.감사합니다.
-
미해결카카오,구글 SNS 로그인(springboot3, vue3)
[질문] 소셜 로그인한 적이 없다면 회원가입 시키기
안녕하세요. 강의 감사히 잘 듣고 있습니다.강의를 듣다가 궁금한 점이 생겨 질문 드리고 싶습니다. 강의 16분쯤에 회원가입이 되어있지 않다면 회원가입한다고 말씀하셨습니다.이때 socialId 로 회원가입 여부를 판단하신다고 하셨는데, 왜 email 로는 하지 않으셨는지 궁금합니다. email 도 unique 제약조건을 걸었기 때문에 email 도 가능하다고 생각이 들었는데 강사님의 의견은 어떠한지 여쭤보고 싶습니다. 질문 읽어주셔서 감사합니다.
-
미해결최신 Vue 3 완벽 가이드: 프로젝트 설정 & 스펙 총정리
npm install -D tailwindcss postcss autoprefixer 의 버전을 알고싶습니다.
tailwindcss의 버전이 4.x로 변경됨에 따라 강의 내용의 일부인npx tailwindcss init -p 시 오류가 발생하는 것이 확인되었습니다.최대한 강의를 따라가기 위하여, 일단 제 임의로 3.4.3 버전으로 다시 설치를 한 상황인데요.강사님께서 npm install -D tailwindcss postcss autiprefixer 를 하셨을 때 설치되는 버전을 알고싶습니다.
-
해결됨Vue3 완벽 마스터: 기초부터 실전까지 - "실전편"
중첩된 컴포넌트 문제
안녕하세요! 이번 강의 보면서 포트폴리오 만드는데 질문이 있습니다컴포넌트 A 에서 컴포넌트 B 에서 컴포넌트 C D 이런순으로 있습니다.근데 A 와 B 까지는 잘 되는데 C 로 넘어가는데 데이터가 넘어가지 않습니다 반응형(?) 안되어서 ref 선언도 다 하고요혹시나 프로바이더나 인젝 문제 인가 해서 전부다 해봤는데 여전히 그대로 데이터가 넘어가지 않습니다.근데 새로고침하면 넘어간 상태로 있습니다. 컴포넌트가 총 4개라서 중앙 집중식 상태 관리는 안해놨거든요 해야되는건가요? 규모는 아주 소규모라서 ai 한테도 다 물어보고 이랬는데도 미해결이라 힌트 좀 얻고자 글 남겨봅니다.
-
해결됨Vue js와 UI를 한번에 학습/Nuxt3 + OpenWeatherMap 으로 실시간 날씨 앱 제작
6강에서 css가 안되서 진행이 안됩니다!!!
flex를 사용했는데, 가로 정렬이 되지 않습니다. 배경도 적용이 안되고 있어요. 터미널 로그에 보면 Using default Tailwind CSS file 로그가 없습니다. 이거 무슨 문제인가요?