Vue의 name 옵션은 중요할까

dante Yoon·2023년 11월 9일
1

vue

목록 보기
2/5
post-thumbnail

Vue2 options API의 name

Single File Component (SFC)에서 Vue2의 options API를 사용하면 컴포넌트 정의시 다음과 같은 문법을 사용하게 됩니다.

// CustomComponent.vue 
<script>
  export default {
    name: "CustomComponent",
    props: {
      tree: Object
    },
    data() {
      ...
    },
    created(){
    },
    methods: {
      // ... 
    }
  }
</script>

name 옵션을 사용했을 때의 장점에 대한 Vue3의 최신 문서 설명을 보면 아래와 같이 나와있습니다.

1.Recursive self-reference in the component's own template
컴포넌트가 스스로 자기자신을 참조할 때
2.Display in Vue DevTools' component inspection tree
vue-devtools에서 컴포넌트를 추적할 때
3.Display in warning component traces
콘솔로그 경고창에 component가 스택 트레이스로 표기될 때

SFC에서의 name 옵션

현업에서는 극히 일부분, 스프링이나 php등 서버사이드 개발환경에서 웹팩이나 Vite.js를 사용하지 않고 뷰를 사용해야하는 급조된 FE 개발 환경을 제외하고는 .vue 형식의 파일에 컴포넌트를 작성합니다. 이 파일에 작성된 컴포넌트를 SFC라고 부릅니다.

SFC를 사용하게 되면 항상 번들러를 사용해 빌드과정을 거치기 때문에 name 옵션을 사용하지 않아도 타입스크립트가 자동으로 타입을 추론하듯이 뷰가 충분히 똑똑하게 컴포넌트 이름을 추론할 수 있습니다.
뷰 컴파일러가 .vue로 작성된 파일들을 브라우저에서 실행가능한 자바스크립트로 변경해줍니다.

Vite에서는 @vitejs/plugin-vue, Webpack에서는 vue-loader가 공식적으로 지원하는 플러그인이며 빌드시스템이 SFC를 이해할 수 있게 파싱해주는 역할을 합니다.

이렇게 SFC를 파싱하는 것을 도와주는 플러그인이 없으면 뷰는 컴포넌트의 이름을 정상적으로 추론할 수 없게 되며 아래와 같이 SFC를 사용할 수 없게 됩니다.

.vue 파일을 파싱해주는 플러그인이 없기 때문에 에러가 발생하는 모습

Vite의 경우 파일시스템 구조를 사용해 모듈의 이름을 가져오고 .vue 파일을 임포트할 경우 파일 경로를 모듈의 식별자로 사용합니다.

.vue 파일을 임포트하여 Vite로 부터 식별자를 건너받게 되면

import MyComponent from './MyComponent.vue';

Handling Imports: When you import a Vue SFC, Vite looks at the filename and path. The @vitejs/plugin-vue then takes this information and processes the .vue file, extracting its script, template, and style parts.

@vitejs/plugin-vue가 SFC에서 script, template, style 태그를 파싱합니다.
이때 전달받은 식별자를 보고 컴포넌트의 이름을 추론할 수 있습니다.
위의 예제코드의 MyComponent의 이름은 name옵션이 없이도 MyComponent로 추론되어 <my-component> 와 같이 kebab-case로도 사용될 수 있는 것입니다.

따라서 SFC를 작성할 때 name 옵션을 사용하지 않아도 devtools를 사용하거나 개발을 할때 문제되는 부분은 없습니다.

재귀형식으로 컴포넌트를 작성할때

앞서서 재귀형식으로 작성된 컴포넌트에서 name옵션이 필요하다고 했습니다.

1.Recursive self-reference in the component's own template

SFC를 재귀형식으로 작성해보고 name 옵션을 삭제하여 테스트를 해봅시다.

Vue2에서는 warning이 발생하고 Vue3에서는 name 옵션을 사용하지 않아도 warning이 발생하지 않습니다.

App.vue와 TreeNode.vue 코드를 먼저 보겠습니다.

// App.vue
<template>
  <div id="app">
    <TreeNode :treeData="nestedData" />
  </div>
</template>

<script>
import TreeNode from "./components/TreeNode.vue";

const nestedData = [
  {
    id: 1,
    name: "Folder 1",
    children: [
      { id: 2, name: "File 1-1" },
      { id: 3, name: "File 1-2" },
    ],
  },
  {
    id: 4,
    name: "Folder 2",
    children: [
      { id: 5, name: "File 2-1" },
      {
        id: 6,
        name: "Folder 2-1",
        children: [
          {
            id: 7,
            name: "File 2-1-1",
            children: [
              {
                id: 8,
                name: "Folder 2-1-1",
                children: [{ id: 9, name: "File 2-1-1-1" }],
              },
            ],
          },
        ],
      },
    ],
  },
];

export default {
  name: "App",
  components: {
    TreeNode,
  },
  data() {
    return {
      nestedData,
    };
  },
};
</script>

App.vue 파일 내부에서는 TreeNode 컴포넌트를 임포트하여 미리 정의해둔 트리 구조의 데이터를 props로 전달합니다.

이어서 TreeNode 컴포넌트를 보겠습니다.
options api로 작성되었습니다.

<script>
export default {
  // name: "Node",
  props: {
    treeData: {
      type: Array,
      required: true,
    },
  },
};
</script>

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      {{ item.name }}
      <!-- Check if the item has children and recursively call TreeNode component -->
      <TreeNode
        v-if="item.children && item.children.length"
        :treeData="item.children"
      />
    </li>
  </ul>
</template>

item.children을 props로 다시 자기 자신을 template에 그리는 재귀형식의 컴포넌트입니다.

뷰의 버전만 다르게 하여 화면에 표기하겠습니다.

vue2.7

name 옵션을 지정해주지 않자 warning과 함께 올바른 컴포넌트가 렌더링 되지 않는 vue 2.7

warning 메세지와 더불어 올바르게 렌더링 되는 vue 3.3

동적 컴포넌트

만약 Dynamic Component를 이용해 컴포넌트를 렌더링 할때는 항상 name을 설정해야 합니다.

vue2

<script>
export default {
  name: "TreeNode",  
  props: {
    treeData: {
      type: Array,
      required: true
    }
  },
};
</script>

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      {{ item.name }}
      <component is="TreeNode" :treeData="item.children">
        <!-- content -->
      </component>
    </li>
  </ul>
</template>

예제에서는 :is v-bind가 아닌 is props에 스트링 값을 넣었지만 :is로 동적인 값을 넣어도 마찬가지로 name 옵션이 필요합니다. 그렇지 않으면 정상적으로 렌더링 되지 않습니다.

vue3

<script>
  export default {
    name: "TreeNode"
  }
</script>

<script setup>
defineProps({
  treeData: {
    type: Array,
    required: true,
  }
})

</script>

<template>
  <ul>
    <li v-for="item in treeData" :key="item.id">
      {{ item.name }}
      <component is="TreeNode" :treeData="item.children">
        <!-- content -->
      </component>
    </li>
  </ul>
</template>

뷰3의 script setup 태그 사용시 name 옵션을 사용하기 위해서는 위와 같이 별도 script 태그를 작성하고 name을 설정해주어야 합니다.

profile
성장을 향한 작은 몸부림의 흔적들

0개의 댓글