카테고리 없음

[Vue 스터디 #4] vue 스타일 가이드, props, 이벤트

TutleKing 2024. 11. 19. 00:26

vue 스타일 가이드 - 필수 사항

https://ko.vuejs.org/style-guide/rules-essential.html

컴포넌트에는 합성어를 사용해야함

  • HTML 컴포넌트와 겹칠 수 있음.

컴포넌트 data는 function 으로 사용

  • function 의 return 값은 object 여야함
// bad
export default {
  data: {
    foo: 'bar'
  }
}

// good
export default {
  data () {
    return {
      foo: 'bar'
    }
  }
}

// 뷰 인스턴스는 예외
new Vue({
  data: {
    foo: 'bar'
  }
})

Props 정의

  • 최소한 type 설정은 필수, 더 상세하면 좋음
// bad
props: ['status']

// good
props: {
  status: String
}

// better
props: {
  status: {
    type: String,
    required: true,
    validator: function (value) {
      return [
        'syncing',
        'synced',
        'version-conflict',
        'error'
      ].indexOf(value) !== -1
    }
  }
}

v-forkey 지정

  • key를 지정하지 않을 경우, 성능이 좋지않아 질 수 있음
    • vue의 for은 수정이 필요한 부분의 DOM 만 수정하고, 나머지 DOM을 재사용하는 기법인 'in-place patch' 을 사용한다.
    • key가 없으면 한 부분의 삭제가 생길 경우, 모든 DOM의 재배열이 필요하다
// good
<ul>
  <li
    v-for="todo in todos"
    :key="todo.id"
  >
    {{ todo.text }}
  </li>
</ul>

v-forv-if 동시 사용 금지

  • 2.x버전에서는 v-for가 더 높은 우선순위
  • 3.x버전에서는 v-if가 더 높은 우선순위
  • 추천 방법
    • computed로 if 를 대체하거나
    • v-for를 동작시키는 태그를 template 로 변경
// AS-IS
<ul>
  <li
    v-for="user in users"
    v-if="user.isActive"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

// TO-BE - computed
computed: {
  activeUsers: function () {
    return this.users.filter(function (user) {
      return user.isActive
    })
  }
}

<ul>
  <li
    v-for="user in activeUsers"
    :key="user.id"
  >
    {{ user.name }}
  </li>
</ul>

// TO-BE - template
<ul>
  <template v-for="user in users" :key="user.id">
    <li v-if="user.isActive">
      {{ user.name }}
    </li>
  </template>
</ul>

스타일 태그에는 scoped

  • 다른 컴포넌트에 영향을 주지 않고 해당 SFC(싱글 파일 컴포넌트)에만 영향을 주는 스타일이 되기 위해 scoped 속성을 추가해야함
// good
<template>
  <button class="button button-close">×</button>
</template>

<!-- `scoped` 속성 사용하기 -->
<style scoped>
.button {
  border: none;
  border-radius: 2px;
}

.button-close {
  background-color: red;
}
</style>

vue 스타일 가이드 - 강력 추천 사항

https://ko.vuejs.org/style-guide/rules-strongly-recommended.html

프로젝트에서 가독성 및/또는 개발자 경험을 개선하기 위함

컴포넌트 파일

  • 컴포넌트는 파일로 가지고 있어야함 : MyButtom.vue
// bad
app.component("TodoList", {
  // ...
});

app.component("TodoItem", {
  // ...
});

싱글 파일 컴포넌트 파일명 대/소문자

  • 항상 파스칼 케이스이거나 항상 케밥 케이스
    • 많은 에디터에서 지원, 템플릿을 참조하는 케이스에서도 파스칼 케이스를 자동으로 참조 할 수 있음
// good
components/
|- MyComponent.vue // 파스칼

components/
|- my-component.vue // 케밥

Props

  • 컴포넌트에 등록할 수 있는 사용자 정의 속성 (단방향 : 부모 -> 자식 = 하향식 단방향 바인딩)
    • 부모 컴포넌트에서 데이터 전달 가능
    • 부모 컴포넌트에서는 케밥 케이스로 선언 필요 (greeting-message)
      • props 를 선언하는 자식에서는 camelCase로 선언 필요
  • 명시적인 선언 필요
    • 컴포넌트에 전달된 외부 props가 fallthrough 속성으로 처리 되어야함을 알 수있음
      • fallthrough 속성 : props 또는 emits에 명시적으로 선언되지 않은 속성 또는 이벤트
  • 정적 / 동적 전달
    • 정적 : <ComA title="가나다">
    • 동적 : <ComA :title="post.title"> (v-bind를 사용)
      • 객체 자체를 넘길때는 <ComA v-bind="post">
  • 단방향이기 때문에, 부모 컴포넌트에서 props가 변경되면 자식 컴포넌트에서도 함께 변경
    • 그렇기때문에 자식 컴포넌트에서는 변경하면 안됨
      • 변경하고싶다면 local 변수로 재할당 필요 (local 변수는 참조값이 아니게 됨)
      • 그럼에도 진짜 변경해야한다면 emit으로 부모 컴포넌트에서 직접 바꾸도록 변경
    • 주로 computed 와 함께 사용 : 부모가 변하면 computed가 동작해서 적용

문자열 배열, 객체문법 선언

export default {
  props: ['title'], // 문자열 배열
  props: { // 객체 문법
    title: String,
    likes: Number
  }
  setup(props) {
    console.log(props.title)
  }
}
  • 객체문법 사용시
    • type 지정 가능 (모든 것이 다 올 수 있음)
    • default : 속성값이 비어있거나, undefined 이면 기본값으로 사용
    • required (boolean) : 필수값 설정
    • validator : 유효성 검사시 사용
 propF: {
    validator(value) {
      // The value must match one of these strings
      return ['success', 'warning', 'danger'].includes(value)
    }
  },
  propG: {
    type: Function,
    // Unlike object or array default, this is not a factory function - this is a function to serve as a default value
    default() {
      return 'Default function'
    }
  }

  // boolean casting
  export default {
    props: {
        disabled: Boolean
    }
  }

  <MyComponent disabled /> // :disabled="true"
  <MyComponent /> // :disabled="false"

props 사용

  • <template>에서 바로 사용 : {{title}}
  • $props 객체로 사용 : {{$props}}
    • default 안에서 사용할때는 this.$props

Events

  • emit : 자식 컴포넌트에서도 부모 컴포넌트로 데이터 전달 또는 트리거링 하기 위해 이벤트 발행
    • <button @click="$emit('someEvent','ABC123')">click me</button>
    • this.$emit('someEvent')
  • 부모 컴포넌트에서는 수신을 v-on(@)로 하고 네이밍은 케밥 케이스로 한다.
    • <MyComponent @some-event="callFunction" />
    • callFunction = (인자1) => {인자1 사용}
  • 문자열 배열 / 객체 선언
    • emits: ['inFocus', 'submit']
    • emit: {submit : (인자1)=>{validtion for 인자1}, fork:null}
반응형