vue.js

vue 문법 [컴포넌트]

youngseokim_kr 2021. 11. 8. 20:44

props

<template>
  <MyBtn>Banana</MyBtn>
  <MyBtn
    :color="color">
    <span style="color:red;">Banana</span>
  </MyBtn>
  <MyBtn
    large
    color="royalblue">
    Apple
  </MyBtn>
  <MyBtn>Cherry</MyBtn>
</template>

<script>
import MyBtn from '~/components/MyBtn'

export default {
  components : {
    MyBtn
  },
  data() {
    return {
      color:'#000'
    }
  }
}
</script>

app.vue를 작성하고 컴포넌트를 불러와서 같은 버튼을 여러개 만든다.

<template>
  <div 
    :class="{large}"
    :style="{background : color }"
    class="btn">
    <slot></slot>
  </div>
</template>

<script>
export default {
  // 속성을 정의해주는 옵션
  props : {
    color: {
      type: String,
      default : 'gray'
    },
    large : {
      type : Boolean,
      default:false
    }
  }
}
</script>

<style scoped lang="scss"> 
  .btn {
    display: inline-block;
    margin:4px;
    padding:6px 12px;
    border-radius : 4px;
    background-color:  gray;
    color : white;
    cursor:pointer;
    &.large {         //scss 중첩문법
    font-size:20px;
    padding:10px 20px;
  }
  }

</style>

MyBtn.vue를 만들고 버튼의 속성과 버튼에 대해서 정의하고 props를 이용하여 버튼의 속성을 변경할 수 있도록 만들어준다. mybtn 태그를 열고 닫고 그 안에 값을 작성하고 slot을 통해서 값을 받아오고 글씨도 스타일을 추가할 수 있다.

버튼 크기도 추가해줄 수 있다.

속성 상속

<template>
  <div 
    class="btn">
    <slot></slot>
  </div>
  <!-- 최상의 요소가 2개 이상이 되면 클래스나 style이 적용되지 않는다. -->
  <h1 v-bind="$attrs"></h1>
  </h1:class=>
</template>

<script>
export default {
  inheritAttrs:false,
  //  상속이 하나여도 상속하지 않겠다.
  created() {
    console.lg(this.$attrs)
  }
}
</script>

<style scoped lang="scss"> 
  .btn {
    display: inline-block;
    margin:4px;
    padding:6px 12px;
    border-radius : 4px;
    background-color:  gray;
    color : white;
    cursor:pointer;
}
  

</style>

Emit

<template>
  <div 
    class="btn">
    <slot></slot>
  </div>
  <h1 @dblclick="$emit('kk',$event)">
    ABC
  </h1>
  <input
    type="text"
    v-model="msg" />
</template>

<script>
export default {
  emits : [
    'kk',
    'changeMsg'
  ],
  data() {
    return {
      msg: ''
    }
  },
  watch: {
    msg() {
      this.$emit('changeMsg',this.msg)
    }
  }
}
</script>

<style scoped lang="scss"> 
  .btn {
    display: inline-block;
    margin:4px;
    padding:6px 12px;
    border-radius : 4px;
    background-color:  gray;
    color : white;
    cursor:pointer;
}
  

</style>
<template>
  <MyBtn
    @kk="log"
    @change-msg="logMsg">
    Banana
  </MyBtn>
</template>

<script>
import MyBtn from '~/components/MyBtn'

export default {
  components : {
    MyBtn
  },
  methods : {
    log(event){
      console.log('Clikck!!')
      console.log(event)
    },
    logMsg(msg){
      console.log(msg)
    }
  }
}
</script>

slot

<template>
  <MyBtn>
    <!--#->v-slot icon으로 들어가는 구조 -->
    <template #icon>
      <span>(B)</span>
    </template>
    <!-- text를 찾아서 들어가는 구조 -->
    <template #text>
      <span>Banana</span>
    </template>
  </MyBtn>
</template>

<script>
import MyBtn from '~/components/MyBtn'

export default {
  components : {
    MyBtn
  }
}
</script>
<template>
  <div 
    class="btn">
    <slot name="icon"></slot>
    <slot name="text"></slot>
  </div>
</template>



<style scoped lang="scss"> 
  .btn {
    display: inline-block;
    margin:4px;
    padding:6px 12px;
    border-radius : 4px;
    background-color:  gray;
    color : white;
    cursor:pointer;
}
  

</style>

provide,inject

<template>
  <button @click="message='Good?'">
    Click!
  </button>
  <h1>App:{{ message }}</h1>
  <Parent />
</template>

<script>
import Parent from '~/components/Parent'
import {computed} from 'vue'

export default {
  components : {
    Parent
  },
  data() {
    return {
      message : 'Hello world!'
    }
  },
  provide() {  //provide 는 반응성을 유지할 수 없다.
    return{
      msg : computed(()=> {      //반응형을 유지하려면 이렇게 출력해야한다.
        return this.message
      })
    }
  }
}
</script>

app.vue

<template>
  <div>
    Child :{{ msg.value }}
  </div>
</template>

<script>

export default {
 inject : ['msg']
}
</script>

Child.vue

Parent.vue 도 있지만 거치지 않고 두곳을 바로 연결하는  provide가 있다.

Refs

<template>
  <Hello ref="hello" />
</template>

<script>
import Hello from '~/components/Hello'
export default {
  components : {
    Hello
  },
//created에서는 안된다.
  mounted() {
    console.log(this.$refs.hello.$el)
  }
}
</script>

'vue.js' 카테고리의 다른 글

vue Router  (0) 2021.11.09
vue3 문법 [컴포지션API]  (0) 2021.11.08
vue 문법[v-model]  (0) 2021.11.07
vue3 문법 [이벤트 핸들링]  (0) 2021.11.07
vue3 문법[클래스와 스타일 바인딩, 조건부 렌더링, 리스트 렌더링]  (0) 2021.11.07