9주차 01.27(금) Vue.js

하이·2023년 1월 27일
0

수업

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

-- 1페이지 필기
event 전달

  • Vue instance
  • component
    • 상위component/하위component
    • 전역 component/지역 component

{~~~} -> component
: 특수한 property(속성)들이 들어감
(template, data, methods, components, props)

component data 전달
1. props
2. event 처리

230126_Vue06_example 코드 & 사진

Routing

: 웹페이지간의 이동을 의미
: 우리는 지금 SPA를 하고 있음
: 그래서 전체 page를 다시 그리는게 아니라, 필요한 부분만 다시 그리는 방식으로 page 전환

router.js

: Routing 라이브러리 중 가장 대표적인 것
: React, Anguler, Vue 범용
: Vue.js에서는 Vue 라우터(Vue.js의 공식 library)를 이용

Vue 라우터를 위한 CDN

<script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>

230127_Vue01.html
코드넣기

누르면



Nested Routing

<!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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
</head>
<body>
   <div id="app">
        <!-- router-link가 없어도 router view는 있어야됨 -->
        <router-view></router-view>
   </div>

   <script>
        // member component 생성
        let memberComponent = {
            template: `<div>
                    여기는 member component입니다.
                    <router-view></router-view>
            </div>`
            // nested routing 가능하도록 router-view 잡아줌
        }

        // profile component 생성
        let profileComponent = {
            template: '<div>여기는 profile component</div>'
        }

        // post component 생성
        let postComponent = {
            template: '<div>여기는 post component</div>'
        }

        // 컴포넌트 다 만들었고, 이제 경로 설정
        // 어떤 경로가 어떤 컴포넌트와 매칭되는지 설정
        // routes => 경로들
        let routes = [{
            path: '/member', // 이 경로가 들어오면
            component: memberComponent,
            // children라우팅 안에서 라우팅을 한번 더 잡아줌
            // 22번 <router-view></router-view>에 .. 
            children: [{
                path: '/profile',    // /member/profile
                component: profileComponent
            },{
                path: '/post',      // /member/post
                component: postComponent
            }]
        }]

        // 경로를 만든 후, VueRouter객체 생성
        let router = new VueRouter({
            // routes: routes 는 아래와 같은 의미
            routes
        })

        // 1. Root component(mount가 붙어있으니까)
        new Vue({
            router
        }).$mount('#app')
   </script>
</body>
</html>

url 주목!



Named View

<!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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
</head>
<body>
    <!-- EventBus를 이용해서 하위component에서 상위component로 event를 전달 -->
   <div id="app">
        <!-- router-link가 없어도 router view는 있어야됨 -->
        <!-- 하나의 url에 대해서 하나의 component를 넣는게 기본이었음 -->
        <!-- named View : 하나의 url에 대해서 여러개의 component를 내가 원하는 위치에 넣어보자 -->
        <!-- 각각의 router-view에 이름을 줌 -->
        <!-- 이름을 지정하지 않으면 default. -->
        <router-view name="header"></router-view>
        <router-view></router-view>
        <router-view name="footer"></router-view>
        
   </div>

   <script>
       // 3개의 component 생성
       let headerCmp = {
            template: '<div>여기는 Header</div>'
       }
       let bodyCmp = {
        template: '<div>여기는 Body</div>'
       }
        let footerCmp = {
            template: '<div>여기는 Footer</div>'
       }   

       let router = new VueRouter({
            routes : [{
                path: '/',  // 이 url에 component를 여러개 쓰겠다 => components
                components: {
                    header: headerCmp,
                    footer: footerCmp,
                    default: bodyCmp
                }
            }]
       })

       new Vue({
            router
       }).$mount('#app')
   </script>
</body>
</html>



Vue의 HTTP통신

(외부 API를 호출해서 결과를 가져오고 싶음)
: 기존에는 JQuery가 제공하는 AJAX문법을 이용하여 처리해봄
: $.ajax({})

: Vue에서는 AJAX를 어떻게 해야하나요?
: (Vue resource라는 공식 library가 없어지고) Axios라는 외부 library
: JQuery와 대동소이

: 사용하려면 CDN

<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

230127_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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
   <div id="app">
        <button v-on:click="myFunc">AJAX 호출</button>
   </div>

   <script>
       new Vue({
            methods:{
                myFunc: function(){
                    // Axios를 이용한 AJAX 호출
                    // $.ajax({
                    //    success: function() {}
                    // });
                    // axios정보로 요청하고 성공하면 then, 실패하면 catch
                    axios({
                        // 영화진흥위원회 openAPI
                        url: 'http://www.kobis.or.kr/kobisopenapi/webservice/rest/boxoffice/searchDailyBoxOfficeList.xml',
                        method: 'GET',
                        // data는 POST, PUT, DELETE 메소드방식에만 적용 가능
                        // data: {
                        //    
                        // }
                        // params는 URL parameter를 지칭함
                        // Query String 방식으로 전달되는 데이터를 의미. 당연히 GET방식 !
                        // params를 이용해 데이터를 넘겨줌
                        params:{
                            key:'8af68cecd7d222e2af7cafbc370d06d9',
                            targetDt: '20230101'
                        },
                        // json이 기본값이라 안 써도 됨
                        responseType: 'json'
                    }).then(function() {
                        alert('호출성공!')
                    }).catch(function() {
                        alert('호출실패!')
                    });

                }
            }
       }).$mount('#app');
   </script>
</body>
</html>



Template의 속성

① template속성을 이용하여 component를 화면에 출력
: 이 방법은 쉽고 간단하지만, 한계가 있음
Single File Component 방식
: <template> </template>

Data Binding

: JavaScript객체의 data(Model)를 화면에 표현하기 위해 특수한 표기법으로 연동하는 것
: {{ }} Mustache Syntax

: v-bind
: directive : v-로 시작하는 tag 속성 ( v-on, v-bind... )

{{ }}
: text interpolation(텍스트 삽입)
v-bind
: HTML의 tag속성(attribute)
: id의 값을 객체와 연동할 때 사용,
: class..
: <div id='app'>에서 id

  • {{ }}의 다양한 사용법
    ① 한글자씩 잘라서 배열에 넣음
    ② 배열내용을 역순으로 뒤집음
    ③ 배열 안의 내용을 뽑아서 하나로 합침

230127_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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
    <!-- EventBus를 이용해서 하위component에서 상위component로 event를 전달 -->
   <div id="app">
      안녕하세요 ! {{ message }}
   </div>

   <script>
      new Vue({
            // template으로 덮어씌움
            //  div로 감싸야함 왜???? 
            template: `<div>
                하이하이 {{ message }}
            </div>`,
            data: {
                message: '홍길동'
            }
      }).$mount('#app');
   </script>
</body>
</html>


230127_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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <style>
        .myStyle{
            background-color: skyblue;
        }
    </style>
</head>
<body>
    <!-- EventBus를 이용해서 하위component에서 상위component로 event를 전달 -->
   <div id="app">
     <div v-bind:id="myID">소리없는 아우성!</div>
     <div>텍스트연동은: {{ message }}</div>
     <div v-bind:class="styleValue">스타일 연동</div>
     <!-- v-bind는 생략 가능 -->
     <div v-bind:class="styleValue">스타일 연동</div>
     <my-component v-bind:my-data="message"></my-component>
   </div>

   <script>
      // 컴포넌트를 {}생성하면서, Vue.component로 전역컴포넌트로 등록
      Vue.component('my-component', {
        props : ['myData'],
        template: '<div>전달된 데이터: {{ myData}} </div>'
      });

      new Vue({
            data: {
                message: '소리없는 아우성!',
                myID: 'myDiv',
                styleValue: 'myStyle'          
            }
      }).$mount('#app');
   </script>
</body>
</html>



  • {{ }}의 다양한 사용법
    ① 한글자씩 잘라서 배열에 넣음
    ② 배열내용을 역순으로 뒤집음
    ③ 배열 안의 내용을 뽑아서 하나로 합침

230127_Vue07.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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <div id="app">
     <div>{{ message }}</div>
     <div>{{ message  + "!!!" }}</div>
     
     <!-- 아래의 표현은 가능하지만 좋지 X -->
     <!-- {{ }}는 가능한 값만 출력하는 역할을 하는게 좋음 -->
     <!-- 아래와 같은 경우는 함수를 따로 만들어서 사용하는게 좋음 -->
     <div>{{ message.split('').reverse().join('') }}</div>
     
     <!-- <div>{{ let a = 100; }}</div> 이런 거 안 됨 -->
     <!-- <div>{{ if(true){ return 100 }}}</div> 이런 거안 됨-->
    
     <div>{{ true ? 10 : 100 }}</div>

     <!-- 이 코드는 좋지 않아서 함수를 따로 만들어보자 -->
     <div>{{ message.split('').reverse().join('') }}</div>
     <!-- 이렇게 바꿈 -->
     <div>{{ myFunc() }}</div>
     <div>{{ myFunc() }}</div>

     <!-- 이런 함수와 약간 다른 성능이 좋은 기능이 있음 -->
     <div>{{ myComputed }}</div>
   </div>

   <script>
      new Vue({
            data: {
                message: '소리없는 아우성',        
            },
            // methods는 안에 있는 함수를 명시적으로 호출
            methods: {
                myFunc: function(){
                    console.log('함수호출');
                    return this.message.split('').reverse().join('')
                }
            },
            // 용도에 따라 
            // methods는 함수, computed는 변수
            // methods보다 computed가 효율적
            // computed는 명시적으로 호출하는게 아니라
            // 데이터가 변경되는 시점에 미리 계산된 결과를 가져다씀
            computed: {
                myComputed: function(){
                    console.log('Computed호출');
                    return this.message.split('').reverse().join('')
                }
            }
      }).$mount('#app');
   </script>
</body>
</html>



directive

: HTML속성에 나오는v- 접두사를 가지는 모든 속성
: v-on:, v-bind: ...

① v-if
② v-show
③ v-bind
④ v-on
⑤ v-model
: form에서 사용
: 사용자가 입력한 데이터를 component의 data와 연동 가능
: + watch의 속성까지 알아봤음
⑥ v-for : 반복처리


v-if & v-show

<!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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <div id="app">
        <div v-bind:id="myID">소리없는 아우성</div>
        <!-- 만약 v-if의 값이 false면 DOM에서(구성요소에서) 제거 -->
        <a v-if="flag" href="http://www.naver.com">네이버로 가기</a>
        <br><br>
        <!-- v-show의 값이 false일 경우, 화면에서 안 보이지만 DOM에는 존재함 -->
        <a v-show="flag" href="http://www.kakao.com">카카오로 가기</a>
   </div>

   <script>
      
    // Vue instance  
      new Vue({
        data:{
            // flag가 false면 DOM에서(구성요소에서) 제거
            flag: false,
            myID: 'myDIV'
        }
      }).$mount('#app');

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

v-show는 false일 경우, 화면에서 안 보이지만 DOM에는 존재함

<!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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <div id="app">
        <div v-bind:id="myID">소리없는 아우성</div>
        <!-- 만약 v-if의 값이 false면 DOM에서(구성요소에서) 제거 -->
        <a v-if="flag" href="http://www.naver.com">네이버로 가기</a>
        <br><br>
        <!-- v-show의 값이 false일 경우, 화면에서 안 보이지만 DOM에는 존재함 -->
        <a v-show="flag" href="http://www.kakao.com">카카오로 가기</a>
        <br><br>
        <input v-model="myTxt">
        <button v-on:click="myFunc">입력상자 안 내용을 알아보아요!</button>
   </div>

   <script>
      
    // Vue instance  
      new Vue({
        data:{
            // flag가 false면 DOM에서(구성요소에서) 제거
            flag: false,
            myID: 'myDIV',
            myTxt: ''
        },
        methods: {
            myFunc: function(){
                alert(this.myTxt);
            }
        }
      }).$mount('#app');

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


v-model + watch

<!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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <div id="app">
        <div v-bind:id="myID">소리없는 아우성</div>
        <!-- 만약 v-if의 값이 false면 DOM에서(구성요소에서) 제거 -->
        <a v-if="flag" href="http://www.naver.com">네이버로 가기</a>
        <br><br>
        <!-- v-show의 값이 false일 경우, 화면에서 안 보이지만 DOM에는 존재함 -->
        <a v-show="flag" href="http://www.kakao.com">카카오로 가기</a>
        <br><br>
        <input v-model="myTxt">
        <button v-on:click="myFunc">입력상자 안 내용을 알아보아요!</button>
   </div>

   <script>
      
    // Vue instance  
      new Vue({
        data:{
            // flag가 false면 DOM에서(구성요소에서) 제거
            flag: false,
            myID: 'myDIV',
            myTxt: ''
        },
        methods: {
            myFunc: function(){
                alert(this.myTxt);
            }
        },
        watch: {
            myTxt: function(data){
                console.log(data, '로 변경되었어요!');
            }
        }
      }).$mount('#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>
    <!-- Vue 라우터를 위한 CDN을 포함시킴 (*버전 주의) -->
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <!-- Axios를 위한 CDN -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    
</head>
<body>
   <div id="app">
        <div v-bind:id="myID">소리없는 아우성</div>
        <!-- 만약 v-if의 값이 false면 DOM에서(구성요소에서) 제거 -->
        <a v-if="flag" href="http://www.naver.com">네이버로 가기</a>
        <br><br>
        <!-- v-show의 값이 false일 경우, 화면에서 안 보이지만 DOM에는 존재함 -->
        <a v-show="flag" href="http://www.kakao.com">카카오로 가기</a>
        <br><br>
        <input v-model="myTxt">
        <button v-on:click="myFunc">입력상자 안 내용을 알아보아요!</button>
        <br><br>
        <ul>
            <li v-for="name in names">{{ name }}</li>
        </ul>
   </div>

   <script>
      
    // Vue instance  
      new Vue({
        data:{
            // flag가 false면 DOM에서(구성요소에서) 제거
            flag: false,
            myID: 'myDIV',
            myTxt: '',
            names:['홍길동', '신사임당', '강감찬']
        },
        methods: {
            myFunc: function(){
                alert(this.myTxt);
            }
        },
        watch: {
            myTxt: function(data){
                console.log(data, '로 변경되었어요!');
            }
        }
      }).$mount('#app');

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



Sigle File Component

:Vue CLI를 이용한 Sigle File Component 체계

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

0개의 댓글