$ npm create vite@latest 폴더이름
$ cd 폴더이름
$ code . -r
$ npm i
$ npm run dev
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
resolve: {
alias: [
✅ {find :'~', replacement: `${__dirname}/src`},
]
}
})
경로별칭은 여러개 설정을 할 수도 있습니다.
vite3버전
import {fileURLToPath, URL} from 'url' import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { '~': fileURLToPath(new URL("./src", import.meta.url)) } } })
import { createApp } from 'vue'
import App from './App.vue'
createApp(App).mount('#app')
$ npm i -D eslint eslint-plugin-vue
.eslintrc.json
{
"env": {
"browser": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:vue/vue3-recommended"
],
"rules": {
"semi": ["error", "never"],
"quotes": ["error", "single"],
"eol-last": ["error", "always"], //빈줄 하나 허용
"vue/html-closing-bracket-newline": ["error", {
"singleline": "never",
"multiline": "never"
}],
"vue/html-self-closing": ["error", {
"html": {
"void": "always",
"normal": "never",
"component": "always"
},
"svg": "always",
"math": "always"
}],
"vue/comment-directive": "off",
"vue/multi-word-component-names": "off"
}
}
$ npm i -D sass
🔑vuex설치 및 연결
$ npm install vuex@next
import { createStore } from 'vuex' // Create a new store instance. const store = createStore({ state () { return { count: 0 } }, mutations: { increment (state) { state.count++ } } })
🔑 route 설치 및 연결
컴포넌트 등록
- 지역등록
- 전역등록
부모
<!-- 여기서의 :value는 props옵션입니다 (1) value라는 이름으로 msg데이터르르 전달-->
<TextField :value="msg" />
<script>
import TextField from '~/components/TextField.vue'
export default {
components: {
TextField
},
data() {
return {
msg: 'Hello Vue!'
}
}
}
</script>
자식(TextField)
<template>
//v-model로 사용을 하면 안됩니다!!(props를 받기 때문에)
<input :value="value" />
</template>
<script>
export default {
// (2) 자식 요소에 props등록
props: {
value: {
type: String,
default: ''
}
}
}
</script>
컴포넌트에서 v-model 사용하기
✅props로 받은 데이터는 v-model을 통한 양방향으로 연결하면 안됩니다
✅만약 부모에서 v-model을 이용해 props를 내려보냈다면, modelValue라는 값으로 데이터를 받습니다. 올려보내는 emit의 이름은 update:modelValue입니다
부모
<template>
<h1> {{ msg }} </h1>
<TextField v-model="msg" />
</template>
자식
<template>
<input
:value="modelValue"
@input="$emit('update:modelValue', $event.target.value)" />
</template>
<script>
export default {
props: {
modelValue: {
type: String,
default: ''
}
},
//emits을 등록
emits: ['update:modelValue']
}
</script>
⭐🌟
:
를 통해 데이터로 전달하기 때문에 ''로 감싸서 전달- is라는 속성에 작성한 컴포넌트의 이름이 있으면 등록된 컴포넌트를 그 자리에 출력을 하겠다는 의미
App.vue
<template>
//ABC를 클릭하면 compName이라는 반응형데이터에 ABC라는 문자를 할당해주세요
<button @click="compName='ABC'">
ABC
</button>
//XYZ를 클릭하면 compName이라는 반응형데이터에 XYZ라는 문자를 할당해주세요
<button @click="compName='XYZ'">
XYZ
</button>
<Component :is="compName" />
</template>
<script>
// import TextField from '~/components/TextField.vue'
import ABC from '~/components/ABC.vue'
import XYZ from '~/components/XYZ.vue'
export default {
components: {
ABC,
XYZ
},
data() {
return {
msg: 'Hello Vue!',
compName: 'ABC' //초기값을 ABC로 설정
}
}
}
</script>
ABC.vue(XYZ도 텍스트 빼고 동일)
<template>
<h1>{{ msg }}</h1>
</template>
<script>
export default {
data() {
return {
msg: 'ABC!'
}
}
}
</script>
(모달창에서 발생할 수 있는 문제를 방지해줍니다.)
참고
- vite에서 scss문법을 사용하기 위해서는
npm i -D sass
만 설치해주면 됩니다.
App.vue
<template>
<div class="box">
<Modal>
Hello World!
</Modal>
</div>
</template>
<script>
import Modal from '~/components/Modal.vue'
export default {
components: {
Modal
},
data() {
return {
msg: 'Hello Vue!',
compName: 'ABC'
}
}
}
</script>
<style lang="scss" scoped>
.box {
width: 200px;
height: 200px;
position: fixed;
bottom: 0;
right: 0;
border: 4px solid;
✅transform: scale(1);
}
</style>
Modal.vue
<template>
<div class="modal">
<div class="bg"></div>
<div class="contents">
<slot></slot>
</div>
</div>
</template>
<style lang="scss" scoped>
.modal {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
.bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(#000, .6);
}
.contents {
position: relative;
width: 200px;
max-height: calc(100% - 100px);
background-color: #fff;
}
}
</style>
position - fixed
- 요소의 조상 중 하나가 transform, perspective, filter속성 중 어느 하나라도 있으면 개를 조상 요소로 삼습니다.
이 경우 teleport를 이용할 수 있습니다.
<template>
<Teleport>
<div class="modal">
<div class="bg"></div>
<div class="contents">
<slot></slot>
</div>
</div>
</Teleport>
</template>