9주차 01.26(목) Vue.js

하이·2023년 1월 26일
0

수업

목록 보기
17/41
post-custom-banner

Vue.js

: web UI개발
: MVVM(Model-View-ViewModel)

  • VS code를 Editor로 이용
    : 여러개의 plugin을 이용해서 개발을 쉽고 편하게 할 수 있음 (나중에 설치할 예정)

Vue instance

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
        안녕하세요 {{ myID }}
   </div>
   <script>
        new Vue({
            el: '#app',
            template: '<div>네 안녕하세요</div>'// app의 내용을 template로 덮어씌움
        })
   </script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
        안녕하세요 {{ myID }}
   </div>
   <script>
        new Vue({
            el: '#app',
            // template: '<div>네 안녕하세요</div>'// app의 내용을 template로 덮어씌움
            data:{
                myID: '홍길동',
                myAge: 20
            }
        })
   </script>
</body>
</html>

Component

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
        안녕하세요 {{ this.myID }}
        <my-component></my-component>
        <my-local-component></my-local-component>
   </div>
   <script>
        // 컴포넌트부터 하나 생성해야함
        // 컴포넌트는 자바스크립트 객체.
        let myCmp = {
            template: '<div>여기는 DIV입니다.</div>'
        }
        // 전역 컴포넌트 등록하는 방법
        // vue가 가지고 있는 component. 괄호 안에 component 이름이 들어감
        // component이름은 케밥케이스가 권장됨
        // 2단어 이상으로 구성되는 것을 권장함
        // 만약, 케밥케이스로 사용하지 않을거면 파스칼케이가 권장됨 MyConponent
        // componet 이름은 결국 HTML태그명으로 사용됨
        Vue.component('my-component',myCmp);    

        let loacalCmp = {
            template : '<div>여기는 로컬입니다.</div>'
        }

        // Vue instance
        new Vue({
            el: '#app',
            // template: '<div>네 안녕하세요</div>' // app의 내용을 template로 덮어씌움
            data:{
                myID: '홍길동',
                myAge: 20
            },
            components: {
                'my-local-component': loacalCmp
            }
        })
   </script>
</body>
</html>

Data 속성

: Root component -> Vue instance
: data 속성을 가지고 있음

data: {
	myName:'홍길동'
}

: 다른 하위 component들(전역과 지역에 상관없이)
-> 재사용 목적 -> Root component하단에 여러개가 반복해서 나올 수 있음
-> 그래서 data 속성은 반드시 함수로 표현해야함 : 객체를 리턴해야 함

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
    Root component의 변수값은: {{ myName }}
    <global-component></global-component>
    <global-component></global-component>
    <global-component></global-component>
   </div>

   <script>
        // 전역component 등록
        Vue.component('global-component', {
            template: '<div>변수의 값은: {{ myData }}</div>',
            data: {
                // component가 자체적으로 가지고 있는 값
                myData: 100
            }
        });
        new Vue({
            el: '#app',
            data:{
                myName: '홍길동'
            }
        });
   </script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
    Root component의 변수값은: {{ myName }}
    <global-component></global-component>
    <global-component></global-component>
    <global-component></global-component>
   </div>

   <script>
        // 전역component 등록
        Vue.component('global-component', {
            template: '<div>변수의 값은: {{ myData }}</div>',
            // data: function() {
            //    return{
            //        myData: 200
            //    };
            //}
     		data(){
                return{
                    myData:200
                }
            }
        });
        new Vue({
            el: '#app',
            data:{
                myName: '홍길동'
            }
        });
   </script>
</body>
</html>

component Scope

코드로 알아보기
: component의 data는 scope가 각 component로 한정됨
: 그래서 하나의 component에서 다른 component의 data를 직접적으로 access할 수 없음

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
     <!-- root 하단에 지역 컴포넌트로 뜨게됨 -->
    <my-component1></my-component1>
    <my-component2></my-component2>
   </div>

   <script>
    // 지역 component 2개를 만들어서 사용해 보자
    let cmp1 = {
        template:'<div>첫번째 지역 component : {{ cmp1Data }}</div>',
        data: function(){
            return {
                cmp1Data: 100
            }
        }
    }

    let cmp2 = {
        template:'<div>두번째 지역 component : {{ cmp2Data }}</div>',
        data: function(){
            return {
                // 어떻게 해야 첫번째 component의 data를 사용할 수 있나요?
                // 이렇게 하면 안 됨 (한 컴포넌트에서 다른 컴포넌트의 데이터를 직접 access하는 건 허용X)
                cmp2Data: cmp1.data.cmp1Data
            }
        }
    }
    
    new Vue({
        el:'#app',
        
        components: {
            // 내가 만든 객체를 지역 컴포넌트로 등록
            'my-component1' : cmp1,
            'my-component2' : cmp2
        }
    })

   </script>
</body>
</html>

  • 그럼 어떻게 해야 component간 data통신을 할 수 있나요?
    : Vue가 몇가지 방법을 제공함

Component간 data를 전달하는 방법

전제
: 상위 component -> 하위 component

1. 기본 <component가 상하관계일 때>

230126_Vue04.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
        <child-component></child-component>
   </div>

   <script>
    // 컴포넌트 하나를 전역 컴포넌트로 등록하고
    // Vue instance를 div에 붙임
    // Vue instance에 하위 컴포넌트로 해당 컴포넌트를 포함시킴
    // Vue instance가 상위 component가 되고
    // 포함되는 전역 컴포넌트는 하위 component가 됨
    // props를 이용하면 상위 component에서 하위 component로 데이터 전달 가능 !!
    // Vue instance의 data를 전역 컴포넌트에게 전달 가능

    // 컴포넌트 하나를 전역 컴포넌트로 등록하고
    Vue.component('child-component',{
        // 이 컴포넌트는 화면에 어떻게 보일 것인가 명시
        data(){
            return {
                myData: 200
            }
        },
        template: '<div>여기는 하위 컴포넌트! => {{ myData }}</div>'
    })
    // Vue instance를 div에 붙임
    // Vue instance에 하위 컴포넌트로 해당 컴포넌트를 포함시킴
    new Vue({
        el: '#app'
    })
   </script>
</body>
</html>

props를 이용한 데이터 통신

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
    <!-- chlid-component(하위 컴포넌트가) 가지고 있는 v-bind : 케밥스타일 props-Data:"여기 안에는"  상위컴포넌트의 데이터가 들어감 -->
        <child-component v-bind:props-Data="message"></child-component>
   </div>

   <script>
    // 컴포넌트 하나를 전역 컴포넌트로 등록하고
    // Vue instance를 div에 붙임
    // Vue instance에 하위 컴포넌트로 해당 컴포넌트를 포함시킴
    // Vue instance가 상위 component가 되고
    // 포함되는 전역 컴포넌트는 하위 component가 됨
    // props를 이용하면 상위 component에서 하위 component로 데이터 전달 가능 !!
    // Vue instance의 data를 전역 컴포넌트에게 전달 가능

    // 컴포넌트 하나를 전역 컴포넌트로 등록하고
    Vue.component('child-component',{
        // 이 컴포넌트는 화면에 어떻게 보일 것인가 명시
        // data(){
        //    return {
        //        myData: 200
        //    }
        // },
        // props를 이용해서 상위 컴포넌트가 전달하는 데이터를
        // []안에 변수를 선언함(변수는 카멜케이스가 기본)
        // props: ['propsData', 'secondData'],
        // 위에보다 밑에 형식 권장 !
        props: {
            propsData : String, // value값은 데이터타입을 나타내는 생성자 함수
                                // propsData에게 데이터를 주려면 div로 올라가서 v-bind
        },
        template: '<div>여기는 하위 컴포넌트! => {{ propsData }}</div>'
    })
    // Vue instance를 div에 붙임
    // Vue instance에 하위 컴포넌트로 해당 컴포넌트를 포함시킴
    new Vue({
        el: '#app',
        data: {
            message : '소리없는 아우성!'
        }
    })
    // Vue instance가 상위 component가 되고
    // 포함되는 전역 컴포넌트는 하위 component가 됨
    // props를 이용하면 상위 component에서 하위 component로 데이터 전달 가능 !!
    // Vue instance의 data를 전역 컴포넌트에게 전달 가능

   </script>
</body>
</html>



2. 하위component에서 상위component로 데이터를 전달

: 하위 component에서 event를 emit시켜서 상위 component에게 신호를 보내면 됨

230126_Vue05.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
    <child-component></child-component>
   </div>

   <script>
        // 전역 component로 만들고, Root Component의 하위로 사용
        Vue.component('child-component',{
            template: '<button v-on:click="childFunc">클릭클릭</button>', //버튼에서 클릭이라는 이벤트가 발생하면 =뒤쪽에 이벤트 상위컴포넌트의 함수명
            data(){
                return {
                    // 변수는 여기
                    myData: 200
                }
            },
            methods: {
                // 함수는 여기
                childFunc: function(){
                    alert('버튼이 클릭되었어요');
                } 
            }
        });

        new Vue({
            el: '#app'
        });
   </script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
   <div id="app">
    <child-component v-on:print_msg="printText"></child-component>
   </div>

   <script>
        // 전역 component로 만들고, Root Component의 하위로 사용
        Vue.component('child-component',{
                        //버튼에서 click 이벤트가 발생하면 =뒤쪽에 이벤트 상위컴포넌트의 함수명 을 호출
            template: '<button v-on:click="childFunc">클릭클릭</button>', 
            data(){
                return {
                    // 변수는 여기
                    myData: 200
                }
            },
            methods: {
                // 함수는 여기
                childFunc: function(){
                    this.$emit('print_msg', 100, 'Hello', {
                        msg: '전달된 이벤트'
                    });
                } 
            }
        });

        new Vue({
            el: '#app',
            methods: {
                printText: function(...args) {
                    console.log('이벤트 발생');
                    console.log(args[0]);
                    console.log(args[1]);
                    console.log(args[2].msg);

                }
            }
        });
   </script>
</body>
</html>

버튼을 누르면 event를 전달하면서 data도 같이 전달

3. EventBus

코드로 알아보기
230126_Vue06.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
    <!-- EventBus를 이용해서 하위component에서 상위component로 event를 전달 -->
   <div id="app">
        <child-component></child-component>
   </div>

   <script>
        // EventBus를 이용하기 위해 Vue instance를 생성
        let eventBus = new Vue();
        // 하위 component로 사용할 전역 component를 등록
        Vue.component('child-component',{
            template: '<button v-on:click="btnClick">클릭클릭</button>',
            methods: {
                btnClick: function(){
                    // eventBus에 대해서 event를 발생시킴
                    eventBus.$emit('generateEvent', 300);
                }
            }
        });

        // Root Component
        new Vue({
            el: '#app',
            created: function(){
                // eventBus에 대해 이벤트를 등록함 : $on
                // 'generateEvent'가 발생하면 function 한다는 의미
                eventBus.$on('generateEvent', function(value){
                    console.log('이벤트 발생!', value);
                })
            }

        })
   </script>
</body>
</html>

버튼을 누르면 eventBus를 통해 발생



230126_Vue06_exec.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
   <!-- jQuery를 사용하기 위한 CDN을 설정 -->
   <script src="https://code.jquery.com/jquery-3.6.3.min.js" integrity="sha256-pvPw+upLPUjgMXY0G+8O0xUf+/Im1MZjXxxgOcBQBXU=" crossorigin="anonymous"></script>
   <script src="./js/230119_jQuery07.js"></script>

    <!-- Vue.js를 이용해보아요! CDN을 포함시켜요 -->
    <script src="https://cdn.jsdelivr.net/npm/vue@2.7.14/dist/vue.js"></script>

</head>
<body>
    <!-- EventBus를 이용해서 하위component에서 상위component로 event를 전달 -->
   <div id="app">
        <global-component-a></global-component-a>
        <global-component-b></global-component-b>
   </div>

   <script>
       // 전역변수 생성
       Vue.component('global-component-a',{
            template: `<div>
            <local-component-c></local-component-c>
            <local-component-d></local-component-d>
            </div>`,
            components: {
                // 어떤 컴포넌트가 지역변수로 있는지 나옴
                'local-component-c':{
                    template : '<div>local component c</div>'
                    
                },
                'local-component-d':{
                    template : '<div>처리된 데이터: {{ }}</div>'
                },
            }
       });

       Vue.component('global-component-b',{
            template:'<local-component-f></local-component-f>',
            components: {
                'local-component-f': {
                    template: `
                    <div>
                        <input type=text id='inputTxt'>
                        <button v-on:click="btnClick">클릭클릭</button>
                    </div>
                    `,
                    methods: {
                        btnClick: function(){
                           alert($('#inputTxt').val());
                        }   
                    }
                }
            }
       });

       new Vue({
            el: '#app'
       })
   </script>
</body>
</html>

profile
기록의 즐거움 😆💻
post-custom-banner

0개의 댓글