Vue.js_1일차

써니·2022년 12월 24일
0

vue.js

목록 보기
1/15

Vue.js 시작

⚙️설치 프로그램




⚙️플로그인 설치


vuetr, material icon, night owl, live server, ESLint, Prettier, Auto Close Tag, Atom Keymap 설치




✔️색, 아이콘 변경

  • 아래쪽 톱니바퀴에서 icon theme 선택
  • 아래로 내리면서 선택할 수 있음
  • color theme에서 night owl 설정

❌chrome 브라우저 열리지 않는 현상해결

live Server setting에서 chorme를 설정 후 host 내 ip주소를 넣어준다




Vue란?

  • View -> 브라우저에서 사용자가 보는 요소(HTML)
  • DOM Listeners -> 이벤트를 뷰에서 창취, 그리고 이벤트를 잡아서 자바스크립트에서 실행
  • Data Bindings -> 데이터가 바뀔때 반영하게 도와줌



Data Bindings

프로젝트 만들기

! + tab -> html/head/body 자동생성

html vs Javascript

html은 화면 그대로 보이는 것
Javascript는 값을 변화시키는 것
-> 처음 선언해준 값을 갱신시킬 때 그대로 반영되지 않고 바뀐 값을 다시 화면에 넣어줘야 갱신된 값을 출력할 수 있음

html 태그를 정의하고 그 태그의 정보를 받아와서 특정 변수에 담긴 값 출력

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <script>
     //console.log(div);
     var div =  document.querySelector('#app');
     var str = 'hello world';
     div.innerHTML = str;

     str = 'hello world!!!';
     div.innerHTML = str; // 갱신된 값을 다시 넣어줘야 화면에 출력
    </script>
</body>
</html>

Object.defineProperty()

공식문서 설명
객체를 동작을 재정의하는 API

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <script>
     var div = document.querySelector('#app');
     var viewModel = {};

    //  Object.defineProperty(대상 객체, 객체의 속성, {
    //     // 정의할 내용
    //  })

    Object.defineProperty(viewModel, 'str', {
        // 속성에 접근했을 때의 동작을 정의
        get: function() {
            console.log('접근');
        },
        // 속성에 값을 할당했을 때의 동작을 정의
        set: function(newValue) {
            console.log('할당', newValue);
            div.innerHTML = newValue;
        }
    });
    </script>
</body>
</html>


즉시 실행 함수

공식문서
즉시 실행 함수란?
-> 정의하자마자 실행되는 함수

(function () {
    statements
})();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <script>
     var div = document.querySelector('#app');
     var viewModel = {};

    //  Object.defineProperty(대상 객체, 객체의 속성, {
    //     // 정의할 내용
    //  })
    
    (function() {
        function init() {
            Object.defineProperty(viewModel, 'str', {
                // 속성에 접근했을 때의 동작을 정의
                get: function () {
                    console.log('접근');
                },
                // 속성에 값을 할당했을 때의 동작을 정의
                set: function (newValue) {
                    console.log('할당', newValue);
                    div.innerHTML = newValue;
                    render(newValue);
                }
            });
        }

        function render(value) {
            div.innerHTML = value;
        }

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

🔨개발자도구-Vue

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Getting Started</title>
</head>

<body>
    <div id="app">
        {{ message }}
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        new Vue({
            el: '#app',
            data: {
                message: 'Hello Vue.js'
            }
        })
    </script>
</body>
</html>

컴포넌트안에서 편집도 가능하고 바로 페이지에서 반영도 가능!


Vue 사용해보기

vue를 선언해줘야함
그리고 가장 중요한건 특정 태그를 el:로 지정해줘야함❗

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- ... -->
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm = new Vue({
            el: '#app', // 무조건 el 지정(특정 태그에 지정해야함)
            data: {
                message: 'hi'
            }
        });

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




📌인스턴스 함수

생성자 함수

fucntion 다음 대문자로 선언하면 생성자를 선언하겠다는 뜻

기본적인 생성자 함수 예시


new Vue() 사용하는 이유

생성자 함수1
생성자 함수2


인스턴스 속성 / API

인스턴스에서 사용할 수 있는 속성 / API

key / value 형태로 들어옴

new Vue({
  el: ,
  template: ,
  data: ,
  methods: ,
  created: ,
  watch: ,
});
  • el : 인스턴스가 그려지는 화면의 시작점 (특정 HTML 태그)
  • template : 화면에 표시할 요소 (HTML, CSS 등)
  • data : 뷰의 반응성(Reactivity)이 반영된 데이터 속성
  • methods : 화면의 동작과 이벤트 로직을 제어하는 메서드
  • created : 뷰의 라이프 사이클과 관련된 속성
  • watch : data에서 정의한 속성이 변화했을 때 추가 동작을 수행할 수 있게 정의하는 속성

원래는 var options = {} 객체안에 담아서 var vm = new Vue(options) 담지만 가독성을 위해 위에서 생성자를 생성하는 동시에 속성 및 api를 선언

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- ... -->
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // var options =
        var vm = new Vue({
            el: '#app', // 무조건 el 지정(특정 태그에 지정해야함)
            data: {
                message: 'hi'
            },
            methods: {
            },
            created: function() {
            }
        });
    </script>
</body>
</html>



📚뷰 컴포넌트

코드의 재사용성 높임


전역 컴포넌트

(실습)뷰 컴포넌트

인스턴스를 생성하면 root 컴포넌트가 됨
Vue.component('컴포넌트 이름', 컴포넌트 내용);

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
        <app-content></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // Vue.component('컴포넌트 이름', 컴포넌트 내용);
        // 전역 컴포넌트
        Vue.component('app-header', {
            template: '<h1>Header</h1>'
        });
        Vue.component('app-content', {
            template: '<div>content</div>'
        });
        new Vue({
            el: '#app' // 인스턴스를 생성해서 태그에 붙이겠다.
        });
    </script>
</body>
</html>


지역 컴포넌트

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
        <app-content></app-content>
        <app-footer></app-footer>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // Vue.component('컴포넌트 이름', 컴포넌트 내용);
        // 전역 컴포넌트
        Vue.component('app-header', {
            template: '<h1>Header</h1>'
        });
        Vue.component('app-content', {
            template: '<div>content</div>'
        });
        new Vue({
            el: '#app', // 인스턴스를 생성해서 태그에 붙이겠다.
            // 지역 컴포넌트
            components: {
                // '키' : '값'
                // '컴포넌트 이름' : '컴포넌트 내용'
                'app-footer' : {
                    template: '<footer>footer</footer>'
                }
            }
        });
    </script>
</body>
</html>


🤔전역 vs 지역 컴포넌트

보통 여러개를 정의할 때는 -s까지 붙여야한다.
ex) components

  • 지역 컴포넌트
    -- 특정 컴포넌트 하단의 어떤 것이 등록되었는지 컴포넌트 속성에서 알 수 있다.
    일반적으로 서비스를 구현할 때는 컴포넌트를 사용하여 계속 아래로 그린다.
  • 전역 컴포넌트
    -- 대부분 플러그인이나 라이브러리처럼 전역으로 사용하는 경우메만 사용

컴포넌트와 인스턴스의 관계

인스턴스를 생성할 때마다 컴포넌트를 생성해줘야하는 것이 지역 컴포넌트
전역 컴포넌트를 선언하면 그럴 필요 없지만 보통은 지역 컴포넌트를 쓴다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
        <!-- <app-content></app-content> -->
        <app-footer></app-footer>
    </div>

    <div id="app2">
        <app-header></app-header>
        <!-- <app-content></app-content> -->
        <app-footer></app-footer>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        // Vue.component('컴포넌트 이름', 컴포넌트 내용);
        // 전역 컴포넌트
        Vue.component('app-header', {
            template: '<h1>Header</h1>'
        });
        // Vue.component('app-content', {
        //     template: '<div>content</div>'
        // });
        new Vue({
            el: '#app', // 인스턴스를 생성해서 태그에 붙이겠다.
            // 지역 컴포넌트
            components: {
                // '키' : '값'
                // '컴포넌트 이름' : '컴포넌트 내용'
                'app-footer' : {
                    template: '<footer>footer</footer>'
                }
            }
        });

        new Vue({
            el: '#app2',
            components: {
                'app-footer': {
                    template: '<footer>footer</footer>'
                }
            }
        });
    </script>
</body>
</html>


📡컴포넌트 통신

위에서 아래로는 데이터 전달 / 아래서 위로는 이벤트 발생

🤔만약? 컴포넌트가 제대로 선언이 안되어 있는 경우를 생각해보자

그렇다고 한다며 어디서 이벤트가 발생하고 데이터가 전달되는지 파악하기 어렵다.

❗❗ 하지만 초기에 설정은 복잡할 수 있지만 선언을 제대로 해준다면?

이런식으로 어디서 데이터(Props)가 움직이고 event가 어디서 발생하는 지
데이터의 흐름을 추적할 수 있다.


Props

v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message"></app-header>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>header</h1>',
            props: ['propsdata']
        }

        new Vue({
            el: '#app',
            components: {
                'app-header' : appHeader
            },
            data: {
                message: 'hi'
            }
        })
    </script>
</body>
</html>

{{propsdata}}

상위 컴포넌트 데이터가 바뀌면 props도 따라간다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message"></app-header>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>{{propsdata}}</h1>',
            props: ['propsdata']
        }

        new Vue({
            el: '#app',
            components: {
                'app-header' : appHeader
            },
            data: {
                message: 'hi'
            }
        })
    </script>
</body>
</html>

(실습) Props

reactivity -> 상위 값이 바뀌면 하위 값도 같이 바뀐다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 데이터 이름"></app-header> -->
        <app-header v-bind:propsdata="message"></app-header>
        <app-content v-bind:propsdata="num"></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<h1>{{propsdata}}</h1>',
            props: ['propsdata']
        }

        var appContent = {
            template: '<div>{{propsdata}}</div>',
            props: ['propsdata']
        }

        new Vue({
            el: '#app',
            components: {
                'app-header' : appHeader,
                'app-content' : appContent
            },
            data: {
                message: 'hi',
                num : 10
            }
        })
    </script>
</body>
</html>


event emit

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<button v-on:click="passEvent">click me</button>',
            methods: {
                passEvent: function() {
                    this.$emit('pass')
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader
            }
        });
    </script>
</body>
</html>


event emit 콘솔 출력

하위컴포넌트에서 발생한 이벤트를 상위 컴포넌트에서 출력

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트 이름="상위 컴포넌트 메서드 이름"></app-header> -->
        <app-header v-on:pass="logText"></app-header>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<button v-on:click="passEvent">click me</button>',
            methods: {
                passEvent: function() {
                    this.$emit('pass')
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader
            },
            methods: {
                logText: function() {
                    console.log('hi');
                }
            }
        });
    </script>
</body>
</html>


(실습) event emit

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p>{{ num }}</p>
        <!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트 이름="상위 컴포넌트 메서드 이름"></app-header> -->
        <app-header v-on:pass="logText"></app-header>
        <app-content v-on:increase="increaseNumber"></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<button v-on:click="passEvent">click me</button>',
            methods: {
                passEvent: function() {
                    this.$emit('pass')
                }
            }
        }

        var appContent = {
            template: '<button v-on:click="addNumber">add</button>',
            methods: {
                addNumber: function() {
                    this.$emit('increase')
                }
            },
            
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            methods: {
                logText: function() {
                    console.log('hi');
                },
                // 메서드 정의
                increaseNumber: function() {
                    this.num = this.num + 1;
                }
            },
            data: {
                num: 10
            }
        });
    </script>
</body>
</html>


this

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <div id="app">
        <p>{{ num }}</p>
        <!-- <app-header v-on:하위 컴포넌트에서 발생한 이벤트 이름="상위 컴포넌트 메서드 이름"></app-header> -->
        <app-header v-on:pass="logText"></app-header>
        <app-content v-on:increase="increaseNumber"></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<button v-on:click="passEvent">click me</button>',
            methods: {
                passEvent: function () {
                    this.$emit('pass')
                }
            }
        }

        var appContent = {
            template: '<button v-on:click="addNumber">add</button>',
            methods: {
                addNumber: function() {
                    this.$emit('increase')
                }
            }
        }

        var vm = new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            methods: {
                logText: function () {
                    console.log('hi');
                },
                increaseNumber: function() {
                    this.num = this.num + 1;
                }
            },
            data: {
                num: 10
            }
        });
    </script>
</body>

</html>

여기서 new Vue를 var vm이라는 변수로 선언하고 console.log에 찍었을 때 결과 값을 살펴 보자

👉 console.log(vm) 했을 때 객체 Vue가 불러와지고 안에 num 값이 들어있다. 따라서 this.num은 Vue 객체의 num이라는 것이다.


📡같은 레벨에서의 컴포넌트 통신 방법

root -> 인스턴스
같은 레벨의 컴포넌트인 appcontent, appHeader
🤔AppContent 에서 AppHeader를 어떻게 전달할까?


AppContent에서 AppHeader로 갈 수 있는 길은 막혀 있다.
따라서 AppContent에서 event로 올려주고 root에서 AppHeader로 데이터를 전달하는 방식을 사용해야한다.

event 전달

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
        <app-content></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<div>header</div>'
        }
        var appContent = {
            template: '<div>content<button v-on:click="passNum">pass</button></div>',
            methods: {
                passNum: function() {
                    this.$emit('pass', 10);
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            }
        });
    </script>
</body>
</html>


data 선언

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <app-header></app-header>
        <app-content></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<div>header</div>'
        }
        var appContent = {
            template: '<div>content<button v-on:click="passNum">pass</button></div>',
            methods: {
                passNum: function() {
                    this.$emit('pass', 10);
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            data: {
                num: 0
            }
        });
    </script>
</body>
</html>


Props 데이터 전달

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p>{{ num }}</p>
        <!-- <app-header v-bind:프롭스 속성 이름="상위 컴포넌트의 이름"></app-header> -->
        <app-header v-bind:propsdata="num"></app-header>
        <!-- app-content v-on:pass="deliverNum(value)"></app-content> -->
        <app-content v-on:pass="deliverNum"></app-content>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var appHeader = {
            template: '<div>header</div>',
            props: ['propsdata']
        }
        var appContent = {
            template: '<div>content<button v-on:click="passNum">pass</button></div>',
            methods: {
                passNum: function() {
                    this.$emit('pass', 10);
                }
            }
        }

        new Vue({
            el: '#app',
            components: {
                'app-header': appHeader,
                'app-content': appContent
            },
            data: {
                num: 0
            },
            methods: {
                deliverNum: function(value) {
                    this.num = value;
                }
            }
        });
    </script>
</body>
</html>

  1. AppContent에서 인자 10을 담은 이벤트 발생
  2. deliverNum(value)를 따로 써주지 않아도 value값을 가져감
  3. value값을 this.num(data의 num)에 담음
  4. 변화된 data값을 가지고 props로 데이터를 AppHeader에 전달

🔍뷰 라우터

뷰 라우터란?
뷰 라이브러리를 이용하여 페이지 이동은 하지 않고 싱글 페이지 애플리케이션을 구현할 때 사용하는 라이브러리

뷰 라우터 설치

cdn-vue router download

👇 아래 코드를 넣어줌 - 꼭 vue.js 다음 라우터 script를 넣어줘야함

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>

router : router 에서 오른쪽이 내가 선언해준 var router
공식문서에서 변수를 저런 식으로 선언함

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app"></div>

    <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router@3.5.3/dist/vue-router.js"></script>
    <script>
        var router = new VueRouter({

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

0개의 댓글