props

props는 부모 컴포넌트의 데이터를 자식 컴포넌트로 전달한다.

부모 > 자식

 

emit

자식 컴포넌트에서 $emit 이벤트를 이용해 부모 컴포넌트에서 만들어 놓은 이벤트를 호출한다.

자식 > 부모

 

BaseButton 만들기

  1. BaseButton.vue 파일을 만들어 버튼을 공통으로 사용한다.
  2. class 속성을 props로 전달받아 css를 적용한다.
  3. $emit를 사용해 부모 컴포넌트에 작성한 이벤트를 호출한다.

 

결과 화면

 

1. BaseButton 컴포넌트 만들기

  • components/base/BaseButton.vue (자식 컴포넌트)
  1. :class="[color]" color 라는 속성을 만들어 부모 컴포넌트에서 색상 값을 전달받는다. (배열 형태로 만들면 여러 가지 값을 전달받을 수 있다.)
  2. <script> 태그 안 props 부분에 color에 대한 타입을 정의한다. (타입을 정의하지 않으면 잘못된 값을 전달받았을 때 콘솔 오류가 발생한다.)
  3. 전달받은 color에 대한 css를 작성한다. (.red, .blue)
  4. @click="$emit('click')" $emit을 이용해 클릭 이벤트를 호출한다. (클릭 이벤트는 부모 컴포넌트에 만든다.)
<template>
  <button
    type="button"
    :class="[color]"
    @click="$emit('click')">
    <slot/>
  </button>
</template>

<script>
export default {
  name: 'BaseButton',

  props: {
    color: {
      type: String,
      required: false
    }
  }
}
</script>

<style lang="scss" scoped>
button {
  width: 150px;
  height: 40px;

  &.red {
    background-color: red;
  }

  &.blue {
    background-color: blue;
  }
}
</style>

 

2. BaseButton 컴포넌트 사용하기

  • pages/index.vue (부모 컴포넌트)
  1. <BaseButton> 컴포넌트를 import 한다.
  2. <BaseButton> 컴포넌트에 color 속성을 작성한다. (color="red", color="blue")
  3. @click 메서드를 통해 클릭 이벤트를 호출한다.
  4. <script> 태그 안 methods 부분에 클릭 이벤트를 작성한다. (redAlert(), blueAlert())
<template>
  <TheLayout>
    <BaseButton
      color="red"
      @click="redAlert">
      빨간색 버튼
    </BaseButton>

    <BaseButton
      color="blue"
      @click="blueAlert">
      파란색 버튼
    </BaseButton>
  </TheLayout>
</template>

<script>
import TheLayout from "@/components/layout/TheLayout"
import BaseButton from "@/components/base/BaseButton"

export default {
  name: 'Main',

  components: {
    TheLayout,
    BaseButton
  },

  methods: {
    redAlert() {
      alert('빨간색 버튼')
    },

    blueAlert() {
      alert('파란색 버튼')
    }
  }
}
</script>

결과 화면

 


1. styled-components, @types/styled-components 설치하기

styled-components 패키지와 @types/styled-components 패키지를 설치한다.

 

자바스크립트일 경우, styled-components 패키지만 설치해도 되지만,

타입스크립트에서 사용하기 위해서는 @types/styled-components 패키지도 설치해야 한다.

yarn add styled-components
또는
npm install styled-components
yarn add @types/styled-components
또는
npm install @types/styled-components

 

2. Button 컴포넌트 만들기

2-1. StyledButton 만들기

  • src/components/Button.tsx

styled-components를 import 한다.

StyledButton 컴포넌트를 만든 후, `` 안에 css를 작성한다.

StyledButton 컴포넌트를 적용할 Button 컴포넌트를 만든다. 

import styled from 'styled-components'

const StyledButton = styled.button`
  // 필요한 css를 작성한다.
  
  width: 100%;
  height: 50px;
  ...
`

const Button = () => {
  return (
    <StyledButton>버튼</StyledButton>
  )
}

export default Button

 

2-2. StyledButton에 props 적용하기

props로 값을 받기 위해서는 ${(props) => props.~} 형태로 받아야 한다.

 

backgroundColor 변수를 만들고, 필요한 값을 작성한다. (background-color가 필요했을 뿐, 다른 값들도 가능하다.)

props로 넘길 값(backgroundColor)의 타입을 정의하기 위해 interface를 만든다.

StyledButton 컴포넌트에 타입(ButtonProps)과 props로 넘길 값을 정의한다.

Button 컴포넌트의 파라미터에 variant 값을 넘긴다.

import styled from 'styled-components'

const backgroundColor = {
  primary: '#677987',
  secondary: '#B4B6AC'
}

interface ButtonProps {
  readonly variant: 'primary' | 'secondary'
}

const StyledButton = styled.button<ButtonProps>`
  width: 100%;
  height: 50px;
  background-color: ${(props) => backgroundColor[props.variant]};
  text-align: center;
`

const Button = ( { variant }: ButtonProps) => {
  return (
    <StyledButton variant={variant}>버튼</StyledButton>
  )
}

export default Button

 

2-3. 부모 컴포넌트에 값 전달하기

Button 컴포넌트의 텍스트도 props로 전달하기 위해서 children을 사용한다.

 

interface에 children의 타입을 정의한다.

Button 컴포넌트의 파라미터에 childred 값을 넘긴다.

import styled from 'styled-components'

const backgroundColor = {
  primary: '#677987',
  secondary: '#B4B6AC'
}

interface ButtonProps {
  children: string
  readonly variant: 'primary' | 'secondary'
}

const StyledButton = styled.button<ButtonProps>`
  width: 100%;
  height: 50px;
  background-color: ${(props) => backgroundColor[props.variant]};
  text-align: center;
`

const Button = ({ children, variant }: ButtonProps) => {
  return (
    <StyledButton variant={variant}>{children}</StyledButton>
  )
}

export default Button

 


최종 코드

  • src/components/Button.tsx
import styled from 'styled-components'

const backgroundColor = {
  primary: '#677987',
  secondary: '#B4B6AC'
}

const textColor = {
  primary: '#FCFCFC',
  secondary: '#FCFCFC'
}

interface ButtonProps {
  children: string
  readonly variant: 'primary' | 'secondary'
}

const StyledButton = styled.button<ButtonProps>`
  width: 100%;
  height: 50px;
  border-radius: 5px;
  background-color: ${(props) => backgroundColor[props.variant]};
  color: ${(props) => textColor[props.variant]};
  font-size: 16px;
  text-align: center;
  transition: all 0.3s;
  
  &:hover {
    opacity: 0.8;
  }
`

const Button = ({ children, variant }: ButtonProps) => {
  return (
    <StyledButton variant={variant}>{children}</StyledButton>
  )
}

export default Button

 

  • src/App.tsx

Button 컴포넌트를 import 한다.

props로 넘길 값들(children, variant)을 작성한다.

 

Title 컴포넌트도 같은 방식으로 작성됐다.

import Title from '../../components/base/Title'
import Button from '../../components/form/Button'
import './index.scss'

const App = () => {
  return (
    <>
      <div className="board-create">
        <Title children="Write content"/>
        
        <Button children="Confirm" variant="primary"/>
        <Button children="Cancel" variant="secondary"/>
      </div>
    </>
  )
}

export default App

+ Recent posts