관리 메뉴

bright jazz music

blog17 : 글 작성화면 만들기 2 본문

Projects/blog

blog17 : 글 작성화면 만들기 2

bright jazz music 2023. 2. 1. 12:23

1. Vue component의 대략적인 사용법알아보기

<!--App.vue-->
<script setup lang="ts">
import { RouterLink, RouterView } from "vue-router";
// import HelloWorld from "./components/HelloWorld.vue";
</script>
<template>
  <header>
      <nav>
        <RouterLink to="/">Home</RouterLink>
        <RouterLink to="/write">글 작성</RouterLink> <!-- 글 작성  -->
      </nav>
  </header>
  <RouterView />
</template>
<style scoped>
</style>

 

 

<!-- WriteView.vue -->

<script setup lang="ts">

import {ref} from "vue"; //ref를 사용하기 위해 import
// const count = 0 //변수 선언: 반응형 변수가 아니다. 보통은 ref나 reactive를 사용해서 반응형 변수를 만들어 준다.
const count = ref(0) //ref를 사용하여 만든 반응현 변수
</script>

<template>
  <p>안녕하세요</p>
  <p>{{count}}</p> <button @click="count += 1">버튼을 눌러주세요</button> <!-- @: vue용 함수 호출인 듯 -->
</template>

<style>

</style>

 

vue에서 제공하는 기본 컴포넌트를 사용하면 이렇게 보인다.

 

부트스트랩 또는 element ui라는 CSS 프레임워크를 사용하면 좀 더 예쁘게 꾸밀 수 있다.

여기까지가 기본적인 내용이었다. 이제 WriteView.vue 파일의 <template></template> 태그 내부의 내용을 모두 지운다.

 

 

 

2. 본격

 

 

 

<!-- WriteView.vue -->

<script setup lang="ts">

import {ref} from "vue"; //ref를 사용하기 위해 import

const count = ref(0)
</script>
<template>
  <div>
    <input type="text" placeholder="제목을 입력해 주세요">
  </div>

  <div>
    <textarea rows="15"></textarea>
  </div>
  <button>글 작성 완료</button>

</template>

<style>
</style>

 

 

element plus 설치

https://element-plus.org/en-US/guide/installation.html#hello-world

 

Installation | Element Plus

 

element-plus.org

뷰 프로젝트가 위치한 디렉토리로 이동

 

$ npm install element-plus --save

 

 이제 element plus에 대한 컴포넌트를 사용할 수 있다.

 

추가적으로 부트스트랩 css 설치 (유틸용 css를 사용할 것이다)

npm install bootstrap@v5.2.3

//main.ts
import { createApp } from "vue";
import { createPinia } from "pinia";

import App from "./App.vue";
import router from "./router";

import ElementPlus from 'element-plus' //element plus 추가
import 'element-plus/dist/index.css' //element plus 추가

import "bootstrap/dist/css/bootstrap-utilities.css" //bootstrap css

// import "./assets/main.css"; 사용x

const app = createApp(App); //vue.js 앱을 맨들고

app.use(createPinia()); //필요한 프러그인 사용처리
app.use(router);
app.use(ElementPlus) //element plus 추가


app.mount("#app"); //#app으로 런치 ==> index.html 렌더링하고 거기에 App.vue 컴포넌트를 렌더링

 

 

<!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import
</script>

<template>
  <div>
    <input type="text" placeholder="제목을 입력해 주세요"/>
  </div>

  <div>
    <div>
      <textarea rows="15"></textarea>
    </div>

    <div>
      <button>글 작성 완료</button>
    </div>
  </div>
</template>

<style>
</style>
기본 태그만 사용했을 때

 

element plus(el) 과 bootstrap utility css(mt-2)를 사용했을 때

<!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import
</script>

<template>
  <div>
    <el-input type="text" placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="d-flex align-items-center">
    <div>
      <el-input type="textarea" rows="15"></el-input>
    </div>

    <div class="mt-2">
    <el-button type="primary">글 작성 완료</el-button>
    </div><!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import
</script>

<template>
  <div class="mt-2">
    <el-input placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="mt-2">
     <el-input type="textarea" rows="15"></el-input>
  </div>

  <div class="mt-2">
    <el-button type="primary">글 작성 완료</el-button>
  </div>

</template>

<style>
</style>
  </div>
</template>

<style>
</style>
이렇게 바뀌었다. 그런데 현재는 텍스트가 입력되지 않는다.어떤 데이터를 변수에 담을 지 정해주지 않않기 때문이다. v-model을 사용한다.

 

반응형 변수 title과 content를 선언하고 이들을 값을 입력 태그의 v-model 값으로 설정한다.

<!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import

const title = ref("") //입력받은 값을 저장할 변수 선언
const content = ref("") //입력받은 값을 저장할 변수 선언

</script>

<template>
  <div class="mt-2">
<!--    선언한 title, content 변수를 아래 v-model 태그에 넣는다.-->
    <el-input v-model="title" placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="mt-2">
     <el-input v-model="content" type="textarea" rows="15"></el-input>
  </div>

  <div class="mt-2">
    <el-button type="primary">글 작성 완료</el-button>
  </div>

</template>

<style>
</style>

 

이제 '글 작성 완료' 버튼을 누르면 포스트가 저장되도록 만들어야 한다.

 

우선 테스트

<!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import

const title = ref("") //입력받은 값을 저장할 변수 선언
const content = ref("") //입력받은 값을 저장할 변수 선언

const write = function() {
  // console.log(title, content) ref로 감싸져 있음.
  console.log(title.value, content.value)//콘솔에 직접 찍힘
}



</script>

<template>
  <div class="mt-2">
<!--    선언한 title, content 변수를 아래 v-model 태그에 넣는다.-->
    <el-input v-model="title" placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="mt-2">
     <el-input v-model="content" type="textarea" rows="15"></el-input>
  </div>

  <div class="mt-2">
    <el-button type="primary" @click="write()">글 작성 완료</el-button> <!--눌렀을 때 write() 함수 호출 -->
  </div>

</template>

<style>
</style>

콘솔에 찍히는 모습을 볼 수 있다.

 

이걸 보내려면 AXIOS라는 라이브러리를 사용한다.

https://axios-http.com/kr/docs/intro

 

시작하기 | Axios Docs

시작하기 브라우저와 node.js에서 사용할 수 있는 Promise 기반 HTTP 클라이언트 라이브러리 Axios란? Axios는 node.js와 브라우저를 위한 Promise 기반 HTTP 클라이언트 입니다. 그것은 동형 입니다(동일한 코

axios-http.com

 

설치 완료
TS2591: Cannot find name 'require'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in

오류 발생

CommonJs형태가 아니었기 때문. 따라서 import axios from 'axios' 로 임포트

<!-- WriteView.vue -->
<script setup lang="ts">


import {ref} from "vue"; //ref를 사용하기 위해 import

// const axios = require('axios').default; 오류발생 :CommonJS형태가 아니기 때문.
import axios from 'axios'// 따라서 이렇게 import

const title = ref("") //입력받은 값을 저장할 변수 선언
const content = ref("") //입력받은 값을 저장할 변수 선언

const write = function() {
  axios.get("https://google.com")
}



</script>

<template>
  <div class="mt-2">
<!--    선언한 title, content 변수를 아래 v-model 태그에 넣는다.-->
    <el-input v-model="title" placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="mt-2">
     <el-input v-model="content" type="textarea" rows="15"></el-input>
  </div>

  <div class="mt-2">
    <el-button type="primary" @click="write()">글 작성 완료</el-button> <!--눌렀을 때 write() 함수 호출 -->
  </div>

</template>

<style>
</style>

 

글 작성 완료 버튼 누른다. 의도는 구글로 보내기였다.
https의 경우. CORS 문제 발생
http의 경우

 

CORS문제가 발생하는 이유.

==>

 

우리가 만든 localhost:8080 에 쏴도 마찬가지다.

 

 

CORS에러 해결하기.

 

WebConfig클래스 생

//WebConfig.java

package com.endofma.blog.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("http://localhost:5173");
    }
}

현재 로컬 vue의 포트가 5173이다.

'글 작성완료' 버튼을 눌러서 http://localhost:8080에 get으로 접근해보자.

 

성공 (뭐 만든 게 없어서 404)

 

글 작성하기

//WriteView.vue

const write = function() {
  axios.post("http://localhost:8080/posts") //글 등록 api
}

 

전문

<!-- WriteView.vue -->
<script setup lang="ts">
import {ref} from "vue"; //ref를 사용하기 위해 import

// const axios = require('axios').default; 오류발생 :CommonJS형태가 아니기 때문.
import axios from 'axios'// 따라서 이렇게 import

const title = ref("") //입력받은 값을 저장할 변수 선언
const content = ref("") //입력받은 값을 저장할 변수 선언

//WriteView.vue
const write = function() {
  axios.post("http://localhost:8080/posts",
      //RequestBody
      {
        title: title.value,
        content: content.value
      });
}

</script>

<template>
  <div class="mt-2">
<!--    선언한 title, content 변수를 아래 v-model 태그에 넣는다.-->
    <el-input v-model="title" placeholder="제목을 입력해 주세요"/>
  </div>

  <div class="mt-2">
     <el-input v-model="content" type="textarea" rows="15"></el-input>
  </div>

  <div class="mt-2">
    <el-button type="primary" @click="write()">글 작성 완료</el-button> <!--눌렀을 때 write() 함수 호출 -->
  </div>

</template>

<style>
</style>

로그도 찍혔다. PostService.java

 

application.yml 에서 계정 참고해서 로그인

 

DB에 저장됐다.

 

Comments