๐Ÿค ์€์ง€log ๐Ÿค

[VUE] Vue๋กœ ๋งŒ๋“  ๊ฒŒ์‹œํŒ์— CRUD ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณธ๋ฌธ

๐Ÿ“ Vue

[VUE] Vue๋กœ ๋งŒ๋“  ๊ฒŒ์‹œํŒ์— CRUD ๊ตฌํ˜„ํ•˜๊ธฐ

Eun_zii 2023. 10. 27. 11:42

๊ฒŒ์‹œํŒ css๋Š” bootstrap์„ ์‚ฌ์šฉํ•˜์˜€๊ณ  ์ด ๊ธ€์€ crud๊ณผ์ •๋งŒ ์ •๋ฆฌํ•œ ๊ธ€ ์ž„๋ฏธ๋Œฑ.. !๐Ÿ˜‹

 

 

 

๐Ÿ”† json-server

RestApi๋Š” json-server์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค !

 

GitHub - typicode/json-server: Get a full fake REST API with zero coding in less than 30 seconds (seriously)

Get a full fake REST API with zero coding in less than 30 seconds (seriously) - GitHub - typicode/json-server: Get a full fake REST API with zero coding in less than 30 seconds (seriously)

github.com

 

// ๊ฐœ๋ฐœํ™˜๊ฒฝ ์„ค์น˜: -D
npm install -D json-server 

// ์ „์—ญ์ ์œผ๋กœ ์„ค์น˜: -g
npm install -g json-server

 

// ๋กœ์ปฌ์— ์„ค์น˜ํ•œ ๊ฒฝ์šฐ( -D ์˜ต์…˜ ์„ค์น˜)
npx json-server --watch db.json

// ์ „์—ญ์ ์œผ๋กœ ์„ค์น˜ํ•œ ๊ฒฝ์šฐ ( -g ์˜ต์…˜ ์„ค์น˜)
json-server --watch db.json

 

๋ฃจํŠธ ํด๋” ์•ˆ์— db.json ํด๋”๊ฐ€ ์ƒ์„ฑ๋˜๊ณ , ์•ˆ์— ์šฐ์„  ์ž„์˜๋กœ ํ…Œ์ŠคํŠธ์šฉ ๋ฐ์ดํ„ฐ ๋„ฃ์–ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค !

// db.json
{
  "posts": [
   {
      "id": 1,
      "title": "์ œ๋ชฉ1",
      "content": "๋‚ด์šฉ1",
      "createdAt": "2023-01-01"
    },
     {
      "id": 2,
      "title": "์ œ๋ชฉ2",
      "content": "๋‚ด์šฉ2",
      "createdAt": "2023-03-17"
    },
    {
      "id": 3,
      "title": "์ œ๋ชฉ3",
      "content": "๋‚ด์šฉ3",
      "createdAt": "2023-04-26"
    },
    {
      "id": 4,
      "title": "์ œ๋ชฉ4",
      "content": "๋‚ด์šฉ4",
      "createdAt": "2023-10-20"
    },
    {
      "id": 5,
      "title": "์ œ๋ชฉ5",
      "content": "๋‚ด์šฉ5",
      "createdAt": "2023-12-15"
    }
  ]
}

 

๋ฐ์ดํ„ฐ ๋„ฃ์–ด ์ฃผ์‹  ํ›„ ๋‹ค์‹œ ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ํ™•์ธํ•ด ๋ณผ ์ˆ˜ ์žˆ๋Š”๋ฐ

์ด๋•Œ ! ํฌํŠธ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์›ํ•˜์‹œ๋Š” ํฌํŠธ ์ง€์ •ํ•˜์‹œ๊ณ  localhost:4000/posts์œผ๋กœ ๋“ค์–ด๊ฐ€์‹œ๋ฉด ๋ณธ์ธ์ด ์ €์žฅํ•œ json๋ฐ์ดํ„ฐ๋ฅผ ๋ณผ์ˆ˜์žˆ์Šต๋‹ˆ๋‹ค !

npx json-server --watch db.json --port 4000

 

๐Ÿ”† axios ์„ค์น˜

npm i axios

 

๐Ÿ”† src/api(ํด๋”)/posts.ts

import axios from 'axios'

export function getPosts() {
  return axios.get('http://localhost:4000/posts')
}

export function getPostById(id: number) {
  return axios.get(`http://localhost:4000/posts/${id}`)
}

export function createPost(data: any) {
  return axios.post('http://localhost:4000/posts', data)
}
export function updatePost(id: number, data: any) {
  return axios.put(`http://localhost:4000/posts/${id}`, data)
}
export function deletePost(id: number) {
  return axios.delete(`http://localhost:4000/posts/${id}`)
}

 

๐Ÿ”† Create

<template>
  <div>
    <h2>๊ฒŒ์‹œ๊ธ€ ๋“ฑ๋ก</h2>
    <hr class="my-4" />
    <form @submit.prevent="save">
      <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="goListPage">๋ชฉ๋ก</button>
        <button class="btn btn-primary">์ €์žฅ</button>
      </div>
    </form>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'

import { createPost } from '../../api/posts'

const router = useRouter()
const form = ref({
  title: null,
  content: null
})

const save = () => {
  try {
    createPost({
      ...form.value,
      createdAt: Date.now()
    })
    router.push({ name: 'PostList' })
  } catch (error) {
    console.error(error)
  }
}

const goListPage = () => router.push({ name: 'PostList' })
</script>

<style></style>

 

๐Ÿ”† List

<template>
  <h2>๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก</h2>
  <hr class="my-4" />
  <div class="row g-3">
    <div v-for="post in posts" :key="post.id" class="col-4">
      <PostItem
        :title="post.title"
        :content="post.content"
        :created-at="post.createdAt"
        @click="goPage(post.id)"
      ></PostItem>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter } from 'vue-router'

import PostItem from '../../components/posts/PostItem.vue'
import { getPosts } from '../../api/posts'

const router = useRouter()
const posts = ref([])

const fetchPosts = async () => {
  try {
    const { data } = await getPosts()
    posts.value = data
  } catch (error) {
    console.error(error)
  }
}
fetchPosts()

const goPage = (id) => {
  router.push({
    name: 'PostDetail',
    params: { id }
  })
}
</script>

<style></style>

 

๐Ÿ”† Detail

<template>
  <h2>{{ form.title }}</h2>
  <p>{{ form.content }}</p>
  <p class="text-muted">{{ form.createdAt }}</p>
  <hr class="my-4" />
  <div class="row g-2">
    <div class="col-auto">
      <button class="btn btn-outline-dark">์ด์ „๊ธ€</button>
    </div>
    <div class="col-auto">
      <button class="btn btn-outline-dark">๋‹ค์Œ๊ธ€</button>
    </div>
    <div class="col-auto me-auto"></div>
    <div class="col-auto">
      <button class="btn btn-outline-dark" @click="goListPage">List</button>
    </div>
    <div class="col-auto">
      <button class="btn btn-outline-primary" @click="goEditPage">Edit</button>
    </div>
    <div class="col-auto">
      <button class="btn btn-outline-danger" @click="remove">Delete</button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'
import { useRouter, useRoute } from 'vue-router'

import { getPostById, deletePost } from '../../api/posts'

const route = useRoute()
const router = useRouter()
const id = route.params.id
const form = ref({})

const fetchPost = async () => {
  try {
    const { data } = await getPostById(id)
    form.value = { ...data }
  } catch (error) {
    console.error(error)
  }
}
fetchPost()
const remove = async () => {
  try {
    if (confirm('์‚ญ์ œํ•˜์‹œ๊ฒ ์Šต๋‹ˆ๊นŒ?')) {
      await deletePost(id)
      router.push({ name: 'PostList' })
    }
  } catch (error) {
    console.error(error)
  }
}

const goListPage = () => router.push({ name: 'PostList' })
const goEditPage = () => router.push({ name: 'PostEdit', params: { id } })
</script>

<style></style>

 

๐Ÿ”† Edit

<template>
  <div>
    <h2>๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •</h2>
    <hr class="my-4" />
    <form @submit.prevent="edit">
      <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-danger me-2" @click="goDetailPage">
          ์ทจ์†Œ
        </button>
        <button class="btn btn-primary">์ˆ˜์ •</button>
      </div>
    </form>
  </div>
</template>

<script setup>
import { useRoute, useRouter } from 'vue-router'
import { ref } from 'vue'

import { getPostById, updatePost } from '../../api/posts'

const route = useRoute()
const router = useRouter()
const id = route.params.id

const form = ref({
  title: null,
  content: null
})
const fetchPost = async () => {
  try {
    const { data } = await getPostById(id)
    setForm(data)
  } catch (error) {
    console.error(error)
  }
}
const setForm = ({ title, content }) => {
  form.value.title = title
  form.value.content = content
}
fetchPost()
const edit = async () => {
  try {
    await updatePost(id, { ...form.value })
    router.push({ name: 'PostDetail', params: { id } })
  } catch (error) {
    console.error(error)
  }
}

const goDetailPage = () => router.push({ name: 'PostDetail', params: { id } })
</script>

<style></style>

 

โค๏ธ ์ „์ฒด ์ฝ”๋“œ :

 

โค๏ธ ๋„์›€ ์ฃผ์‹  ๋ถ„ :

728x90