Vue 인스턴스

new Vue({
  el:,//인스턴스의 시작 지점
  data:,//인스턴스의 데이터 속성
  template:,//인스턴스의 템플릿 속성
  methods:,//이벤트 및 화면 동작 메서드
  created://라이프 사이클 커스텀 로직
});

Vue컴포넌트


전역 컴포넌트
사용 Vue.component()함수를 이용한다.
전역적으로 사용할 수 있다.


#컴포넌트 사용 이유
- 화면을 구조화하여 일괄적인 패턴으로 개발하기 위해
- 화면을 분리하여 재활용할 수 있는 형태로 관리하기 위해
- 코드의 재사용성과 직관성을 높일 수 있다.
#부모와 자식 컴포넌트 간의 통신
- 부모 컴포넌트의 데이터를 자식 컴포넌트에서 참조하기 위해서는 props 옵션을 사용한다.
props를 통해 전달하면 이를 템플릿 내부에서 데이터 처럼 사용할 수 있다.
이 때 자식 컴포넌트에서는 props를 명시적으로 선언해야 한다.
템플릿 내부에서 props를 적을 때는 kebab-case를 사용한다. 그리고 스크립트 내부에서는 camelCase를 사용한다.

[주의사항] 데이터 전달은 부모==> 자식으로 단방향으로 전달되며 자식 컴포넌트는 이를 props로 전달받아 props를 수정하려 해서는 안된다. props는 readonly임에 주의하자.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://www.unpkg.com/vue"></script>
</head>
<body>

    <hr color="blue">
    <div id="app">
        부모 app {{mydata}}
        <child-comp title="첫째 자식" msg="1번이요" your-msg="잘가"></child-comp>
        <child-comp title="둘째 자식" v-bind:msg="mydata"></child-comp>
        <!--
            정적인 data를 props로 전달할 경우: title="~~"
            동적인 data를 props로 전달할 경우: v-bind로 해당 데이터와 연결해야 한다.
            
        -->
    </div>
    <hr color='red'>
    <div id="app2">
        부모 app2 {{yourdata}}
        <child-comp title="Hello Component" msg="3번이요"></child-comp>
    </div>
</body>
<script>
    //전역 컴포넌트 등록.
    //[주의사항] 컴포넌트 이름은 2단어 이상으로 짓는다. (필수)
    Vue.component('child-comp',{
        template:"<div>Child Component - title: {{title}} <h2 style='color:purple'>{{msg}}</h2> {{yourMsg}}</div>"
        ,
        props:['title','msg','yourMsg']
    })

    new Vue({
        el:'#app',
        data(){
            return {
                mydata:'Hi~~'
            }
        }
    }),
    new Vue({
        el:'#app2',
        data(){
            return{
                yourdata:'Hello~'
            } 
        }
    })
</script>
</html>

지역 컴포넌트

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://www.unpkg.com/vue"></script>
    <style>
        div{
            margin:10px;
        }
        h3{
            color:coral;
        }
        .container{
            width: 80%;
            background-color: cornsilk;
            padding: 1em;
            margin: 10px auto;
            color: navy;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>지역 컴포넌트 사용 - components속성을 이용</h1>
        <div id="app">
            {{mydata}}
            <my-comp title="Good"></my-comp>
            <my-comp title="Bye"></my-comp>
        </div>
        <div id="app2">
            {{yourdata}}
            <!--여기서는 my-comp를 사용 못함. 지역 컴포넌트이므로-->
            <my-comp title="잘 나오는가"></my-comp>
        </div>
    </div>
</body>
<script>
    new Vue({
        el:'#app',
        components:{//지역 컴포넌트 등록 : '컴포넌트명' :'컴포넌트 내용'
            'my-comp':{
                template:`I am local Component 
                        <h3>{{title}}</h3>`
                ,
                props:['title']
            }
        },
        data(){
            return{
                mydata:'Hello App'
            }
        }
    });
    new Vue({
        el:'#app2',
        data:{
            yourdata:'나는 app2부모'
        }
    })
</script>
</html>

컴포넌트 통신
자식이 부모에게 데이터를 전달하고자 할 때는 이벤트를 발생시켜서 전달한다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://www.unpkg.com/vue"></script>
</head>
<body>
    <div id="app">
        <h1>부모</h1>
        <h2>부모와 자식 컴포넌트 통신</h2>
        <my-comp title="hello" v-on:go="show"></my-comp>
        <my-comp title="hi"></my-comp>
        <hr color='blue'>
        <h1 style='color:green'>{{parentData}}</h1>
    </div>
</body>
<script>
    var myComp={
        template:`
            <div style='background-color:orange'>MyComp
            <h3 v-on:click="pass">{{title}}</h3>
            </div>
        `,
        props:['title'],
        data(){
            return{
                msg:'myData'
            }
        },
        methods:{
            pass(){
                this.$emit('go','MyComP가 보내는 데이터>>'+this.msg);
            }
        }
    };
    new Vue({
        el:'#app',
        data(){
            return{
                parentData:''
            }
        },
        components:{
            'my-comp' : myComp
        },
        methods:{
            show(val){
                //alert(val);
                this.parentData = val;
            }
        }
    })

</script>
</html>

형제간 통신 (이벤트 버스)
연습문제
react같은 경우는 부모에게 보내고 자식에게 통신해야하지만 Vue는 형제 컴포넌트간 통신이 가능하다

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://www.unpkg.com/vue"></script>
    <style>
        #app{
            width:60%;
            margin:2em auto;
            background-color: beige;
            padding: 2em;
            text-align: center;
        }
        .done{
            color:red;
            text-decoration: line-through;
        }
        .notdone{
            color: blue;
        }
        div{
            margin:10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>To Do App</h1>
        <input-component></input-component>
        <list-component></list-component>
    </div>
    
    <template id="comp1">
        <div>
            <input type="text" @keyup.enter="addToDo" name="task" id="task" placeholder="할 일 입력후 엔터" v-model="todo">
            <button @click="addToDo">입력</button>
        </div>
    </template>

    <template id="comp2">
        <div>
            <ul style="list-style:none;text-align: center;">
                <!--해야할 일들을 반복문 돌면서 출력해보기-->
                <li v-for="(list,i) in todoArr" :key="i" :class="{done:list.done,notdone:!list.done}">
                    {{list.content}}
                    <label><input type="checkbox" v-model="list.done"></label>
                </li>
            </ul>
        </div>
    </template>
</body>
<script>
    var bus=new Vue();
    new Vue({
        el:'#app',
        components:{
            'input-component':{
                template:'#comp1',
                data(){
                    return{
                        todo:''//텍스트박스와 동기화
                    }
                },
                methods:{
                    addToDo(){
                        bus.$emit("insert-todo",this.todo)
                        this.todo="";
                        this.$refs.task.focus();
                    }
                }
            },
            'list-component':{
                template:'#comp2',
                data(){
                    return{
                        todoArr:[
                            {content:'VueJS공부하기',done:false},
                            {content:'카카오준비하기',done:false},
                            {content:'프로젝트하기',done:false},
                            {content:'영화보기',done:true}
                        ]
                    }
                },
                created(){
                    bus.$on('insert-todo',this.addList)
                },
                methods:{
                    addList(val){
                        this.todoArr.push({content:val,done:false})
                    }
                }
            }
        }//Vue components end----
    })
</script>
</html>

To Do App

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="http://www.unpkg.com/vue"></script>
    <style>
        #app{
            width:60%;
            margin:2em auto;
            background-color: beige;
            padding: 2em;
            text-align: center;
        }
        .done{
            color:red;
            text-decoration: line-through;
        }
        .notdone{
            color: blue;
        }
        div{
            margin:10px;
        }
    </style>
</head>
<body>
    <div id="app">
        <h1>To Do App</h1>
        <input-component></input-component>
        <list-component></list-component>
    </div>
    
    <template id="comp1">
        <div>
            <input type="text" name="task" id="task" placeholder="할 일 입력후 엔터" v-model="todo">
            <button>입력</button>
        </div>
    </template>

    <template id="comp2">
        <div>
            <ul style="list-style:none;text-align: center;">
                <!--해야할 일들을 반복문 돌면서 출력해보기-->
                <li v-for="(list,i) in todoArr" :key="i" :class="{done:list.done,notdone:!list.done}">
                    {{list.content}}
                    <label><input type="checkbox" v-model="list.done"></label>
                </li>
            </ul>
        </div>
    </template>
</body>
<script>
    new Vue({
        el:'#app',
        components:{
            'input-component':{
                template:'#comp1',
                data(){
                    return{
                        todo:''//텍스트박스와 동기화
                    }
                }
            },
            'list-component':{
                template:'#comp2',
                data(){
                    return{
                        todoArr:[
                            {content:'VueJS공부하기',done:false},
                            {content:'카카오준비하기',done:false},
                            {content:'프로젝트하기',done:false},
                            {content:'영화보기',done:true}
                        ]
                    }
                }
            }
        }//Vue components end----
    })
</script>
</html>

 

+ Recent posts