React 개발자의 Vue 도전기

오준상·2020년 5월 19일
0

서론

이 글은 개발을 시작한지 1년쯤 된 주니어 개발자가 되고싶은 사람의 글이므로, 틀린 부분이나 피드백을 주고 싶으시면 아래 댓글에 달아주시면 감사하겠습니다.

1년동안 react만 먹고 살았다..

지난 1년동안 React만 먹고 살았습니다. 여러가지 프로젝트를 진행하면서
많이 배웠다고 생각했습니다. 하지만 아무리 한국인이여도, 밥만 먹을 순 없다고 생각하고
다른 프레임워크를 공부해보려고 Vue를 찾아보기 시작했죠.
우선, 모든 프레임워크의 기본이 되는 공식문서를 찾아봤습죠.

<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

음 우선..html 파일에서 script 태그로 불러와도 쓸 수 있구나. 혁명적이네....

그리고 react를 배울 때 가장 먼저 사용했던 CLI에 대해서 검색해 보았다.

vue create 프로젝트명

오 vue에도 CLI가 있네 React랑 비슷하구만.
react의 CRA와 비슷했다.

그리고 CLI가 만들어준 폴더에 들어가 보면 React와 비스무리 한 파일구조가 우릴 반긴다.

음? 어디서 많이 보지 않았는가?
어쨌던, main.js에서 public/index.html에 있는 html 파일에 component들을 render 하는 방식인 것 같았다.

// main.js
import Vue from 'vue'
import App from './App.vue'

Vue.config.productionTip = false
// 개발에 도움을 주는 tip 끄기
new Vue({
  render: h => h(App),
}).$mount('#app')

개발의 첫걸음은 to-do list 개발이지

개인적으로 공부할 때 가장 많이 만들어보는 앱이 todolist라고 생각한다.
나중에 모든 front-end 라이브러리와 js로 todolist앱을 만들어 올리는게 꿈이다.
우선 내가 만든 App.Vue 파일을 보자

<template>
  <div class="todoApp">
    <div class="form-group">
      <h1>ToDo List</h1>
      <form role="form">
        <input type="text" class="form-control" placeholder="해야 할 일" v-model="title" v-on:keyup.enter="addTodo(title)">
      </form>
      <button type="button" v-on:click="addTodo(title)" class="btn btn btn-primary">Add</button>
    </div>
    <div class="todo-list">
      <todoList v-bind:todos="todos" v-bind:checkedTodo="checkedTodo" v-bind:deleteTodo="deleteTodo"></todoList>
    </div>
  </div> 
</template>

<script>
import todoList from './components/List'
export default {
  name: 'todoApp',
  data(){
    return {
      title:'',
      todos:[
        {
          title: '운동하기',
          isCheck: false,
          id: 1,
        },
        {
          title: 'JAVA',
          isCheck: false,
          id: 2,
        },
        {
          title: 'javascript',
          isCheck: false,
          id: 3,
        },
        {
          title: '영어',
          isCheck: false,
          id: 4,
        }
      ]
    }
  },
  methods:{
    addTodo(title){
      if(title){
        this.todos.push({title:title});
        this.title = '';
      }
    },
    checkedTodo(id){
      const clicked = this.todos.filter((todo)=> todo.id == id)[0];
      clicked.isCheck = !clicked.isCheck;
    },
    deleteTodo(e,id){
      const clicked = this.todos.filter((todo)=> todo.id == id)[0];
      const index = this.todos.indexOf(clicked);
      this.todos.splice(index,1);
    }
  },
  components: {
    'todoList': todoList
  }
}
</script>

<style scoped>
h1 {
  margin: 10px;
}
.todoApp {
  margin: auto;
  width: 700px;
  box-shadow: 0px 0px 3px 1px #707070;
  padding: 20px 30px 20px 30px;
}
form {
    display: inline-block;
}
.form-group {
    text-align: center;
    padding-bottom: 25px;
}
.todo-list {
    width: 100%;
    text-align: center;
}
a.close {
    float: right;
}
</style>

리액트의 jsx와 css와 js들을 모두 섞어놓은 듯한 느낌이다.
우선 data는 react의 state와 비슷 or 같다.
그래서 data에 변화가 생기면 다시 render되는 형식의 라이브러리이다.
method는 우리가 react class component의 method를 넣는 느낌이다.
일단 vue의 특별한 점은 templete 부분이다.

<template>
  <div class="todoApp">
    <div class="form-group">
      <h1>ToDo List</h1>
      <form role="form">
        <input type="text" class="form-control" placeholder="해야 할 일" v-model="title" v-on:keyup.enter="addTodo(title)">
      </form>
      <button type="button" v-on:click="addTodo(title)" class="btn btn btn-primary">Add</button>
    </div>
    <div class="todo-list">
      <todoList v-bind:todos="todos" v-bind:checkedTodo="checkedTodo" v-bind:deleteTodo="deleteTodo"></todoList>
    </div>
  </div> 
</template>

이곳을 보면 v-bind라거니 v-on이거니 처음보는 속성들이 많다.
이런 속성들을 자세히 알려면 Vue.js의 공식홈페이지에 가보자(필자가 공부한 곳도 여기다)
https://kr.vuejs.org/
일단 v-bind와 v-on을 대충 설명하자면, v-bind:propsName은 컴포넌트의 props에 값을 넣는 속성이다. react와 다른점은 propsName 앞에 v-bind가 붙는다는 점?
그리고 v-on은 내 생각이지만, event 처리를 위한 함수를 넣을때 사용하는 것 같다.
뭐 대충 코드를 설명하자면, dummyData를 todoList component에 넣고, input 옆의 버튼이 눌리면 addTodo method를 실행한다. 그리고 tooList의 props로 checkedTodo method와 deleteTodo method를 넣어준다.

이제 todolist render를 해보자

<template>
  <div>
    <ul  v-for="(todo, i) in todos" class="list-unstyled" v-bind:key="todo.id" v-on:click="checkedTodo(todo.id)">
        <div v-if="todo.isCheck === false">
            {{i+1}}. {{todo.title}} <span class="close" aria-hidden="true" v-on:click.stop="function(e){deleteTodo(e,todo.id)}">&times;</span>
        </div>
        <div v-else>
            <del>
                {{i+1}}. {{todo.title}} <span class="close" aria-hidden="true" v-on:click.stop="function(e){deleteTodo(e,todo.id)}">&times;</span>
            </del>
        </div>
    </ul>
  </div>
</template>

<script>
  export default {
    name: 'todoList',
    props: ['todos','checkedTodo','deleteTodo']
  };
</script>

<style scoped>
    div {
        width: 100%;
    }
    ul {
        display: flex;
        justify-content: center;
        padding: 0px;
        cursor: pointer;
    }
</style>

여기서 새로운 속성이 나온다.
v-for라는 속성인데, 약간 for-in문과 비슷한 느낌이다.
값이 담길 변수 in 배열이 담긴 변수 이렇게 사용하면, 배열이 순회하며 v-for가 있는 요소가 복사되어 생긴다. 그리고 그 안의 요소들에서는 값이 담기는 변수를 쓸 수 있다.
v-if는 값으로 들어가는 게 true면 render되고 아니면 사라진다.

이제 script에 있는 코드를 보자
name은 다른 곳에서 쓸 이름을 지정하는 것이고
props는 우리가 app에서 넣어준 props들을 여기서 받아온다.

정리

새벽에 쓴 글이라서 정리가 잘 안되었다. 내일 일어나면 정리하겠다.
일단 느낀 바로는, react와 유사하지만 조금 더 직관적이라고 생각했다.
하지만, 내 손가락이 느끼기에는 개발 속도가 영 안났다.
개인적으로 재미있는 개발이였다고 생각한다.

profile
만들고싶은걸만듭니다

0개의 댓글