Vue시작해보기
설치하는 방법 :
npm install -g @vue/cli
시작부터 에러남..
그래서 파워쉘에서 권한 모드 변경해주었음.
프로젝트를 만들기 위해 아래 코드 실행
vue create hello-world
버전은 2로 선택
샘 따라서 그냥 yarn으로 설치햇음..
헬로월드 폴더로 들어가서
yarn serve실행.
8081포트에서 돌아가고있음.
크롬에서 Vue.js devtools다운받기!
또 App.js열었더니 오류발생..
찾아서 해결함..
vue글자가 하얀색으로 나와서 확장프로그램 설치했다.
그리고 자동완성이 안되어서
setting.json파일에 아래처럼 써주었다
{
"eslint.workingDirectories": [
{"mode": "auto"}
],
"emmet.syntaxProfiles":{
"vue-html":"html",
"vue":"html"
}
}
샘이 이거 설치하라고해서 설치도했음.
이것도함.
Helloworld컴포넌트 다 지우고 시작해보자.
TodoList.vue라는 파일 만듬.
vueinit치고 탭누르면 자동완성된다
<template lang="">
<div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="">
</style>
컴포넌트를 만들어보자.
<template>
<div>
<div>
<input type="text">
<button>추가하기</button>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="">
</style>
이제 임포트해보겠다.
App.vue코드 :
<template>
<div id="app">
<TodoList />
</div>
</template>
<script>
import TodoList from "./components/TodoList";
export default {
name: 'App',
components : {
TodoList,
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
잘나옴.
ListItem.vue라는 파일을 만듬.
<template>
<li>리스트 아이템입니다</li>
</template>
<script>
export default {
}
</script>
<style lang="">
</style>
이거를 TodoList.vue에 임포트하고 Input을 선언, 사용해보겠다.
TodoList.vue :
<template>
<div>
<div>
<input type="text" v-model="inputValue" >
<button>추가하기</button>
<ListItem />
</div>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : ""
}
},
components : {
ListItem,
}
}
</script>
<style lang="">
</style>
이렇게만 했을뿐인데!?
input창에 치는 글짜가 바로 상태관리가 됨!!
이번에는 리턴에 listArray를 선언했다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button>추가하기</button>
</div>
<ul>
<ListItem />
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : []
}
},
components : {
ListItem,
}
}
</script>
<style lang="">
</style>
다음으로는 이벤트를 만들어주자.
@click="" 이런식으로 만들면 된다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="">추가하기</button>
</div>
<ul>
<ListItem />
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : []
}
},
components : {
ListItem,
},
}
</script>
<style lang="">
</style>
이제 함수를 만들면된다. 함수는? method라는 방식으로 만든다.
this라는 것을 사용해야 한다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem />
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : []
}
},
components : {
ListItem,
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
}
}
}
</script>
<style lang="">
</style>
허걱 여기까지 만들면 이렇게 나온다.
이제 ListItem에 넣어보자.
vue의 for문 사용과 key넣기, 스타일 넣기는 아래와 같다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem v-for="(value, index) in listArray" :key="index"
:style="style"/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : [],
style: {
color: "red"
}
}
},
components : {
ListItem,
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
}
}
}
</script>
<style lang="">
</style>
출력하면 리스트 개수만큼 ListItem컴포넌트가 호출된다.
이제 컴포넌트에 벨류를 넣어보자.
이제 프롭스로 전달해보자.
첫번째 방법.
ListItem.vue
<template>
<li>{{text}}</li>
</template>
<script>
export default {
props: ["text"]
}
</script>
<style lang="">
</style>
그리고 TodoList에서도 text를 전달한다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem v-for="(value, index) in listArray" :key="index"
:text="value"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : [],
}
},
components : {
ListItem,
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
}
}
}
</script>
<style lang="">
</style>
더 좋은 방법은 객체로 받아서 타입을 정해주는 것이다.
ListItem.vue
<template>
<li>{{text}}</li>
</template>
<script>
export default {
props: {
text: {
type : String
}
}
}
</script>
<style lang="">
</style>
required를 사용하면 꼭 입력값이 있어야한다는 것을 사용할수도 있다.
<template>
<li>{{text}}</li>
</template>
<script>
export default {
props: {
text: {
type : String,
required : true
}
}
}
</script>
<style lang="">
</style>
default값을 넣으면 값이없으면 무조건 이거를 넣어주는 역할도 해준다.
<template>
<li>{{text}}
<button >삭제</button>
</li>
</template>
<script>
export default {
props: {
text: {
type : String,
required : true,
default : "안녕!"
}
}
}
</script>
<style lang="">
</style>
이제 삭제 기능을 구현해보자.
먼저, ListItem.vue에 삭제 버튼을 만든다.
<template>
<li>{{text}}</li>
</template>
<script>
export default {
props: {
text: {
type : String,
required : true,
default : "안녕!"
}
}
}
</script>
<style lang="">
</style>
뷰에서는 이밋 기능을 사용하면 된다.
먼저, TodoList.vue에서 index를 보내준다.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem v-for="(value, index) in listArray"
:key="index"
:text="value"
:index="index"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){ //함수다 data는 객체안에서사용할 상태리턴하면됨
return{
inputValue : "",
listArray : [],
}
},
components : {
ListItem,
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
}
}
}
</script>
<style lang="">
</style>
그 다음에는 ListItem.vue에서 클릭에 itemDelete함수를 만들어서 위로 올렸다.
<template>
<li>{{text}}
<button @click="itemDelete">삭제</button>
</li>
</template>
<script>
export default {
props: {
index : {
type : Number
},
text: {
type : String,
required : true,
default : "안녕!"
}
},
methods: {
itemDelete(){
this.$emit('delete', this.index)
}
}
}
</script>
<style lang="">
</style>
이제 TodoList에서 emit으로 받은 것을 캐칭하는 것은 간단하다.
TodoList.vue
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem
v-for="(value, index) in listArray"
:key="index"
:index="index"
:text="value === '' ? undefined : value"
@delete="catchDeleteItem"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){
return{
inputValue : "",
listArray : [],
}
},
components: {
ListItem
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
},
catchDeleteItem(index){
console.log(index)
}
},
}
</script>
<style lang="">
</style>
이렇게 캐칭이 되는 것이다.
삭제 기능을 모두 만들어보자.
<template>
<div>
<div>
<input type="text" v-model="inputValue" />
<button @click="addItem">추가하기</button>
</div>
<ul>
<ListItem
v-for="(value, index) in listArray"
:key="index"
:index="index"
:text="value === '' ? undefined : value"
@delete="catchDeleteItem"
/>
</ul>
</div>
</template>
<script>
import ListItem from "./ListItem";
export default {
data(){
return{
inputValue : "",
listArray : [],
}
},
components: {
ListItem
},
methods: {
addItem(){
this.listArray.push(this.inputValue);
this.inputValue = "";
},
catchDeleteItem(index){
this.listArray.splice(index,1)
}
},
}
</script>
<style lang="">
</style>
-- 라우터 만들기
다운받는법 : vue add router
터미널 창에 치고 엔터
YES
YES
알아서 라우터와 뷰라는 것들을 만들어준다.
yarn serve로 서버 실행해본다.
라우터 폴더가 생겼다.
화면도 이렇게 바꼈다
Board라는 새로운 라우터를 열어보자.
파일구조 :
Board.vue
<template>
<div class="board">
이곳은 게시판 입니다
</div>
</template>
<script>
export default {
name: "Board_",
}
</script>
<style lang="">
</style>
index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue';
import Board from "../views/Board.vue"
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
},
{
path: '/board',
name: 'Board_',
component: Board
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
App.vue
<template>
<div id="app">
<nav>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link> |
<router-link to="/board">Board</router-link>
</nav>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
그렇다면 url 중에
localhost:3000/user/@jenny
이런거는 어떻게 할까?
요기가 공식문서
https://router.vuejs.org/guide/essentials/dynamic-matching.html
index.js에서 url을 조금 바꿨다.
import Vue from 'vue'
import VueRouter from 'vue-router'
import HomeView from '../views/HomeView.vue';
import Board from "../views/Board.vue"
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: HomeView
},
{
path: '/about',
name: 'about',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/AboutView.vue')
},
{
path: '/board/:id',
name: 'Board_',
component: Board
}
]
const router = new VueRouter({
mode: 'history',
base: process.env.BASE_URL,
routes
})
export default router
이렇게 바꾸면 url에서 board뒤에
localhost:3000/board/news 라고 치면 news를 감지할 수 있는 것이다.
라우트를 추가하면 $route라는 객체가 자동적으로 추가가 된다.
그래서 params라는 부분에 접근할 수 있는 것이다.
Board.vue코드
<template>
<div class="board">
이곳은 {{boardName}}게시판 입니다
</div>
</template>
<script>
export default {
name: "Board_",
data(){
return{
boardName : ""
}
},
created(){
this.boardName = this.$route.params.id;
}
}
</script>
<style lang="">
</style>
crated () : 뷰가 처음 생기는 시점에서 호출되는 것.
url로 준 params가 boardName이라는 변수에 들어가는 것이다.
다음으로는 쿼리스트링에 대해 알아보자.
종종 이런 주소를 본다.
http://localhost:8081/board/sports?articleId=300
이거는 어떻게 처리가 될까?
query로 들어가는 것을 볼수있다.
두개 넣으려면 &를 쓴다.
http://localhost:8081/board/sports?articleId=300&token=sklfj 라고 쓰면
그리고 이렇게 할수도 있다.
Board.vue코드 :
<template>
<div class="board">
이곳은 {{$route.params.id}}게시판 입니다
파라미터를 뽑으려면 {{$route.query.name}}이렇게 합니다.
</div>
</template>
<script>
export default {
name: "Board_",
}
</script>
<style lang="">
</style>
http://localhost:8081/board/sports?name=JENNY 라고 치면 결과는 이렇게 나온다.
App.vue파일을 이렇게 바꿀수도 있다.
name : ' ~ ' => 이부분 무조건 따옴표. 쌍따옴표 쓰면 에러남.
<template>
<div id="app">
<nav>
<router-link :to="{name:'home'}">Home</router-link> |
<router-link :to="{name:'about'}">About</router-link> |
<router-link :to="{name:'Board_'}">Board</router-link>
</nav>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
보통은 이렇게 객체 형태로 쓴다.
안에 파라미터도 넣어보자.
App.vue 파일
<template>
<div id="app">
<nav>
<router-link :to="{name:'home'}">Home</router-link> |
<router-link :to="{name:'about'}">About</router-link> |
<router-link :to="{name:'Board_', params: {name: 'newsㄴㄴ'}}">게시판</router-link>
</nav>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
Board.vue파일
<template>
<div class="board">
이곳은 {{$route.params.name}}게시판 입니다
파라미터를 뽑으려면 {{$route.query.name}}이렇게 합니다.
</div>
</template>
<script>
export default {
name: "Board_",
}
</script>
<style lang="">
</style>
결과 :
query도 넣는다면?
App.vue
<template>
<div id="app">
<nav>
<router-link :to="{name:'home'}">Home</router-link> |
<router-link :to="{name:'about'}">About</router-link> |
<router-link :to="{name:'Board_', params: {name: 'news'}, query:{search:'검색어'}}">게시판</router-link>
</nav>
<router-view/>
</div>
</template>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
결과 :