$ npm create vite@latest notion-test
$ cd notion-test
$ npm i
$ code . -r
$ npm i vue-router pinia
$ npm i -D eslint eslint-plugin-vue sass
history
, scrollBehavior
, routes
필수
import { createRouter, createWebHistory } from 'vue-router'
import Home from './Home.vue'
import Workspace from './Workspace.vue'
import NotFound from './NotFound.vue'
export default createRouter({
// 히스토리 모드인지 해시모드인지 선택하는 옵션
history: createWebHistory(),
// 페이지 이동 시, 스크롤 초기화
scrollBehavior: () => ({ top: 0 }),
routes: [
{
path: '/',
component: Home
},
{
path: '/workspaces/:id',
component: Workspace
},
{
path: '/:notFound(.*)*',
component: NotFound
}
]
})
// main.js - pinia 연결
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
createApp(App)
.use(createPinia())
.mount('#app')
// router 연결
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import router from './routes'
import App from './App.vue'
createApp(App)
.use(createPinia())
.use(router)
.mount('#app')
CRUD는 스토어에서 만들어야 여러 컴포넌트에서도 사용하기 좋다.
서버와 통신하는 코드는 스토어에 만들기!
// 피니아 가져오기
import { defineStore } from 'pinia'
export const useWorkspaceStore = defineStore('workspace', {
state: () {
return {
}
},
getters: {
},
actions: {
// CRUD
}
}
})
contenteditable는 모든 HTML에서 공통으로 사용할 수 있는 특성이다.
contenteditable="true"
속성이 입력된 곳을 클릭하면 문자를 편집할 수 있게 해준다.
노션의 워크스페이스에서 제목과 내용을 입력할 때 유용하게 사용할 수 있다.
routes > Workspace.vue 파일
<!-- 제목 -->
<h1
ref="title"
placeholder="제목 없음"
contenteditable
@keydown.prevent.enter="$refs.content.focus()"
@blur="onInput">
{{ workspaceStore.workspace.title }}
</h1>
<!-- 내용 -->
<p
ref="content"
placeholder="내용을 입력하세요!"
contenteditable
@blur="onInput"
v-html="workspaceStore.workspace.content">
</p>
contenteditable
속성으로 입력한 텍스트들은 이렇게 div 태그로 감싸져서 내용이 추가 되는 것을 확인 할 수 있다.
그래서 XSS 위험이 있다. 내가 입력한 값들이 html구조로 그대로 들어가기 때문에 악의적으로 해킹 코드를 넣어서 서버를 공격하는 등 문제의 소지가 있다.
해당 프로젝트에서는 div
, br
태그만 허용한다.
크로스 사이트 스크립팅(Cross Site Scripting, XSS)은 공격자가 상대방의 브라우저에 스크립트가 실행되도록 해 사용자의 세션을 가로채거나, 웹사이트를 변조하거나, 악의적 콘텐츠를 삽입하거나, 피싱 공격을 진행하는 것을 말합니다