Простой компонент Vue js для таблицы не работает

#vue.js #vue-component

Вопрос:

Я новичок в vue js. Я пытаюсь изучить пошаговые инструкции из официальной документации vue. Я попытался понять функциональность компонента и создал следующий код:

  <div id="app">
     <table class="table">
         <tr>
            <td><strong>Name</strong></td>
            <td><strong>Email Address</strong></td>                        
         </tr>
         <contact-item v-for="item in contacts" v-bind:contact="item" v-bind:key="item.id"></contact-item>                    
     </table>
 </div>
 

а вот код javascript для отображения данных строк из шаблона компонента.

 <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
    Vue.component('contact-item', {
        props: ['contact'],
        template: '<tr><td>{{ contact.name }}</td><td>{{ contact.email }}</td></tr>'
    })
    var app = new Vue({
        el: '#app',
        data: {
            contacts: [
                {id: 1, name:'John Doe', email:'John@Doe.com'},
                {id: 2, name:'Peter Drunket', email:'Peter@Drunket.com'},
                {id: 3, name:'Mike Benjamin', email:'Mike@Benjamin.com'},
            ]
        }
    });        
</script>
 

Проблема в том, что данные отображаются, но не в таблице. Он отображается сразу после раздела «приложение».

Скриншот вывода прилагается.введите описание изображения здесь

Ответ №1:

Существуют определенные предостережения при разборе шаблонов DOM, если в них смешиваются компоненты Vue и собственные элементы.

Некоторые элементы HTML, такие как <ul> , <ol> , <table> и <select> имеют ограничения на то, какие элементы могут отображаться внутри них, а некоторые элементы , такие как <li> , <tr> , и <option> могут отображаться только внутри определенных других элементов.

Это приведет к проблемам при использовании компонентов с элементами, имеющими такие ограничения. Например:

 <table>
  <blog-post-row></blog-post-row>
</table> 
 

Пользовательский компонент будет удален как недопустимое содержимое, что приведет к ошибкам в конечном выводе.

В вашем случае это привело к тому, что ваша таблица отображалась «над» заголовком. На самом деле, браузер создал в этом случае две таблицы: одну для <tr> s, заменяющую поднятый компонент, другую для «родной» таблицы, которая была в шаблоне с самого начала.

К счастью, is специальный атрибут предлагает обходной путь. Вам необходимо указать имя компонента, который вы собираетесь использовать для замены определенного собственного элемента. Не совсем удобно указывать имя этого элемента дважды (сначала в HTML, затем в самом компоненте), но, как уже было сказано, это обходной путь.

 <table>
  <tr is="blog-post-row"></tr>
</table>
 

Вот как это может выглядеть в вашем случае:

 Vue.component('contact-item', {
  props: ['contact'],
  template: '<tr><td>{{ contact.name }}</td><td>{{ contact.email }}</td></tr>'
})
var app = new Vue({
  el: '#app',
  data: {
    contacts: [{
        id: 1,
        name: 'John Doe',
        email: 'John@Doe.com'
      },
      {
        id: 2,
        name: 'Peter Drunket',
        email: 'Peter@Drunket.com'
      },
      {
        id: 3,
        name: 'Mike Benjamin',
        email: 'Mike@Benjamin.com'
      },
    ]
  }
}); 
 <div id="app">
  <table class="table">
    <tr>
      <td><strong>Name</strong></td>
      <td><strong>Email Address</strong></td>
    </tr>
    <tr is="contact-item" v-for="item in contacts" v-bind:contact="item" v-bind:key="item.id"></tr>
  </table>
</div>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> 

Комментарии:

1. Отлично! это исправило проблему. Я новичок, поэтому не знаю, рекомендуется ли использовать «is=’somename'» или использовать сам тег шаблона <somename><somename></somename>.

2. Я бы сказал, что лучше всего избегать использования шаблонов DOM: если бы у вас был компонент для всей таблицы, у вас не было бы этой проблемы. Видите ли, анализатор Vue не читает HTML, вместо этого пытаясь получить информацию из DOM. Но браузеры стараются изо всех сил поддерживать DOM таким, каким он должен быть; отсюда вышеупомянутый подъем и аналогичные эффекты.