보안 전공생의 공부

프로퍼티(2) 본문

WEB/Vue

프로퍼티(2)

수잉 2021. 1. 18. 10:44

출처 

book.naver.com/bookdb/book_detail.nhn?bid=15519728

 

예제로 배우는 Vue.js

자바스크립트 프레임워크인 REACT, ANGULAR, VUE 중 VUE.JS는 가장 인기 있는 프론트엔드 GITHUB 프로젝트가 됐다. 이 책에서는 VUE.JS 학습에 필요한 기본적인 환경 설정부터 뷰 인스턴스, 컴포넌트, VUE-ROU

book.naver.com

 

번에 이어서 프로퍼티에 대해 마저 소개하겠습니다앙

▷computed 프로퍼티를 이용한 필터링

computed 프로퍼티는 양방향 데이터 바인딩으로,

사용자 입력(UI)와 데이터소스(vue instance) 사이에서 한 쪽 데이터 변화가 생기면 반응하는 형태를 갖는다.

이를 이용해서 목록에서 찾고자 하는 것을 필터링하는 코드를 짜보면 이와 같다.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <label>먹고싶은 음식:</label>
        <input v-model="searchFood" type="text"/>
        <ul>
            <li v-for="food in filteredFoods">{{food}}</li>
        </ul>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script type= "text/javascript">
        var vm=new Vue({
            el : '#app',
            data : {
               searchFood: '',
               foods : ['chicken','pizza','tteokbokki','sushi','hamburger','frenchfries',
               'porkbelly','cheesecake','icecream','jeyuk bokkeum','cheese buldak','sandwich']
            },
           computed : {
            filteredFoods(){
                return this.foods.filter(item=>item.match(this.searchFood.toUpperCase()))
            }
           }
        })
    </script>
</body>
</html>

div 태그 부분

v-for 디렉티브는 for문처럼

집합 형태의 데이터를 반복 처리할 때 사용한다.

뷰 인스턴스 부분

검색창에 c를 입력해보았다.

chicken, cheesecake, chees buldak이 필터링 되어야되는데

필터링이 안된다 ;;

책에서는 여행가고싶은 도시들이 나열되어있다.

책이랑 내 코드의 차이점을 굳이 찾으면 문자열이 대문자로 시작하는지 소문자로 시작하는지이다.

첫글자를 대문자로 바꿔봐야겠다.

그리고 다시 서버로 확인해보았다.

오옷! 된다된다

대문자로 시작하는 문자열을 데이터로 넣으니

검색할 때 대문자로든 소문자로든 입력만 하면 필터링이 된다!!

(html attribute는 대소문자를 구분하지 않기 때문이라고 한다)

근데 왜 처음에 소문자로 시작하는 단어들은 안됐는지

구글링해도 알 수 없음..

뭐지..

 

◆ props 프로퍼티

다른 컴포넌트와 데이터를 직접적으로 전달하는 데에 사용하는 프로퍼티이다.

부모 컴포넌트 → 자식 컴포넌트로 데이터 전달

(데이터 전달) (데이터 받음)

· 컴포넌트(component) : vue의 강력한 기능 중 하나로, 크게 template, script, style 부분으로 구성된다.

뷰 인스턴스도 컴포넌트의 일종 !

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <child : text = "message"></child>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script type= "text/javascript">
        Vue.component('child',{
            props:['text'],
            template : '<div style="background-color : yellow;">{{ text }}</div>'
            });
        
        var vm = new Vue({
            el : '#app',
            data() {
                return {    
                    message : 'have a nice day!'
                }
            }
        })
    </script>
</body>
</html>

- Vue.component({}) : 새로운 컴포넌트 등록할 때 사용

child라는 컴포넌트를 등록하였습니다.

div 태그 안에 child 컴포넌트를 html 태그 형태로 추가했어요.

props 프로퍼티를 통해 child 컴포넌트의 text는 have a nice day! 이 되므로

<div style = "background-color : yellow;">{{text}}</div>

                               ↓

<div style = "background-color : yellow;">have a nice day! </div>

가 됩니다.

이를 서버로 확인해보면 have a nice day!라는 글자가 출력되며, 노란색 바탕을 갖고 있어야겠죠?

허헣 근데 아예 문자도 출력이 안돼요 ㅎㅎ..

틀린 게 있나 다시 체크해봐도

아무리 봐도 이상이 없는데 말여..

일단 컴포넌트 부분은 나중에 더 자세히 다루기 때문에

이해만 하고 패쓰!!

◆ watch 프로퍼티

data 객체 내의 데이터 모니터링하고,

특정 데이터에 변화 발생하면 후속처리를 합니다.

watch 프로퍼티를 이용해

사용자가 10진수의 숫자를 입력하면 2진수로 자동변환해 나타내고,

2진수의 숫자를 입력하면 10진수로 자동변환해주는 코드를 짜면 다음과 같습니다.

 

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        10 진수 : <input v-model.number="dec" type="text">
        2 진수 : <input v-model.number="binary" type="text">
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm= new Vue({
            el : '#app',
            data : {
                dec: 0, 
                binary:0
            },
            watch : {
                dec : function(val){
                    this.dec =val;
                    this.binary=parseInt(val.toString(2));
                },
                binary : function(val){
                    this.binary=val;
                    this.dec=parseInt(val, 2);
                }
            }
        })
    </script>
</body>
</html>

input 태그 코드를 살펴봅시다

v-model.number = "dec"은 사용자가 입력하는 값을 data 객체 내의 dec과 바인딩하는 것입니다. input폼을 사용해 입력값을 받는 경우 항상 타입이 문자로 나타나게 됩니다. 이 타입을 숫자(number)로 자동으로 바꿔줍니다.

( 출처 : https://webisfree.com/2019-01-22/[vuejs]-%ED%8F%BC-%EC%9E%85%EB%A0%A5%EA%B0%92%EC%9D%98-v-model%EC%97%90-%EC%88%98%EC%8B%9D%EC%96%B4-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95-modifier )

watch 프로퍼티에서는 2진수를 10진수로, 10진수를 2진수로 변환하는 함수를 정의합니다. data 객체 내의 dec이나 binary에 변화가 발생하면 → watch 프로퍼티는 function(val) 함수에 의해 처리가 됩니다.

val.toString(2) 는 val을 2진수의 형태로 반환합니다. 괄호( ) 안에는 진수를 나타내는 기수의 값이 들어가는데, 2~36 사이의 정수가 들어갈 수 있습니다.

( 출처 : https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Number/toString )

parseInt( ) 는 문자열 형태의 데이터를 10진수의 숫자 형태로 저장해주는 메서드입니다.

parseInt(val, 2)는 2진수인 문자열 val을 10진수의 숫자로 변환해줍니다.

이때, 2는 val이 2진수 형태임을 나타내는 거라구 합니다.(확실X)

10진수를 2진수로 변환할 때는 parseInt(val.toString(2))인데,

2진수를 10진수로 변환할 때는 parseInt(val, 2)로 나타냈었습니다.

2진수 外 진수 → 10진수 : parseInt(x.toString(n))

10진수 → 2진수 外 진수 : parseInt(x, n)

임을 알 수 있습니다.

(그 세세한 디테일과 이유를 설명하고 싶은데

숙취 때문에 지금은 그럴 여력이 없습니다 ㅓㅜ....)

(출처 : https://medium.com/@koteswar.meesala/parseint-vs-tostring-87f5afe0ec5f)

(출처 : https://doomoks.tistory.com/37 )

아무튼 서버로 위의 코드가 잘 실행되는지 확인해 볼 수 있습니다.

10진수 칸에 11을 입력하면 2진수 칸에 자동으로 1011이 뜨고,

2진수 칸에 1101을 입력하면 10진수 칸에 자동으로 13이 뜹니다

근데 좀 짜증나는게 입력한 숫자를 다른 숫자로 바꾸려고 지우면

parseInt 메소드 때문에 NaN(Not a Number)이 뜹니다.. 빈 문자열에 대해 NaN을 반환한다고 합니다.

아무튼 이거때문에 빈 문자열 되면 NaN이 되어서 이걸 또 지우고 숫자를 입력해야 되는 굉장한 번거러움이 생깁니다.

NaN이 안 뜨게 하기 위해서 로지컬 OR(||) 을 이용합니다.

parseInt(…) || 0

첫번째 값인 parseInt(…)가 true인 경우 이를 그대로 반환하는데, 만약 false인 경우(NaN은 false값으로 인식됨) 두번째 값인 0이 반환됩니다.

(출처 : https://stackoverflow.com/questions/6736476/how-to-turn-nan-from-parseint-into-0-for-an-empty-string )

히히 성공 ! 맘이 편안해진다ㅏ..

◇ 한 페이지 내에서 다수의 뷰 인스턴스

각 뷰 인스턴스에 data 객체에 정의된 프로퍼티를 사용해 직접 접근할 수 있다.

두 개의 뷰 인스턴스 vm1, vm2 가 있다고 하면,

2개의 div 앨리먼트 (id값이 각각 app1, app2) 로 작성하면 됩니다.

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #app1{
            background: blue;
            color : white;
            padding: 4px;
            margin-bottom : 4px;
        }
        #app2{
            background:teal;
            color : white;
            padding : 4px;
        }
    </style>
</head>
<body>
    <div id="app1">
        <div>
            <p>{{message}}</p>
        </div>
        <button @click="changeMessage">메시지 바꾸기</button>
    </div>
    <div id="app2">
        <div>
            <p>{{message}}</p>
        </div>
    </div>
    <script src="http://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
        var vm1= new Vue({
            el:'#app1', 
            data :{
                message : '첫번째 뷰 인스턴스'
            },
            methods :{
                changeMessage(){
                    vm2.message='종강마렵다'
                }
            }
        })
        var vm2= new Vue({
            el:'#app2', 
            data :{
                message : '두번째 뷰 인스턴스'
            }
        })
    </script>
</body>
</html>

<button @click="changeMessage">에서

@click v-on:click의 축약형태입니다.

이 버튼을 클릭하면 changeMessage 함수를 호출합니다.

두 뷰 인스턴스 사이의 접근은 vm2.message처럼 정의된 뷰 인스턴스 data 프로퍼티에 정의된 객체를 사용함으로써 가능합니다.

스타일을 적용해서 뷰 인스턴스 2개가 한 페이지에 나타나는 걸

명확히 구분해줬어요.

첫번쨰 뷰 인스턴스의 버튼을 클릭하면

나의 진심어린 소망

두번째 뷰 인스턴스에 변화가 생깁니다~!

◇ 뷰 인스턴스 생명주기

new키워드를 이용해 초기화 되며 시작

https://cigiko.cafe24.com/vue-js-뷰-인스턴스/

 

 

 

- 라이프사이클 속성 : 인스턴스의 상태에 따라 호출 할 수 있는 속성들

- 사이클 훅(hook) : 라이프사이클 속성에서 실행되는 커스텀 로직

▶ beforeCreate : 인스턴스가 생성되고 나서 가장 처음으로 실행되는 단계

data 속성과 methods 속성이 아직 인스턴스에 정의되지 X

DOM 같은 화면 요소(template 속성에 정의됨)에 접근 X

▶ created : data 속성과 methods 속성에 접근할 수 있는 첫 단계

data 속성과 methods 속성이 정의됨 → 정의된 값에 접근해 로직 실행 가능

DOM은 아직 X

▶ beforeMount

: template 속성에 지정한 마크업 속성 → render()함수로 변환 후,

el 속성에 지정한 DOM에 인스턴스 부착 전 호출하는 단계

- render() : 자바스크립트로 화면에 DOM 그리는 함수

▶ mounted : el 속성에서 지정한 화면요소(DOM)에 인스턴스 부착되고 나면 호출하는 단계

▶ beforeUpdate : 인스턴스에 정의한 속성들이 화면에 치환되는 단계

치환된 값들은 뷰의 reactivity를 제공하기 위해 watch 속성으로 접근 가능

데이터가 변경되면 새 데이터에 접근 가능

▶ updated : 데이터가 변경된 후 virtual DOM으로 다시 화면을 그리고 실행되는 단계

이 단계에서 데이터 값 변경하면 무한 루프에 빠짐 → computed, watch와 같은 속성 이용해 값 변경해야함

▶ beforeDestroy : 뷰 인스턴스가 파괴되기 직전 호출되는 단계

▶ destroyed : 파괴된 후 호출되는 단계, 모든 속성과 하위 인스턴스들 모두 파괴됨

(출처 :https://dahye-jeong.gitbook.io/vue-js/vuejs/2019-10-15-instance)

Comments