묻고 답해요
164만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결HTML+CSS+JS 포트폴리오 실전 퍼블리싱(시즌1)
포트폴리오에서 네비게이션 메뉴를 구현하려고 하는데요..!
선생님 안녕하세요!다름이 아니라 포트폴리오에서 네비 부분에서 메뉴에서 메뉴로 이동시(home, about, work,,)에 이번 수업에서 배운 텝메뉴를 응용해서 하려고 이런식으로 마크업을 하다가 <ul> <li>home</li> <li>work</li> <li>contact</li> </ul> 문득 생각해보니 생활코딩에서 페이지간 이동을 할 때 이런식으로 a태그로 마크업 하고 또 다른 html 파일을 만들어서 이동 했었던게 생각이 나서 <ul> <li><a href="home.html">home</a></li> <li><a href="work.html">work</a></li> <li><a>home</a></li> </ul> 메뉴와 메뉴 사이에 이동을 할때는 어떻게 해야하는지 약간 혼란이 오네요.. 어떻게 하면 좋을지 여쭤보고 싶습니다.. 답변주시면 감사하겠습니다..!
-
미해결스프링 핵심 원리 - 기본편
기본편을 다시 듣는게 좋을까요?
스프링 기능들에 대한 원리와 어떨때 써야하는지는 이해가는데 막상 혼자서 코딩하려고하면 어떻게 해야할지 감이 안잡힙니다! 이럴경우 로드맵에있는 다음강의를 듣는것보다 강의를 다시 듣는게 나을까요?
-
미해결하루만에 만드는 깃허브 블로그
댓글창 관련강의
이전에 질문해주셨던 분이 계시는데 댓글만드는 강의에서 댓글창은 나오는데 마우스를 가져다되면 금지(/) 마크 생기면서 댓글작성이 안되는데 해결법 알려주시면 감사하겠습니다.
-
미해결홍정모의 따라하며 배우는 C언어
static함수 포인터 리턴
VS 2022 를 쓰는데 static으로 선언해준 변수를 포인터로 반환해줬을 때 Warning이 아니라 Error로 뜨네요. 물론 count함수, static함수 둘다 입니다. 컴파일러 차이일까요. error C2040: 'static_count': 'int *()' differs in levels of indirection from 'void ()' int ct = 0; return &ct; static int ct = 0; return &ct;
-
미해결데브옵스(DevOps)를 위한 쿠버네티스 마스터
시험에서 자주 사용되는 문법 관련 문의
PT 상에 남겨주신 시험에서 자주 사용되는 문법 https://www.notion.so/gasbugs/CKA-Kubectl-070fc3ece01848f2b8d32ae3fe310819 노션 페이지가 안열리는데 확인 부탁드려요! short url도... 만료가 되서 안되네요!
-
미해결홍정모의 따라하며 배우는 C언어
vscode external linkage
안녕하세요 교수님. vscode에서 external linkage를 시도했는데 안 돼서 구글에서 찾다가 못 찾아서 질문을 남깁니다. vscode에서는 external linkage가 안 되는 건가요? #include를 사용하는 방법으로 가능하다는 것은 알고 있습니다! 그냥 vscode에서 external linkage가 가능한지가 궁금합니다!
-
미해결페이스북 클론 - full stack 웹 개발
UserCreationForm.Meta.fields + ('email',)를 해주는 이유가 무엇인지 알고 싶습니다.
상속받는 부모 필드 전체가 필요하다면 UserCreationForm.Meta.fields 만으로 충분할것이고 명시적으로 해줄거면 ('email','name'.....) 이렇게 할텐데 이미 부모필드에 있는 이메일을 뒤에 추가하는 형식으로 fields를 선언해주는 이유가 왜인지 알고 싶습니다.
-
미해결Nuxt.js 시작하기
nuxt axios를 사용하지 않는 이유가 있을까요?
넉스트에서는 @nuxtjs/axios 사용 시this.$axios 로 axios 사용이 가능한 것으로 알고 있습니다.근데 강의에서는 axios를 사용하고 계시서요. 그렇게 하시는 것에 어떤 이슈가 있어서인지 알고 싶습니다. (_ _)
-
미해결Slack 클론 코딩[실시간 채팅 with React]
안녕하세요! mysql root 아이디 생성되서 로그인되는데 npx sequelize db:create하면 econnrefused 에러가 뜨네요
전체 메시지는 Sequelize CLI [Node: 14.17.2, CLI: 6.2.0, ORM: 6.6.5] Loaded configuration file "config/config.js". Using environment "development". ERROR: connect ECONNREFUSED 127.0.0.1:3306 입니다. db 접속도 되구, mysql 서비스 시작도 되있는 상태입니다 cmd에서 net start mysql 서비스해서 시작하는것도 확인했구요.... 뭐가 문제일까요,,,>
-
미해결Slack 클론 코딩[실시간 채팅 with React]
logout시 발생하는 순서
logout 버튼을 누르면 /api/users/logout으로 post요청이 보내진후 성공 -> revalidate함수실행 -> useSWR의 fetcher함수 실행 fetcher함수가 api/users로 axios를 실행하면 왜 false 값이 return이 되나요? api/users/logout 으로 post를 보내면 서버측에서 알아서 로그인 할 때 전달받은 정보를 false로 바꾸어주는 건가요? 답변 부탁드립니다.
-
미해결하울의 안드로이드 인스타그램 클론 만들기
사진업로드 안됨
사진을 업로드 하려고 아래 bottomnavigationview의 카메라 버튼을 누른 화면입니다. 누르면 activity_add_photo.xml 화면이 나와야 정상인거같은데 저게 끝입니다ㅜㅜ 뭐가 문제일까요 / bottomnavigationview의 다른 버튼을 누르면 색도 변하고 작동 되는 것 같은데 이미지 업로드 하는 버튼만 안됩니다. / 코드도 영상이랑 동일하게 하고 manifest 파일에 AddphotoActivity도 추가했습니다.
-
미해결PyGame 어드벤쳐 : 위니브 월드를 수복하라!
코드_질문드립니다.
002_요리하기 코드를 실행하면 1. 다음 오류가 뜨며 창이 강제종료 되는데, 어떤 것이 문제인지 잘 모르겠습니다. [] => {} 라고 바꿔도 그대로 오류가 생깁니다. 자바독이미지딕셔너리[요리] = [] TypeError: 'pygame.Surface' object does not support item assignment 2. 코드에서 어떤 부분은 예시로 '전' 으로 작은따옴표가 쓰일 때가 있고 "전"이라고 큰따옴표가 쓰일 때도 있는데 어떤 차이인지 질문드립니다.
-
미해결탄탄한 백엔드 NestJS, 기초부터 심화까지
3:44 초 질문 있습니다
서버에서 토큰 발급해서 프론트로 전달 하는걸 쿠키, local storage에 저장 한다고 하셨는데, 1. 쿠키에 저장하면 보안에 취약 하지 않나요? 2. 쿠키, local storage에 저장하는 건 프론트에서 하는건가요? 3. redis를 사용 하지 않고 해도 되나요? 4. 새로고침 해도 토큰값은 유지 되나요?
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
Test class 위치
안녕하세요. 강의 너무 잘 듣고 있습니다. 상세히 설명해주셔서 감사합니다. 한 가지만 여쭤보겠습니다. 테스트 클래스를 test 디렉토리에 만들 때, 만드시 원래 소스코드와 패키지 이름과 위계 등을 맞춰서 대응되게 만들어줘야 하는 건가요?
-
미해결취미로 해킹#2(해커의 컴퓨팅)
631포트가 열려있으면
안녕하세요.알려준 쇼단(?) 이라는 사이트에 제 개인 아이피를 넣어봤는데요.631 포트가 열려있다고 나오는데 무엇을 의미하는지 궁금합니다.
-
미해결Spring Cloud로 개발하는 마이크로서비스 애플리케이션(MSA)
인증 관련하여 질문드립니다.
좋은 강의 올려주셔서 감사합니다. 정말 도움이 많이 되고 있습니다. ㅜㅜ 인증 부분에서 궁금한 점이 있는데요, 이전에 User Service의 WebSecurity.java에서 아래 코드를 통해 전체 경로에 대해 AuthenticationFilter를 거치도록 한 것 같은데, 바로 호출이 되어서요. //인증이 된 상태에서만 통과시키도록. http.authorizeRequests() .antMatchers("/**") .hasIpAddress("{source.ip}") //source ip .and() .addFilter(getAuthenticationFilter()); gateway를 통해서 호출하는 경우에는 health_check 에도 토큰이 필요한 것 같았는데, 서비스 직접 호출 시에는 토큰이 필요하지 않은 이유가 무엇인지 궁금합니다. 추가로, actuator/** 에 대해 permitAll은 왜 따로 해주신건지도 궁금합니다. permitAll 하지 않아도 호출 하는데는 문제 없는 것 같더라구요. 감사합니다.
-
미해결모든 개발자를 위한 HTTP 웹 기본 지식
HTTP 응답 메시지
안녕하세요. 강의 잘 듣고 있습니다. 응답메시지를 보면 content-type과 데이터를 보낸다고 하는데 이게 쫌 헷갈려서요. 개발자도구에서 네트워크 탭을 보면 확인 가능한 많은 파일들 때문에저는 response시에 content-type과 html 파일, js 파일등등을 보낼줄 알았는데 데이터라고 하셔서 저 파일등은 그럼 어떻게 나타내지는건지 궁금합니다. 아니면 제가 생각하고 있는 데이터와 강사님이 말씀하신 데이터의 정의가 다른건가 싶기도 하구요. 감사합니다.
-
미해결윤재성의 만들면서 배우는 Spring MVC 5
mybatis 오류
예외 javax.servlet.ServletException: 서블릿 [appServlet]을(를) 위한 Servlet.init() 호출이 예외를 발생시켰습니다. org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.base/java.lang.Thread.run(Thread.java:834) 근본 원인 (root cause) org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSession' defined in ServletContext resource [/WEB-INF/config/servlet-context.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1726) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1434) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:925) org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716) org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591) org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530) org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170) javax.servlet.GenericServlet.init(GenericServlet.java:158) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.base/java.lang.Thread.run(Thread.java:834) 근본 원인 (root cause) org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are: PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'dataSource' threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:135) org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:79) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1722) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1434) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601) org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524) org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:925) org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:702) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:668) org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:716) org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:591) org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:530) org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:170) javax.servlet.GenericServlet.init(GenericServlet.java:158) org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542) org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:687) org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:357) org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374) org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) java.base/java.lang.Thread.run(Thread.java:834)이렇게 오류가 뜨는데 도저히 뭐가 잘못된건지 모르겠습니다..
-
미해결Vue로 Nodebird SNS 만들기
게시물 업로드가 되지 않아 질문드려요!ㅜ
4-17강의 거의다 듣다 게시물 포스트가 되지 않아 질문드려요 네트워크 창에서는 에러 500이라 뜨고, 터미널에서는 유저 이메일, 패스워드, 닉네임이 널이 되면 안된다 하는데 ValidationError [SequelizeValidationError]: notNull Violation: User.email cannot be null, notNull Violation: User.nickname cannot be null, notNull Violation: User.password cannot be null at InstanceValidator._validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:78:13) at processTicksAndRejections (internal/process/task_queues.js:93:5) at async InstanceValidator._validateAndRunHooks (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:111:7) at async InstanceValidator.validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:93:12) at async model.save (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:3890:7) at async Function.create (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:2207:12) at async C:\Users\com\vue강좌\복습\back\routes\post.js:32:21 { errors: [ ValidationErrorItem { message: 'User.email cannot be null', type: 'notNull Violation', path: 'email', value: null, origin: 'CORE', instance: [User], validatorKey: 'is_null', validatorName: null, validatorArgs: [] }, ValidationErrorItem { message: 'User.nickname cannot be null', type: 'notNull Violation', path: 'nickname', value: null, origin: 'CORE', instance: [User], validatorKey: 'is_null', validatorName: null, validatorArgs: [] }, ValidationErrorItem { message: 'User.password cannot be null', type: 'notNull Violation', path: 'password', value: null, origin: 'CORE', instance: [User], validatorKey: 'is_null', validatorName: null, validatorArgs: [] } ] } SequelizeValidationError: notNull Violation: User.email cannot be null, notNull Violation: User.nickname cannot be null, notNull Violation: User.password cannot be null at InstanceValidator._validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:78:13) at processTicksAndRejections (internal/process/task_queues.js:93:5) at async InstanceValidator._validateAndRunHooks (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:111:7) at async InstanceValidator.validate (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\instance-validator.js:93:12) at async model.save (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:3890:7) at async Function.create (C:\Users\com\vue강좌\복습\back\node_modules\sequelize\lib\model.js:2207:12) at async C:\Users\com\vue강좌\복습\back\routes\post.js:32:21 POST /post 500 21.201 ms - 1150 구글링도 해보고 찾아 봤는데 방법이 안나와 질문 드립니다. 유저 이메일 등이 잘못 설정이 된거면 도대체 어디에서 잘못된건지 만진적이 없는거 같은데 ㅜ 도와주시면 감사하겠습니다 참고로 코딩페이지 보내드리겠습니다 routes/post.js(백엔드) const express = require('express') const multer = require('multer') const path = require('path') const db = require('../models') const { isLogedIn, isNotLogedIn } = require('./middlewares') const router = express.Router() const upload = multer({ storage: multer.diskStorage({ destination(req, file, done) { done(null, 'uploads'); }, filename(req, file, done) { const ext = path.extname(file.originalname) const basename = path.basename(file.originalname, ext) done(null, basename + Date.now() + ext) } }), limit: { fileSize: 20 * 1024 * 1024} }) router.post('/images', isLogedIn, upload.array('image'), (req, res) => { console.log(req.files); res.json(req.files.map(v => v.filename)); }) router.post('/', isLogedIn, async (req, res, next) => { try { const hashtags = req.body.content.match(/#[^\s#]+/g); const newPost = await db.Post.create({ content: req.body.content, UserId: req.user.id, }); if (hashtags) { const result = await Promise.all(hashtags.map(tag => db.Hashtag.findOrCreate({ where: { name: tag.slice(1).toLowerCase() }, }))); await newPost.addHashtags(result.map(r => r[0])); } const fullPost = await db.Post.findOne({ where: { id: newPost.id }, include: [{ model: db.User, attributes: ['id', 'nickname'], }], }); return res.json(fullPost); } catch (err) { console.error(err); next(err); } }); module.exports = router PostForm.vue(프론트엔드) <template> <v-card style="margin-bottom: 20px"> <v-container> <v-form ref="form" v-model="valid" @submit.prevent="onSubmitForm"> <v-textarea outlined auto-grow clearable v-model="content" label="어떤 신기한 일이 있었나요?" :hide-details="hideDetails" :success-messages="successMessages" :success="success" :rules="[v => !!v || '내용을 입력해라']" @input="onChangeTextarea" /> <v-btn type="submit" color="green" absolute right>짹짹</v-btn> <input ref="imageInput" type="file" multiple hidden @change ="onChangeImages"> <v-btn @click="onClickImageUpload" type="button">이미지 업로드</v-btn> <div> <div v-for="(p, i) in imagePaths" :key="p" style="display: inline-block"> <img :src="`http://localhost:3085/${p}`" :alt="p" style="width: 200px"> <div> <button @click="onRemoveImage(i)" type="button">제거</button> </div> </div> </div> </v-form> </v-container> </v-card> </template> <script> import { mapState } from 'vuex' export default { data() { return { valid: false, hideDetails: false, successMessages: '', success: false, content: '', } }, computed: { ...mapState('users', ['me']), ...mapState('posts', ['imagePaths']) }, methods: { onChangeTextarea(value) { if(value.length) { this.hideDetails = true; this.success = false; this.successMessages = ''; } }, onSubmitForm() { if(this.$refs.form.validate()) { this.$store.dispatch('posts/add', { content : this.content, }) .then(() => { this.content = '', this.hideDetails = false; this.success = true; this.successMessages = '게시글 등록 성공'; }) .catch(() => { }) } }, onClickImageUpload() { this.$refs.imageInput.click(); }, onChangeImages(e) { console.log(e.target.files) const imageFormData = new FormData(); [].forEach.call(e.target.files, (f) => { imageFormData.append('image', f) }) this.$store.dispatch('posts/uploadImages', imageFormData) }, onRemoveImage(index) { this.$store.commit('posts/removeImagePaths', index) } } } </script> <style> </style> posts.js(프론트엔드) export const state = () => ({ mainPosts: [], hasMorePost: true, imagePaths: [] }) const limit = 10; const totalPosts = 51 export const mutations = { addMainPosts(state, payload) { state.mainPosts.unshift(payload); state.imagePaths = []; }, removeMainPosts(state, payload) { const index = state.mainPosts.findIndex(v => v.id === payload.id); state.mainPosts.splice(index, 1) }, addComment(state, payload) { const index = state.mainPosts.findIndex(v => v.id === payload.postId); state.mainPosts[index].Comments.unshift(payload) }, loadPosts(state, payload) { const diff = totalPosts - state.mainPosts.length const fakePosts = Array(diff > limit ? limit : diff).fill().map(v => ({ id: Math.random().toString(), User: { id: 1, nickname: "Moon" }, content: `hello infinite scrolling ${Math.random()}`, Comments: [], Img: [], })) state.mainPosts = state.mainPosts.concat(fakePosts) state.hasMorePost = fakePosts.length === limit }, concatImagePaths(state, payload) { state.imagePaths = state.imagePaths.concat(payload) }, removeImagePaths(state, payload) { state.imagePaths.splice(payload, 1) } } export const actions = { add({commit, state}, payload) { this.$axios.post('http://localhost:3085/post', { content: payload.content, imagePaths: state.imagePaths, }, { withCredentials: true }) .then((res) => { commit('addMainPosts', res.data) }) .catch(() => { }) }, remove({commit}, payload) { commit('removeMainPosts', payload) }, addComment({commit}, payload) { commit('addComment', payload) }, loadPosts({commit, state}, payload) { if(state.hasMorePost) { commit('loadPosts', payload) } }, uploadImages({ commit }, payload) { this.$axios.post('http://localhost:3085/post/images', payload, { withCredentials: true, }) .then((res) => { commit('concatImagePaths', res.data); }) .catch(() => { }) } }
-
미해결스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
react, vue 웹 프론트엔드 기술
안녕하세요. 이번 강의 영한님 설명 중에 궁금한 점이 있습니다. react, vue로 개발하는 웹 프론트엔드 개발자가 따로 있으면 백엔드 개발자는 그냥 API만 만들어서 넘기면 된다고 하셨는데, 앱 같은 경우는 스토어에서 애플리케이션을 미리 다운받아서 서버로부터 데이터를 받아서 해당 앱에서 데이터를 보여주면 되지만, 프론트 엔드 같은 경우는 이 과정이 어떻게 이루어지나요? 제가 어떤 웹 페이지에 접속했을 때, 앱처럼 해당 웹 페이지의 기본 틀을 제 로컬에 저장해놓는 게 아닌 이상 잘 이해가 안 됩니다. 이와 관련해서 구글링을 좀 해봤는데 검색 키워드가 잘못되었는지 원하는 정보를 얻을 수가 없네요 ㅜㅜ