[Vue실강] 4강 vite

youngseo·2022년 5월 25일
1
post-thumbnail

0524 강의정리

1. vite.js 시작

vite.js공식문서

1-1 vite.js설치

$ npm create vite@latest 폴더이름
$ cd 폴더이름
$ code . -r
$ npm i
$ npm run dev

1-2 경로별칭 설정

vite공식문서 경로별칭설정

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))
    }
  }
})

1-3 main.js

import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

1-4 eslint설치

$ 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"
  }
}

1-5 scss구성

$ 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 설치 및 연결

2. 컴포넌트

컴포넌트 등록

  • 지역등록
  • 전역등록

2-1 컴포넌트 등록

부모

<!-- 여기서의 :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>

2-2 컴포넌트에서 v-model사용하기

컴포넌트에서 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>

3. 동적컴포넌트

vue.js공식문서

⭐🌟

  • :를 통해 데이터로 전달하기 때문에 ''로 감싸서 전달
  • 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>

동적컴포넌트 심화(keep-alive)

vue.js공식문서

Teleport

(모달창에서 발생할 수 있는 문제를 방지해줍니다.)

vue.js공식문서

참고

  • 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>

0개의 댓글