ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Vue.js] import/export, component 사용해보기
    Front-End/Vue.js 2022. 11. 23. 10:20

     

     

    vue 파일에서 < 꺽쇠 하나 친 다음에 엔터 누르면 기본 템플릿이 나온다. 

     

     

     

    📑 Vue에서 import , export 하기 

     

    📌 변수 1개일 때, A파일의 변수 B파일에서 사용하기

     A파일
    var apple =10; 
    export default apple; 

    B파일
    import apple from './assets/data.js'

     

     

    📌 변수 2개일 때, A파일의 변수 B파일에서 사용하기

     A파일
    var apple =10; 
    var apple2 =100; 
    export {apple,apple2}; 

    B파일
    import {apple,apple2 } from './assets/data.js'

     

     

     

    📑 component - 사용해보기

     

    component는 긴 HTML을 한 단어로 줄일 수 있는 문법이다. 컴포넌트를 사용하는 문법은 다음과 같다.

    📌 1. 컴포넌트로 만들고 싶은 데이터들을 새로운 파일에 담는다. 예를들어 Modal.vue라는 새로운 파일을 만들어 데이터들을 넣는다.

    📌 2. Modal.vue가 아닌 본 vue 파일에 Modal.vue를 import 해온다. 

    📌 3. export default에 components : {}안에 컴포넌트를 등록한다. 

    📌 4. 사용한다. 

     

     

     

    📌 1. 컴포넌트로 만들고 싶은 데이터들을 새로운 파일에 담는다. 

     

    < Discount.vue>

    <template>
        <div class="discount">
        <h4>지금 결제하면 20% 할인</h4>
      </div>
    </template>
    
    <script>
    export default {
    
        name : 'Discount',
    }
    </script>
    
    <style>
    
    </style>

     

     

    📌 2. <script>태그 안에 본 vue 파일에 Modal.vue를 import 해온다. 

     

    import Discount from './Discount.vue'

     

     

    📌 3. export default에 components : {}안에 컴포넌트를 등록한다.

     

    export default {
      data :function(){
        return {
          오브젝트 : {name : 'kim', age :20},
          메뉴들 : ['Home', 'Shop', 'About'],
          외부데이터 : data,
          사용자클릭 : 0,
          모달창보이나 : false,
    
        }
      },
      components : {
        // 디스카운트 : Discount,
        Discount,
        Modal,
        Card,
        
      }
     
    }

     

     

    📌 4. 사용한다. 

     

    <Discount />

     

     

    이렇게 작성하면 <Discount />라는 컴포넌트를 쓴 곳에 Discount.vue에 저장해둔 파일이 로딩된다.

     

     


     

    📑 component - props, 데이터 사용

     

    만약 본 vue 파일에 저장되어 있는 데이터를 컴포넌트에서 써야 된다면?? props라는 속성 값을 사용한다. props 안에는 {데이터이름:자료형이름} 방식으로 적어주면 된다. Modal 창을 만드는 코드를 컴포넌트로 빼보자. 아래 예제는 코드로 살펴본다. 

     

     

    <Modal.vue>

    <template>
        <div class="black-bg" v-if="모달창보이나==true">
        <div class="white-bg">
            <p>{{외부데이터[사용자클릭].title}}</p>
            <p>{{외부데이터[사용자클릭].content}}</p>
            <!-- <button @click="모달창보이나=false">닫기</button> -->
    
        </div>
      </div>
    </template>
    
    <script>
    //모달창에서는 지금 App.vue에서 정의된 데이터를 사용한다. 
    //그럼 여기에 데이터를 따로 또 넣어줘야 되나??
    // 그거는 좋지 않은 방식이다 데이터는 한 곳에 보관하는 게 좋다. 
    //가져다 쓰는 문법이 props문법. 부모/자식컴포넌트라고 칭한다. 
    //props : {데이터이름:자료형이름}
    export default {
    
        name : 'Modal',
        //data(){}로 만들면 되지 않음? 
        //되긴 되는데 부모도 쓰는 데이터라면 부모컴포넌트에 만들어두자.
        props : {
            외부데이터 : Array,
            모달창보이나 : Boolean,
            사용자클릭 : Number,
    
        }
    
    }
    </script>
    
    <style>
    
    </style>

     

     

    <App.vue>

     

    <template>
    
      
    
    
      <!-- <div class="black-bg" v-if="모달창보이나==true">
        <div class="white-bg">
            <p>{{외부데이터[사용자클릭].title}}</p>
            <p>{{외부데이터[사용자클릭].content}}</p>
            <Discount />
            <button @click="모달창보이나=false">닫기</button>
    
        </div>
      </div> : v-bind-->
      <!-- <Modal :외부데이터="외부데이터"/> -->
      <Modal :외부데이터="외부데이터" :사용자클릭="사용자클릭" :모달창보이나="모달창보이나"/>
    
      
    
    
      <div class="menu">
        <a v-for="(a,i) in 메뉴들" :key="i">
        {{a}}
        </a>
      </div>
    
      
    
    <!--컴포넌트 문법 쓰는 이유, 재사용 쉽고, 코드 보기 편함-->
      
        
     <div v-for="(a,i) in 외부데이터" :key="i">
        속성 값은 :를 붙여 v-bind로 값을 넣어줘야 한다.
        <img :src="외부데이터[i].image" />
        <p @click="모달창보이나=true">{{a.title}}</p>
        <p>{{a.content}}</p>
        <p>{{a.price}}</p>
        
      </div>
    
    </template>
    
    <script>
    
    //축약해둔 컴포넌트 쓰는 법
    //1. vue 파일 import 해오고 2. 등록하고 3. 쓰고
    //데이터 바인딩이 어려워 데이터 관리가 조금 복잡해져서 이게 단점이다. 
    
    import data from './assets/data.js'
    import Modal from './Modal.vue'
    
    
    
    
    export default {
      data :function(){
        return {
          오브젝트 : {name : 'kim', age :20},
          메뉴들 : ['Home', 'Shop', 'About'],
          외부데이터 : data,
          사용자클릭 : 0,
          모달창보이나 : false,
    
        }
      },
      components : {
        Modal,
        
      }
     
    }
    </script>
    
    <style>
    #app {
      font-family: Avenir, Helvetica, Arial, sans-serif;
      -webkit-font-smoothing: antialiased;
      -moz-osx-font-smoothing: grayscale;
      text-align: center;
      color: #2c3e50;
    }
    
    .menu{
      background-color: darkslateblue;
      padding:15px;
      border-radius:15px;
    }
    
    .menu a{
      color :white;
      padding : 10px;
    }
    
    body{
      margin: 0
    }
    
    div{
      box-sizing:border-box;
    }
    
    .discount{
      background-color: gray;
      padding: 10px;
      margin: 10px;
      border-radius : 5px;
    }
    .black-bg{
      width: 100%; height: 100%;
      background: rgba(0,0,0,0.5);
      position: fixed; padding:20px;
    }
    
    .white-bg{
      width: 100%; background: white;
      border-radius: 8px;
       padding:20px;
    }
    </style>

     

     

    위의 코드를 살펴보면 Modal 창을 띄우는 코드를 따로 Modal.vue에 옮긴다.  <p>{{외부데이터[사용자클릭].title}}</p> 이 코드를 보면 App.vue에 선언되어 있는 data를 사용하는 것을 볼 수 있다. 이를 바로 자식 Modal.vue에선 사용할 수 없다. 부모 데이터를 자식 데이터에 보내줘야된다. 이럴때 쓴는 것이 바로 props이다. 

     

    컴포넌트로 지정한 <Modal />을 사용할 때 데이터를 보내줄 수 있다. 데이터를 보내는 방식은 다음과 같다. 

     

    <Discount :이름="오브젝트.name" :나이="오브젝트.age"/> 
    <Discount v-bind="오브젝트"/>   
    <Discount :오브젝트="오브젝트"/>

     

     

    이런식으로 App.vue에서 컴포넌트를 호출할 때 부모 vue에 있는 데이터를 전달해주는 것이다. Modal에서 사용하는 데이터들을  <Modal :외부데이터="외부데이터" :사용자클릭="사용자클릭" :모달창보이나="모달창보이나"/> 이와 같이 보내준다. 

     

     

    이렇게 전달받은 데이터는 Modal.vue에 데이터로 선언해줘야 하는데 그 방식은 다음과 같다. 데이터이름 : 자료형

     

     props : {       
    외부데이터 : Array,       
    모달창보이나 : Boolean,       
    사용자클릭 : Number,   
    }

     

     

     

    📑 component - 자식 vue에서 부모 데이터 변경

     

    위에서 사용한 props는 부모에게 받은 데이터인데, 이는 자식 vue에서 변경할 수 없다. 즉) read-only인 것!! 그럼 어떻게 데이터의 값을 변경할까?? 

     

    그 해답은 바로 custom event!!  $emit을 사용하면 된다. $emit('작명', 데이터)는 부모까지 메시지를 전달할 수 있다. 이 전달한 메시지를 부모가 받으려면 @작명이름으로 입력하면 된다. 예로 살펴보자.

     

    집 사진이 있고 title, content, price가 아래에 설명 돼있다고 할 때, title을 클릭하면 modal창이 뜨도록 하려고 한다. 

     

    원래는 <p @click="모달창보이나=true">{{a.title}}</p> 이런식으로 자식 vue안에 적혀있었다면 이는 자식 컴포넌트에서는 사용할 수 없는 방법이다. 

     

    why? 부모 데이터인 "모달창보이나"의 값을 false에서 true로 변경하려고 했기 때문에!! 따라서 부모에게 나 데이터 바꿀거야라고 메시지를 전달해줘야 된다. 

     

     

     

    <자식 - Card.vue>

     

    <template>
       <div v-for="(a,i) in 외부데이터" :key="i">
        <!--속성 값은 :를 붙여 v-bind로 값을 넣어줘야 한다. -->
        <img :src="외부데이터[i].image" />
        <!--props는 즉 부모에게 받아온 데이터는 자식이 수정할 수 없다. read-only
        custom event를 사용한다. -->
        <!-- <p @click="모달창보이나=true">{{a.title}}</p> -->
        <!-- $는 vue의 문법, $emit('작명', 데이터) 부모까지 메시지를 전달할 수 있다.
        만약 부모에서 데이터를 받으려면 @작명한거=""-->
        <p @click="$emit('openModal',외부데이터[i].id)">{{a.title}}</p>
        <p>{{a.content}}</p>
        <p>{{a.price}}</p>
        <!-- id = {{외부데이터[i].id}}
        {{외부데이터}} -->
      </div>
    
    
    </template>
    
    <script>
    export default {
        name : 'Card',
        props : {
            외부데이터 : Array,
        }
    
    }
    </script>
    
    <style>
    
    </style>

     

     

    openModal이라는 이름으로 외부데이터인 id의 값을 전달하는 것. 그럼 부모에서 데이터가 변경된다.

    <p @click="$emit('openModal',외부데이터[i].id)">{{a.title}}</p>

     

     

     

    <부모 App.vue>

    <Card  @openModal = "모달창보이나 = true; 사용자클릭=$event"   :외부데이터="외부데이터" />

     

    부모에 @openModal을 통해 "모달창보이나"에 true값이 저장되고 "사용자클릭"이라는 데이터에 자식에서 전달한 id의 값이 전달된다. 그렇기에 게시글에 해당하는 Modal창이 보이게 되는 것.! 

    반응형

    댓글

Designed by Tistory.