Vue элементов не отображаются - PullRequest
1 голос
/ 10 февраля 2020

Я пытаюсь создать Vue элементы, используя template элементы в теле HTML. Это работало довольно хорошо, пока я не попытался использовать два из них вместе.

<template id="root-template">
  <div>
    <app-navbar targetId="#app-sidenav" />
    <app-header />
  </div>
</template>

По некоторым причинам, комментирование app-navbar приводит к отображению app-header, однако, если отображается app-navbar, app-header вообще не отображается! Этот полностью поставил меня в тупик.

const Navbar = Vue.component("app-navbar", {
  name: "app-navbar",
  template: "#navbar-template",
  props: {
    targetId: {
      type: String,
      default: "#app-sidenav"
    }
  },
  mounted() {
    this.sidenav = M.Sidenav.init(document.querySelector(this.targetId));
  },
});

const Header = Vue.component("app-header", {
  name: "app-header",
  template: "#header-template"
});

const AppRoot = Vue.component("app-root", {
  template: "#root-template",
  components: {
    Navbar,
    Header
  },
});

const store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {}
});

const app = new Vue({
  el: "#app",
  store,
  render: h => h(AppRoot)
});
<script src="https://unpkg.com/vuex@3.1.2/dist/vuex.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css" rel="stylesheet" />
<link href="https://fonts.googleapis.com/icon?family=Material+Icons&type=.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<ul class="sidenav" id="app-sidenav">
  <li><a href="#">Sass</a></li>
  <li><a href="#">Components</a></li>
  <li><a href="#">Javascript</a></li>
  <li><a href="#">Mobile</a></li>
</ul>
<div id="app" />
<template id="navbar-template">
  <nav>
    <div class="nav-wrapper container">
      <a href="#!" class="brand-logo">Logo</a>
      <a href="#" data-target="app-sidenav" class="sidenav-trigger">
        <i class="material-icons">menu</i>
      </a>
      <ul class="right hide-on-med-and-down">
        <li><a href="#">Sass</a></li>
        <li><a href="#">Components</a></li>
        <li><a href="#">Javascript</a></li>
        <li><a href="#">Mobile</a></li>
      </ul>
    </div>
  </nav>
</template>
<template id="header-template">
  <div class="section no-pad-bot" id="index-banner">
    <div class="container">
      <br /><br />
      <h1 class="header center orange-text">Todos</h1>
      <div class="row center">
        <h5 class="header col s12 light">
          A modern responsive front-end framework based on Material Design
        </h5>
      </div>
      <div class="row center">
        <a href="http://materializecss.com/getting-started.html" id="download-button"
          class="btn-large waves-effect waves-light orange">Get Started</a>
      </div>
      <br /><br />
    </div>
  </div>
</template>
<template id="root-template">
  <div>
    <app-navbar target-id="#app-sidenav" />
    <app-header />
  </div>
</template>

Я также превратил это в Ручку . Может кто-нибудь сказать мне, почему это происходит?

Ответы [ 2 ]

2 голосов
/ 10 февраля 2020

Вы должны поместить шаблоны в функции, если вы используете единый файловый подход. Посмотрите код ниже для примера. Шаблоны не анализируются должным образом из-за самозакрывающегося синтаксиса и, следовательно, только отображения одного компонента. Когда вы используете строки шаблона, вы можете получить ожидаемое отображение из шаблонов того, как они есть у вас сейчас. Просто поместите их в template: функции компонента следующим образом:

const Navbar = Vue.component("app-navbar", { 
    name: "app-navbar", 
    template: 
      `
       <nav>
        <div class="nav-wrapper container">
          <a href="#!" class="brand-logo">Logo</a>
          <a href="#" data-target="app-sidenav" class="sidenav-trigger">
            <i class="material-icons">menu</i>
          </a>
          <ul class="right hide-on-med-and-down">
            <li><a href="#">Sass</a></li>
            <li><a href="#">Components</a></li>
            <li><a href="#">Javascript</a></li>
            <li><a href="#">Mobile</a></li>
          </ul>
        </div>
      </nav>
      `, 
    props: { 
      targetId: { 
        type: String, 
        default: "#app-sidenav" 
      } 
    },
    mounted() {
      this.sidenav = M.Sidenav.init(document.querySelector(this.targetId));
    },
});

const Header = Vue.component("app-header", {
  name: "app-header",
  template: 
    `
    <div class="section no-pad-bot" id="index-banner">
      <div class="container">
        <br /><br />
        <h1 class="header center orange-text">Todos</h1>
        <div class="row center">
          <h5 class="header col s12 light">
            A modern responsive front-end framework based on Material Design
          </h5>
        </div>
        <div class="row center">
          <a href="http://materializecss.com/getting-started.html" id="download-button"
            class="btn-large waves-effect waves-light orange">Get Started</a>
        </div>
        <br /><br />
      </div>
    </div>
    `
});

const AppRoot = Vue.component("app-root", {
  template: 
    `
    <div>
      <!--   Comment out the navbar to see the header. expected behavior is that both ar displayed   -->
      <app-navbar target-id="#app-sidenav" />
      <app-header />
    </div>
    `,
  components: { Navbar, Header },
});

store = new Vuex.Store({
  state: {},
  getters: {},
  mutations: {},
  actions: {}
});

app = new Vue({
  el: "#app",
  store,
  render: h => h(AppRoot)
});

Удалите шаблоны из своего пера кода и добавьте это к JS, чтобы увидеть, как оно работает. В качестве альтернативы вы можете использовать синтаксис закрывающих тегов для своих компонентов, но более удобочитаемым и интуитивно понятным является использование самозакрывающихся тегов и разделение битов отображения на их функции вместо большого двоичного объекта <template></template> тегов. Просто мое мнение о чистом коде, поэтому не стесняйтесь использовать любой подход по желанию / необходимости.

2 голосов
/ 10 февраля 2020

Не используйте самозакрывающиеся теги в обычных HTML файлах.

Если вы измените эти строки HTML:

<app-navbar target-id="#app-sidenav" />
<app-header />

на эти:

<app-navbar target-id="#app-sidenav"></app-navbar>
<app-header></app-header>

это будет работать.

...