Programing

VueJS에서 v-for 지시문을 사용하여 여러 루트 요소를 렌더링하는 방법

c10106 2022. 4. 12. 20:17
반응형

VueJS에서 v-for 지시문을 사용하여 여러 루트 요소를 렌더링하는 방법

지금, 나는 내 노드에 공급된 최근 뉴스 게시물을 보여주는 웹사이트를 만들려고 한다.JS API.

다음 사항을 시도해 보았다.

HTML

<div id="news" class="media" v-for="item in posts">
    <div>
        <h4 class="media-heading">{{item.title}}</h4>
        <p>{{item.msg}}</p>
    </div>
</div>

자바스크립트

const news = new Vue({
    el: '#news',
    data:   {
        posts:  [
            {title: 'My First News post',   msg: 'This is your fist news!'},
            {title: 'Cakes are great food', msg: 'Yummy Yummy Yummy'},
            {title: 'How to learnVueJS',    msg: 'Start Learning!'},
        ]
    }
})

보아하니, 부에가 여러 개의 루트 요소를 렌더링할 수 없기 때문에 위와 같은 것은 효과가 없었다.

나는 VueJS의 공식 매뉴얼을 찾아봤지만 해결책을 생각해 낼 수가 없었다.한동안 구글로 검색해 보니 복수의 루트 요소를 렌더링하는 것이 불가능하다는 것을 이해했지만, 아직 해결책을 내놓지 못했다.

여러 루트 요소를 추가하는 가장 간단한 방법은 단일 요소를 추가하는 것이다.<div>렌더링을 위한 CSS 마법과 함께 소자를 포장하고 사라지게 한다.

이를 위해 "디스플레이: 콘텐츠" CSS 속성을 사용할 수 있다.그 효과는 용기를 사라지게 하여 원소의 어린이 원소가 DOM에서 다음 단계로 올라가게 하는 것이다.

따라서 Vue 구성 요소 템플릿에서 다음과 같은 기능을 사용할 수 있다.

<template>
    <div style="display: contents"> <!-- my wrapper div is rendered invisible -->
        <tr>...</tr>
        <tr>...</tr>
        <tr>...</tr>
    </div>
</template>

래핑으로 인해 브라우저가 포맷을 망치지 않고 구성 요소를 사용할 수 있는 경우<div>루트 요소는 표시 목적으로 브라우저에 의해 무시된다.

<table>
   <my-component></my-component> <!-- the wrapping div will be ignored -->
</table>

그러나 대부분의 브라우저에서는 이 기능이 작동하지만 대상 브라우저를 처리할 수 있는지 확인하려면 여기를 클릭하십시오.

사용자 지정 지시어 정의:

Vue.directive('fragments', {
  inserted: function(el) {
    const children = Array.from(el.children)
    const parent = el.parentElement
    children.forEach((item) => { parent.appendChild(item) })
    parent.removeChild(el)
  }
});

그런 다음 구성요소의 루트 요소에 사용할 수 있다.

<div v-fragments>
  <tr v-for="post in posts">...</tr>
</div>

루트 요소는 테이블을 렌더링할 때 특히 효과적인 DOM에서 렌더링되지 않는다.

렌더 함수를 사용하여 여러 루트 요소(또는 구성 요소)를 가질 수 있음

간단한 예로는 여러 개의 부품을 렌더링하는 구성 요소가 있다.<li>요소:

<template>
 <li>Item</li>
 <li>Item2</li>
 ... etc
</template>

그러나 위의 내용은 오류를 일으킬 것이다.이 오류를 해결하기 위해 위의 템플릿을 다음으로 변환할 수 있다.

export default {
 functional: true,
 render(createElement) {
  return [
    createElement('li', 'Item'),
    createElement('li', 'Item2'),
  ]
 }
}

하지만 여러분이 아마 눈치채셨을 겁니다. 예를 들어 여러분이 50리짜리 아이템을 전시하고 싶다면, 이것은 매우 지루할 수 있다.따라서 결국 동적으로 요소를 표시하기 위해 다음과 같은 작업을 수행할 수 있다.

export default {
 functional: true,
 props: ['listItems'], //this is an array of `<li>` names (e.g. ['Item', 'Item2'])

 render(createElement, { props }) {
   return props.listItems.map(name => {
     return createElement('li', name)
   })
 }
}

그러한 예에서 는 속성 기능을 사용했다: 사실이지만 물론 "렌더 함수"를 사용할 필요는 없다.여기서 기능 구성 요소에 대해 자세히 알아보십시오.

Vue는 단일 루트 노드가 있어야 한다.그러나 다음과 같이 html을 변경해 보십시오.

<div id="news" >
    <div class="media" v-for="item in posts">
       <h4 class="media-heading">{{item.title}}</h4>
       <p>{{item.msg}}</p>
    </div>
</div>

이러한 변경은 단일 루트 노드 id="news"를 허용하지만 여전히 최근 게시물 목록을 렌더링할 수 있다.

Vue 3에서는 이 기능이 다음과 같이 지원됨:

3.x에서 구성요소는 이제 여러 루트 노드를 가질 수 있다!그러나 이를 위해서는 개발자가 속성을 분배해야 할 위치를 명시적으로 정의해야 한다.

<!-- Layout.vue -->
<template>
  <header>...</header>
  <main v-bind="$attrs">...</main>
  <footer>...</footer>
</template>

Vue에서 여러 루트 요소가 지원되지 않음(이러한 루트 요소는v-for지시, 하나 이상의 요소를 렌더링할 수 있으므로).또한 매우 간단하게 해결할 수 있다. HTML을 다른 요소가 할 수 있는 것으로 포장하십시오.

예를 들면 다음과 같다.

<div id="app">
   <!-- your HTML code -->
</div>

그리고 js:

var app = new Vue({
  el: '#app', // it must be a single root!
  // ...
})

참조URL: https://stackoverflow.com/questions/47511674/a-way-to-render-multiple-root-elements-on-vuejs-with-v-for-directive

반응형