Vue 코딩을 하다가 에러가 나면 이 글을 확인해라

이은지·2021년 8월 16일
0

[뷰js 2 (vuejs 2) 기초 익히기 기본 강좌] 01 뷰 인스턴스 생성하기!
Vue js 기초는 코지코딩~ 힘이 드네요...
해당 영상을 개인공부용으로 재구성한 내용입니다.

Vue 생성과 기본적인 데이터 바인딩 with {{}}

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> <!--이 태그 안에 vue 코드를 작성할 수 있게 된다-->
        {{ nextYear('안녕하세요') }}
    </div>
    <script>
        new Vue({
            el: '#app', 
            // 위 div의 id와 호환됨
            data: {
                person: { 
                    name: 'eunddodi',
                    age: 23
                }
            },
            methods: {
                nextYear: function(greeting) {
                    return greeting + '! ' + this.person.name + '는 내년에 ' + (this.person.age +1) + '살 입니다';
                },
                otherMethod() {
                   <!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <form v-on:submit.prevent="submit"> <!--여기서 submit은 함수명-->
            <input type="text" :value="text" @keyup="updateText"><br>
            {{text}}<br>
            <button type="submit">Submit</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                text: 'text'
            },
            methods: {
                submit() {
                    alert('submitted');
                    console.log('hello');
                },
                updateText(event) {
                    console.log(event);
                }
            }
        })
    </script>
</body>
</html> this.nextYear();
                }
            }
        })
    </script>
</body>
</html>

name, age 데이터를 person이라는 하나의 데이터로 묶어줄 수 있다

methods안에서 함수를 사용할 수 있는데, 인자를 받을 수도 있다

this.person.name은 this.data.person.name과 같다. vue에서 자동으로 data에 접근해준다.

this를 사용하면 한 메소드에서 다른 메소드를 호출할 수도 있다.

html에서 {{}}를 사용하면 <script></script>안의 데이터를 사용할 수 있고, 메소드명 끝에 ( )를 붙이면 메소드 호출도 가능하다

otherMethod( )와 otherMethod : function()은 같다.

데이터 바인딩 with 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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <input :type="type" :value="inputData">
        <a :href="getEunddodiLink('iridescent0959')">블로그 은지야옹</a>
    </div>
    <script>
        new Vue({
            el: '#app', 
            // 위 div의 id와 호환됨
            data: {
                person: { 
                    name: 'eunddodi',
                    age: 23
                },
                inputData: '1234',
                type: 'text',
                link: 'https://blog.naver.com/'
            },
            methods: {
                getEunddodiLink(blog){
                    return this.link + blog;
                }
            }
        })
    </script>
    </body>
</html>

v-bind: 를 통해 데이터를 바인딩할 수 있다.

v-bind: value="inputData" 이렇게 하면 valuescript>data>inputData가 바인딩된다.

메소드를 바인딩할 수도 있다. v-bind: href="getEunddodiLink('iridescent0959')" 이렇게 하면 hrefgetEunddodiLink() 메소드의 리턴값이 바인딩된다.

이벤트 핸들링 with v-on

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        {{year}} <br>
        <button v-on:click="plus">더하기</button>
        <button v-on:click="minus">빼기</button>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                year: 2021
            },
            methods: {
                plus() {
                    this.year++;
                },
                minus() {
                    this.year--;
                }
            }
        })
    </script>
</body>
</html>

<button></button> 이렇게 하면 onclick안에 javascript 코드가 들어갈 수 있다

v-on:을 통해 이벤트를 핸들링할 수 있다

v-on@로 줄여서 쓸 수 있다 v-on:click@click은 같은 뜻

더하기 버튼을 클릭하면 plus메소드를 실행. plus메소드는 datayear에 접근해서 year를 +1 해준다.

이벤트 핸들링 with form, event modifier

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <form v-on:submit.prevent="submit"> <!--여기서 submit은 함수명-->
            <input type="text"><br>
            <button type="submit">Submit</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                year: 2021
            },
            methods: {
                submit() {
                    alert('submitted');
                    console.log('hello');
                }
            }
        })
    </script>
</body>
</html>

form은 기본적으로 submit을 한 다음 페이지를 reload한다

event modifier인 .prevent를 이벤트명 끝에 붙여주면 submit이 일어나고 나서도 페이지를 reload하지 않는다.

양방향 바인딩 with v-model

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <form v-on:submit.prevent="submit">
            <input type="text" :value="text" @keyup="updateText"><br>
            {{text}}<br>
            <button type="submit">Submit</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                text: 'text'
            },
            methods: {
                submit() {
                    alert('submitted');
                    console.log('hello');
                },
                updateText(event) {
                    console.log(event);
                }
            }
        })
    </script>
</body>
</html>

keyup에서 이벤트 오브젝트를 자동으로 넣어주기 때문에 인자를 따로 설정하지 않아도 콘솔에 다음과 같은 메시지들이 뜬다.

KeyboardEvent {isTrusted: true, key: "Process", code: "KeyF", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyA", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyD", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "d", code: "KeyD", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyF", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "f", code: "KeyF", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyD", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyD", location: 0, ctrlKey: false, …}
index.html:30 KeyboardEvent {isTrusted: true, key: "Process", code: "KeyR", location: 0, ctrlKey: false, …}
<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <form v-on:submit.prevent="submit">
            <input type="text" :value="text" @keyup="updateText"><br>
            {{text}}<br>
            <button type="submit">Submit</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                text: 'text'
            },
            methods: {
                submit() {
                    alert('submitted');
                    console.log('hello');
                },
                updateText(event) {
                    this.text=event.target.value;
                }
            }
        })
    </script>
</body>
</html>

개발자모드에서 이벤트를 클릭하면 정보를 볼 수 있는데, 우리가 원하는 입력 값은 target>value에 있었음.

keyup 이벤트가 발생하면 updateText 메소드를 실행. updateTextdatatextevent.target.value으로 변경한다.

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app"> 
        <form v-on:submit.prevent="submit"> 
            <!-- <input type="text" :value="text" @keyup="updateText"><br> -->
            <input type="text" v-model="text"><br>
            {{text}}<br>
            <button type="submit">Submit</button>
        </form>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                text: 'text'
            },
            methods: {
                submit() {
                    alert('submitted');
                    console.log('hello');
                }
                // updateText(event) {
                //     this.text=event.target.value;
                // }
            }
        })
    </script>
</body>
</html>

v-model을 활용하면 주석 처리한 부분 없이 사용자의 입력을 받아와서 메소드 내에서 핸들링할 수 있다

사용자의 입력을 받아와서 text를 업데이트

computed 오브젝트 with methods와의 비교

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{reversedMessage}}
        {{reversedMessage}}
        {{reversedMessage}}
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                message: '토마토는 거꾸로 해도 토마토'
            },
            methods: {
                
            },
            computed: {
                reversedMessage() {
                    return this.message.split('').reverse().join('')
                }
            }
        })
    </script>
</body>
</html>

{{}} 안에는 자바 스크립트 문법을 사용할 수 있다

Vue 객체를 만들 때 message에 '토마토는 거꾸로 해도 토마토' 라는 값이 저장됨. computed에 쓸 경우 vue 객체가 만들어짐과 동시에 reversedMessage가 돼서 그 결과값이 미리 계산이 된다. 그 값을 저장해두고 세 번 사용한 것. computed에 연결되어 있는 값(여기서는 message)이 바뀌면 바뀐 것을 캐치하고 새로운 값을 계산한다.

method에서 쓸 때는 함수를 호출할 때마다 계산을 해서 리턴하게 된다.

computed 써줄 때는 {{reversedMessage}} 끝에 괄호 안붙여도 되고 method로 쓸 때는 괄호 붙여야 함.

watch 오브젝트

<!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>Vue 기초 익히기</title>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{message}}<br>
        <button @click="changeMessage">Click</button><br>
        {{updated}}
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                message: '토마토',
                updated: '아니오'
            },
            methods: {
                changeMessage() {
                    this.message = '은또디';
                }
            },
            computed: {
                reversedMessage() {
                    return this.message.split('').reverse().join('')
                }
            },
            watch: {
                message(newVal, oldVal){
                    console.log(newVal,oldVal);
                    this.updated="네";
                }
            }
        })
    </script>
</body>
</html>

watch는 methods, computed와 같은 수준의 오브젝트이다

감시하고 싶은 변수명을 메소드 이름처럼 사용한다

watch 안의 메소드는 newVal, oldVal 두 개의 변수를 받는다. 변수가 변경이 되면 실행이 되면서 newVal에는 새로운 값이, oldVal에는 예전 값이 들어오게 된다

Click 버튼을 클릭하면 changeMessage 메소드가 실행되면서 message의 값이 ''토마토''에서 ''은또디''로 바뀐다. watch는 그 사실을 캐치하고, updated값을 "아니오"에서 ''네''로 바꾼다.

클래스 바인딩

<!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>Vue 기초 익히기</title>
    <style>
        .red {
            color: red;
        }
        .font-bold {
            font-weight: bold;
        }
    </style>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div :class="{ red: isRed, 'font-bold': isBold }">Hello</div>
        <button @click="update">Click</button>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                isRed : false,
                isBold : false
            },
            methods: {
                update() {
                    this.isRed=!this.isRed;
                    this.isBold=!this.isBold;
                }
            }
        })
    </script>
</body>
</html>

<head> 밑에 <style> 태그를 지정.

Click 버튼을 누르면 update 메소드를 실행. update 메소드는 isRedisBold를 true로 바꿔준다. 그럼 redfont-bold 클래스가 'Hello'에 적용된다.

red와 font-bold는 스타일클래스 이름인데, font-bold 처럼 클래스 자체에 대시가 있는 경우 ' ' 로 묶어줘야 한다.

스타일 바인딩

<!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>Vue 기초 익히기</title>
   
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <div :style="{color: red, fontSize: size}">Hello</div>
    </div>
    <script>
        new Vue({
            el: '#app', 
            data: {
                red: 'red',
                size: '30px'
            },
            methods: {
                
            }
        })
    </script>
</body>
</html>

div 태그 안에 바로 style을 바인딩할 수도 있다.

스타일이 여러 개인 경우 {}로 묶기, colorfontSize는 고정값임.

data에 스타일 정보를 넣어놓고 불러오는 형식

Vue 인스턴스 여러 개 생성하고 인스턴스 내 데이터에 접근하기

<!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>Vue 기초 익히기</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{ name }} <!-- el: ''#app' 인 뷰 인스턴스의 name을 가져옴-->
        <button @click="changeText">Click</button>
    </div>

    <div id="app1">
        {{ name }} <!-- el: ''#app1' 인 뷰 인스턴스의 name을 가져옴-->
        <button @click="changeText">Click</button>
    </div>

    <script>
        const app = new Vue({
            el: '#app', 
            data: {
                name: 'eunddodi'
            },
            methods: {
                changeText() {
                    app1.name = 'eunddodi updated';
                }
            }
        })

        const app1 = new Vue({
            el: '#app1',
            data: {
                name: 'eunddodi1'
            },
            methods: {
                changeText() {
                    this.name = 'eunddodi1 updated';
                }
            }
        })
    </script>
</body>
</html>

Vue 인스턴스 내의 el과 div 태그의 id가 서로 호환된다.

el: '#app1' 인 Vue 인스턴스와 <div id="app1">가 서로 호환되는 것. div 태그 안에 "app1" 을 씀으로써 el:'#app1'인 Vue 인스턴스와 연결되는 것.

인스턴스A에서 인스턴스B의 데이터에 접근하기 위해서는 Vue를 생성할 때 변수명에 할당을 해준다. const 변수명 = new Vue()
변수명을 통해서 해당 뷰인스턴스의 데이터에 접근할 수 있다.

this.name 대신 변수명.name

전역 컴포넌트의 선언과 사용법

컴포넌트를 만들어 놓으면 재사용할 수 있다. 반복된 코드 제거 가능.

모든 Vue 인스턴스에서 접근이 가능하다

컴포넌트A 에서 컴포넌트B에 접근하는 것도 가능하다.

<!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>Vue 기초 익히기</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <!--{{ name }}<br>
        <button @click="changeText">Click</button>

        <hr>-->

        <eunddodi-button></eunddodi-button>
    </div>
    <hr><hr>
    <div id="app1">
        <!--{{ name }}<br>
        <button @click="changeText">Click</button>

        <hr>-->

        <eunddodi-button></eunddodi-button>
    </div>

    <script>
        Vue.component('eunddodi-button', {
            template: `
            <div>
                {{ name }}<br>
                <button @click="changeText">Click</button>
            </div>
            `,
            data() {
                return {
                    name: 'eunddodi'
                }
            },
            methods: {
                changeText() {
                    this.name = 'eunddodi updated';
                }
            },
        });

        const app = new Vue({
            el: '#app', 
            // data: {
            //     name: 'eunddodi'
            // },
            // methods: {
            //     changeText() {
            //         this.name = 'eunddodi updated';
            //     }
            // }
        })

        const app1 = new Vue({
            el: '#app1',
            // data: {
            //     name: 'eunddodi'
            // },
            // methods: {
            //     changeText() {
            //         this.name = 'eunddodi updated';
            //     }
            // }
        })
    </script>
</body>
</html>

component의 template 부분에는 html 코드를 넣어준다. 여러 줄로 작성 시 ``로 묶어줘야 한다.

data:data() 함수로 바꿔주고 return 안에 데이터들을 넣어주어야 한다.

실제 html에서는 component 생성 시 설정한 태그를 사용하여 추가할 수 있다
<eunddodi-button></eunddodi-button>

컴포넌트는 Vue 생성 이전에 만들어줘야 하는듯

지역 컴포넌트 선언과 사용법

<!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>Vue 기초 익히기</title>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        {{ name }}<br>
        <button @click="changeText">Click</button>

        <hr>

        <eunddodi-button></eunddodi-button>
    </div>

    <script>
        const EunddodiButton = {
            template: `
            <div>
                {{ name }}<br>
                <button @click="changeText">Click</button>
            </div>
            `,
            data() {
                return {
                    name: 'eunddodi'
                }
            },
            methods: {
                changeText() {
                    this.name = 'eunddodi updated';
                }
            },
        };

        const app = new Vue({
            el: '#app', 
            components: {
                'eunddodi-button':EunddodiButton
            }
        })

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

const를 활용해 컴포넌트를 생성한다. 내용은 전역 컴포넌트와 같다.

지역 컴포넌트를 Vue 인스턴스 내에서 활용하기 위해서는 components: { } 안에 넣어주어야 한다. '컴포넌트 태그명' : 지역 컴포넌트명

el:'#app'인 Vue인스턴스의 components에 정의되어 있어야 해당 지역컴포넌트를 id가 app인 div태그 내에서 사용할 수 있다.

profile
교육학과 출신 서타터업 프론트 개발자 👩🏻‍🏫

0개의 댓글