230215 Vue

kangjuju·2023년 2월 15일
0

Acorn2

목록 보기
4/8


Vue

단일 파일 컴포넌트 기반의 프레임워크다.
웹의 view를 구성하는 요소인 HTML, CSS, JavaScript 코드를 .vue 확장자를 가진 하나의 파일에 모두 정의하는 방식으로 적당한 규모의 프로젝트에서 관리의 생산성을 높이고, 협업이 쉬운 것으로 알려져 있다.
뷰 인스턴스(Instance)는 뷰로 화면을 개발하기 위해 필수적으로 생성해야하는 기본 단위이며 new Vue()를 사용하여 뷰 객체를 생성한다.

  • React에 비해 가볍고 빠르게 개발이 필요한 경우 선호

  • 컴포넌트 기반의 웹 프로그래밍 가능

  • 선언적 렌더링 (HTML 확장), JS상태 변경을 virtual Dom으로 효율적 관리가 가능


기본 문법

    Vue로 결과 출력:
    <div id="app">
        {{message1}} <br>
        {{message2}} <br>
        {{message3}} <br>7
    </div>
    <script>
        let aa = new Vue({
            el:"#app",
            data:{
                message1:"Hello world!",
                message2:"안녕" + "반가워",
                message3:Math.random() * 9
            }
        });
        console.log(aa);
    </script>

기본적으로 위의 코드처럼 new Vue를 통해 인스턴스를 생성하고 안에 el, data등 옵션을 넣어 인스턴스를 생성하고 화면을 컨트롤 할 수 있다.


application 생명주기(생성,갱신,소멸)

<script>
            beforeCreate:function(){ //초기화 담당
                console.log("beforeCreate")
            },
            created:function(){ //반응성
                console.log("created")
            },
            mounted:function(){ //속성설정
                console.log("mounted")
            },
            beforeUpdate:function(){
                console.log("beforeUpdate")
            },
            updated:function(){
                console.log("updated")
            }
</script>

컴포넌트

기본

Vue.component("태그명",옵션)
컴포넌트를 구성하여 사용자 정의 태그를 사용한다.

    <div id="appBasic">
      <hello></hello>
    </div>

    <script>
        Vue.component("hello",{
            template:'<h1>{{title}}</h1>', //template: 화면에 표시할 마크업요소를 정의
            
            data:function(){
                return{
                    title:"컴포넌트 txt"
                }
            }
        });
        new Vue({
            el:"#appBasic"
        })
    </script>

컴포넌트는 꼭 해당 Vue객체 위에서 만들어야한다.

컴포넌트 - 이벤트관련

    <div id="appBasic2">
        <world></world>
    </div>
    <script>
        Vue.component("world",{
            template:'<h2>{{title}} <button @click="changeTitle">타이틀 변경</button></h2> ', 
            methods:{
                changeTitle:function(){this.title = "변경된 타이틀"}
            },
            data:function(){
                return{
                    title:"컴포넌트 txt2"
                }
            }
        });
        new Vue({
            el:"#appBasic2"
        })
  </script>

버튼 클릭시 텍스트 변경처리.
마크업에서 click이벤트로 만든 메소드에 대한 구현은 methods에서 구현했다.


지역/전역 컴포넌트

전역 컴포넌트

Vue.compoent() 로 등록한다.
플러그인이나 라이브러리 형태로 전역으로 사용해야 하는 컴포넌트만 이렇게 작성한다.
여러 인스턴스에서 공통으로 사용 가능하다.

Vue.component('컴포넌트 이름 ',{
	컴포넌트 내용
})

지역 컴포넌트

compoents 로 등록한다.
복수형
보통은 컴포넌트를 여러개를 등록하기 때문에 components 로 작성한다.
지역 컴포넌트는 하단에 어떤 것이 등록 되는지 알 수 있다.
특정 인스턴스 내부에서만 사용 가능하다.

       new Vue({
           components:{ // 지역컴포넌트 
               '컴포넌트 이름': 컴포넌트 내용
           }
       }) 

예제

    <div id="app">
      <div>컴포넌트 등록1</div>
      <global-component></global-component><!-- 전역 컴포넌트 표시 -->
      <local-component></local-component><!-- 지역 컴포넌트 표시 -->
    </div>
    <div id="app2">
      <div>컴포넌트 등록2</div>
      <global-component></global-component>
      <local-component></local-component>
    </div>
    <div id="app3">
      <div>컴포넌트 등록3</div>
      <global-component></global-component>
      <local-component></local-component>
    </div>
    <script>
      //global-component는 여러 인스턴스에서 공통으로 사용 가능
      // 전역 컴포넌트 등록 - 강결합
      Vue.component("global-component", {
        template: "<b>전역 컴포넌트 등록!</b>",
      });
      new Vue({
        el: "#app",
      });
      // 지역 컴포넌트 등록 - 약결합
      let cmp = {
        template: "<p>지역 컴포넌트 등록~~~~</p>",
      };
      new Vue({
        el: "#app",
        components: {
          "local-component": cmp,
        },
      });
      
      new Vue({
        el: "#app2",
      });
      new Vue({
        el: "#app3",
      });
    </script>

전역으로 등록한 컴포넌트는 다른 Vue객체에서도 적용된것을 확인 할 수 있다.


Directive

  • HTML 안에 적는 속성. v-라는 접두어 사용.
    무언가를 지시하는 특수한 토큰이다
  • Vue객체에서 선언한 데이터들을 직접적으로 태그에 꽂는 식이다.
<body>
<hr>
<div id ="app">

<a href = "{{link}}">링크(에러발생함.)</a>
<a v-bind:href = "link">링크1</a>
<a :href = "link">링크2</a><!-- v- bind생략가능. -->

<h2 v-text="say"></h2>
<h2 v-once>data 속성 1 : {{say}}</h2>
<h3>함수 호출 결과: {{sayFunc()}}</h3>
</div>

<script type="text/javascript">
new Vue({
   el:'#app',
   data:{
      link:'http://daum.net',
      say: "안녕하세요",
      aLinkToNaver: "<a href='https://naver.com'>가자 네이버로</a>",
      name: 'tom',
   },
   methods:{
    sayFunc:function(){
        this.say = "반가워요"
        return this.say
    }
   }
})
</script>
  • v-once 디렉티브는 HTML코드로 출력이 된 이후에 어떤 후처리가 있더라도 처음에 출력한 값을 유지시킬 때 사용된다.

v-text / v-html 차이점

<span v-text="aLinkToNaver"></span> 
<span v-html="aLinkToNaver"></span>

Directive text가 온전한 html 구문일때 사용할 수 있다.

양방향 데이터 binding (v-model)

<input type="text" v-model:value="name" >{{name}}
  • v-model:value에 의해 Vue객체의 {{name}}이 실시간으로 변화한다.
    두 요소가 연결되어 양방향으로 데이터가 처리되는것.

v-model:value이 없다면 단방향 처리로 {{name}} 이 변경되지않는다.
하지만 이 단방향 input태그를 핸들러와 메소드로 v-model처럼 똑같이 직접 구현할 수도 있다.

단방향 input2: <input type="text" :value='name' @input="changeName">{{name}}
<script>
   methods:{
    changeName(e){
        this.name = e.target.value
    }
   }
</script>

computed

      a={{a}} b={{b}} <br>
      a 값 입력 : <input type="text" v-model="a">
<script>
        computed:{ //계산된 프로퍼티 : 함수처럼 작동            
            b:function(){
               return parseFloat(this.a) + 1  //계산

            }
        }
</script>
  • 계산된 프로퍼티 computed 로 인해 b는 단순한 변수가 아닌 함수가 된다.

  • js에서 +는 문자열로써 더하기 때문에 입력값에 함수 리턴값에 parseFloat를 적용하여 실수로써 계산했다.

만약 리턴에 parseFloat를 적용하지 않는다면 대체 방법으로 <input> 에서
v-model.number 로 적용시킬 수 있다.

<script>
      a 값 입력 (number적용) : <input type="text" v-model.number="a">
           computed:{          
            b:function(){
                return this.a + 1  //문자열더하기
            }
        }
 </script>


조건판단문

if

      <h2 v-if="a > 5">a가 5보다 크다.</h2>
      <h2 v-if="a == 5">a는 5다.</h2>
      <h2 v-else>a는 5를 제외한 수이다.</h2> <br>

Vue객체의 ar값을 조건 판단 후 해당 태그내용을 출력하거나 하지않는다.

for

      반복문 for
      <ul>
        <li v-for="todo in todos">{{todo.text}}</li>
      </ul>
       <ul>
        <li v-for="(todo,index) in todos">{{index+1}}/{{todo.text}}</li>
      </ul>
      
<script>
      new Vue({
        el: "#app",
        data: {
          todos:[
            {text:'아침먹고'},
            {text:'점심먹고'},
            {text:'집에가기'}
          ]
        },
 </script>
  • v-for=사용할 이름 in 출력할 배열 형태로 사용한다.
  • 괄호 사용으로 배열로부터 나오는 index값까지 뽑아올 수 있다.


v-if / v-show 차이

https://doozi316.github.io/vuejs/2020/10/28/Vue7/

  • v-if는 조건에 따라 엘리먼트가 제거되고 새로 렌더링 된다
  • v-show는 조건에 따라 엘리먼트가 새로 렌더링 되는게 아니라 단순히 css의 display 속성 값만 변경된다
  • display: none의 유/무
      <p v-if="season">여름이 좋아</p>
      <p v-else>겨울이 좋아</p>
      <button v-on:click="season = !season">출력 결과 변경</button>

      <template v-if="season">
        <p>옷 입기가 편하다</p>
        <p>해충이 많다.</p>
      </template>
      <template v-else>
        <p>다양한 옷 스타일</p>
        <p>해충이 없다.</p>
      </template>

      <!--v-show-->
      <span v-show="season">
        <p><b>옷 입기가 편하다</b></p>
      </span>
      <template v-show="season">
        <p><b>옷 입기가 편하다2</b></p> 
      </template>
  • 버튼으로 내용을 스위칭 했다.
  • v-show 로는 template 엘리먼트 내용이 사라지지 않는다.
    조건에 따라 엘리먼트가 새로 렌더링 되는 v-if를 사용하는 것이 적절하다.

참고 예제

클릭수로 버튼 비활성화 하기

      <p v-if="count === 10">{{count}}번 클릭. 버튼 비활성화</p>
      <p v-else-if="count => 1">현재 클릭 수 : {{count}}번</p>
      <p v-else>버튼을 클릭하시오</p>
      <button v-bind:disabled="count===10" v-on:click="addFunc">증가</button>

    <script>
      new Vue({
        el: "#app",
        data: {
          season: false,
          myVisible: false,
          count: 0,
        },
        methods: {
          // addFunc:function(){
          addFunc() {
            this.count++;
          },
        },
      });
    </script>

checkbox로 if연습

      <label><input type="checkbox" v-model="myVisible" />체크박스 확인</label>
      <div v-if="myVisible">check On</div>
      <div v-else>check Off</div>
      
      (Vue객체는 위와 공유한다.)

반복렌더링 위한 v-for

      <h3>갈증 날때</h3>
      <ul>
        <li v-for="li in list">{{li}}</li>
      </ul>
      <h3>문득 가보고 싶은 곳</h3>
      <ol>
        <li v-for="city in objArray">{{city.name}}은 {{city.taketime}}</li>
      </ol>
      <br />
      <h3>구구단 7단</h3>
      <ul>
        <li v-for="n in 9">7 * {{n}} = {{n*7}}</li>
      </ul>
      
          <script>
      new Vue({
        el: "#app2",
        data: {
          list: ["아메리카노", "콜라", "사이다", "소맥"], //array
          objArray: [
            { name: "강릉", taketime: "3시간" },
            { name: "부산", taketime: "6시간" },
            { name: "춘천", taketime: "2시간" },
          ],
          myArr: ["일", "이", "삼", "사", "오"],
          numArr:[1,2,3,4,5]
        },
      });
    </script>
  • v-for문은 향상된 for문의 in을 사용하듯 생각하면 된다.
    꼭 배열의 이름이 아니여도 된다는 뜻.

자료 추가 삽입 삭제 메소드 (splice)

      <button @click="addList">자료추가(맨뒤)</button>
      <button @click="addListIndex(3)">자료추가(선택)</button>
      <button @click="changeList(2)">자료변경</button>
      <button @click="delList(1)">자료삭제</button>

<script>
      new Vue({
        el: "#app2",
        methods: {
          addList: function () {
            this.myArr.push("추가"); //맨뒤에 추가됨
          },
          addListIndex: function (arg) {
            this.myArr.splice(arg, 0, "삽입"); //splice(지정위치,0,"자료")
          },
          changeList(arg) {
            this.myArr.splice(arg, 1, "수정");
          },
          delList(arg) {
            this.myArr.splice(arg, 1);
          },
        },
      });
    </script>
  • splice() 을 리스트에 유용하게 썼다.

0개의 댓글