[TIL # 39] Vue 13일차

Yejin Yang·2022년 6월 13일
0

[TIL]

목록 보기
38/67
post-thumbnail

노션 프로젝트(2)

워크스페이스 생성

워크스페이스를 생성합니다.
워크스페이스의 내용(content)은 <div> <br> 태그만 허용(XSS 이슈 - 이전 글 참고)

store > workspace.js

import { defineStore } from 'pinia'

// defineStore는 인수를 두개 받는다 처음은 문자, 두번째는 객체
// 이름을 가지는 내보내기, 이름 패턴은 user+모듈이름+Store
export const useWorkspaceStore = defineStore('workspace', {
  state() {
    return {

    }
  },
  getters: {

  },
  actions: {
    // CRUD
    async createWorkspace() {
      const res = await fetch('URL', {
        method: 'POST',
        headers: {
          'content-type': 'application/json',
          'apikey': '',
          'username': ''
        },
        body: JSON.stringify({
          // parentId: '',
          title: '처음 만드는 워크스페이스!',
          content: '내용..',
          // poster: '',
        })
      })
      const workspace = await res.json()
      console.log(workspace)
			this.readWorkspaces()
    }
  }
})

workspace.vue 파일

// workspace.vue

<template>
  <h1>Workspace!</h1>
  <button @click="workspaceStore.createWorkspace">
    워크스페이스 생성!
  </button>
</template>

<script>
import { mapStores } from 'pinia'
import { useWorkspaceStore } from '~/store/workspace'

export default {
  computed: {
    ...mapStores(useWorkspaceStore)
  }
}
</script>

App.vue

// App.vue
<template>
  <RouterView />
</template>

콘솔에 출력해보기

워크스페이스 목록 조회

전체 워크스페이스 목록을 가져오기(상세내용 제외)

store > workspace.js

GET 비동기 로직 작성(API주소, key, name은 보안상 지웠습니다.)

async readWorkspaces() {
      const res = await fetch('URL', {
      method: 'GET',
      headers: {
        'content-type': 'application/json',
        'apikey': '',
        'username': ''
      },
      })
      const workspaces = await res.json()
      console.log(workspaces) 
    }

Workspace.vue

<button @click="workspaceStore.readWorkspaces">
    워크스페이스 조회!
</button>

참고로, 피니아는 workspaceStore라고 store이름을 꼭 명시해줘야한다.

콘솔에 목록들 출력해보기

가져온 목록들을 스토어의 데이터로 만들기

export const useWorkspaceStore = defineStore('workspace', {
  state() {
    return {
      // 기본은 빈배열, 목록을 불러오면 갱신
      workspaces: []
    }
  },
  
  
  //  actions: 부분
  async readWorkspaces() {
      const workspaces = await request({
        method: 'GET'
      })
    // // 서버에서 가져온 정보를 상태에 담는다.
      this.workspaces = workspaces
      this.workspacesLoaded = true
    },
  

목록 출력하기

새로운 뷰 파일


워크스페이스의 목록이 보여질 곳

LNB.vue

<template>
  <ul>
    <li
      v-for="workspace in workspaceStore.workspaces"
      :key="workspace.id">
      {{ workspace.title }}
    </li>
  </ul>
</template>

// store 연결
<script>
import { mapStores } from 'pinia'
import { useWorkspaceStore } from '~/store/workspace'

export default {
  computed: {
    ...mapStores(useWorkspaceStore)
  },
	// 컴포넌트 실행되자마자 가져와서 새로고침하면 목록 보이게 함
  ctrated() {
    this.workspaceStore.readWorkspaces()
  }
}
</script>

App.vue

<template>
  <LNB />
  <RouterView />
</template>

<script>
import LNB from './components/LNB.vue'

export default {
  components: {
    LNB
  }
}
</script>

워크스페이스 삭제

특정 워크스페이스를 삭제하기
자식 워크스페이스의 부모 워크스페이스 참조도 같이 삭제된다.

방법 두가지가 있다.(결정하기 나름)

  1. id를 바탕으로 workspaces 목록에서 해당되는 워크스페이스만 지우기
    • 최적화되긴하지만 복잡해짐
  2. 목록을 서버에서 다시 가져오기
    • 편하긴 하지만 요청이 한번 더 들어가야해서 비용이 더 들음

해당 프로젝트에서는 2번을 사용하기로 했다.

async deleteWorkspace(id) {
      await fetch(`URL${id}`, {
        method: 'DELETE',
        headers: {
          'content-type': 'application/json',
          'apikey': '',
          'username': ''
        }
      })
      this.readWorkspaces()
    }
// LNB.vue
<template>
  <ul>
    <li
      v-for="workspace in workspaceStore.workspaces"
      :key="workspace.id">
      {{ workspace.title }}
      <button @click="workspaceStore.deleteWorkspace(workspace.id)">
        삭제!
      </button>
    </li>
  </ul>
</template>

삭제 비동기 로직 작성하고 버튼에 연결시켜준다.

profile
Frontend developer

0개의 댓글