【问题标题】:Cannot use v-for on stateful component root element because it renders multiple elements无法在有状态组件根元素上使用 v-for,因为它呈现多个元素
【发布时间】:2020-08-08 13:11:41
【问题描述】:

postman.response.txt https://gist.github.com/stanislavgr79/e82999e5ae69876f0316280687388a25

var app = new Vue({
    el: "#app3",
    data: {
        path: "",
        sortEvent: "",
        eventsValue: [],
    },

    methods: {
        getResponse(){
          this.requestByParam(this.sortEvent);
        },
        requestByParam: function (byParam) {
            this.$http
                .get(this.path, {
                    params: { sortEvent: this.sortEvent },
                    headers: {
                        "Content-Type": "application/json",
                        Accept: "application/json",
                    },
                })
                .then((response) =>
                    response.json().then((data) => {
                        let listResultQuery = [];
                        if (data.length == 0) {
                            return;
                        }
                    //    data.forEach((element) => {
                    //   listResultQuery.push(element);
                         // dont work
                    });
                        this.eventsValue = data;
                        this.emptyMessage = "";
                    })
                );
        },
    },
});




 <div id="app3">
        <events_nav path=${resource.path}></events_nav>
        <all_events id="all-events" :eventsValue="eventsValue"></all_events>
</div>

我尝试重新格式化:

 $.ajax({
            type: method_event,
            url: path_event + '.sort.json',
            data: params,
            contentType: 'application/json',
            success: function (response, status, request) {
                if (status == 'success') {
                    var output = "";

                    $.each(response, function (key, value) {
                        output += "<div class='span3'>";
                        output += "<h3>" + key + "<i class='events__" + key + "'></i></h3>";

                        $(value).each(function (index, el) {
                            output += "<ul class='icons icons_type'><i class='icon-" + el.topic + "'></i>";
                            output += "<li class='events_type'>";
                            output += "<span class='date' type='date'>" +    formatDate(el.eventStartDate) + "</span>";
                            output += "<h4><a href='"+el.titleLink+"' rel='"+el.typeOfOpen+"'>" + el.title + "</a></h4>";
                            output += el.description;
                            output += "</li></ul>";
                        });
                        output += "</div>";
                        $('#all-events').html(output);
                });
            }
        }
    })
}

现在我有错误:

Vue.component("all_events", {
props: {
    eventsValue: Array,
},
template:
    '<div class="span3" v-for="(value, name) in eventList">' +
    '<h3>{{ name }}<i class="events__{{ name }}"></i></h3>' +
    '</div>',
});

eventsValue - 它的对象 ?????它的数组?????????

我需要写什么模板才能看到关键

$.each(response, function (key, value) {
                        output += "<div class='span3'>";
                        output += "<h3>" + key + "<i class='events__" + key + "'></i></h3>";

此方法无效:

<ul id="example-1">
  <li v-for="item in items" :key="item.message">
    {{ item.message }}
  </li>
</ul>

这不起作用:

<ul id="example-2">
  <li v-for="(item, index) in items">
    {{ parentMessage }} - {{ index }} - {{ item.message }}
  </li>
</ul>

这不起作用:

<ul id="v-for-object" class="demo">
  <li v-for="value in object">
    {{ value }}
  </li>
</ul>

这不起作用:

<div v-for="(value, name) in object">
  {{ name }}: {{ value }}
</div>

这不起作用:

<div v-for="(value, name, index) in object">
  {{ index }}. {{ name }}: {{ value }}
</div>

【问题讨论】:

    标签: javascript json vue.js


    【解决方案1】:

    对于错误“Cannot use v-for on stateful component root element because it renders multiple elements”

    您只需要将模板包装在另一个 dom 元素中

    示例:

    Vue.component("all_events", {
    props: {
        eventsValue: Array,
    },
    template:`
    <div>
      <div class="span3" v-for="(value, name) in eventList">
        <h3>{{ name }}<i class="events__{{ name }}"></i></h3>
      </div>
    </div>
    `});
    

    在重新格式化之前尝试使用代码。

    【讨论】:

      【解决方案2】:

      此代码有效。感谢社区和丹尼尔

      Vue.component("events_nav", {
          props: {
              dataPath: String,
          },
          data() {
              return {
                  sortEvent: "topic",
                  topic: true,
                  type: false
              };
          },
          methods: {
              requestTopic: function () {
                  this.sortEvent = "topic";
                  this.$root.sortEvent = this.sortEvent;
                  this.topic = true;
                  this.type = false;
                  this.$root.getResponse();
              },
              requestType: function () {
                  this.sortEvent = "type";
                  this.$root.sortEvent = this.sortEvent;
                  this.topic = false;
                  this.type = true;
                  this.$root.getResponse();
              },
          },
          created: function () {
              let servletSelector = ".sort";
              let servletExtension = ".json";
      
              this.$root.dataPath = this.dataPath.concat(
                  servletSelector,
                  servletExtension
              );
              this.$root.sortEvent = this.sortEvent;
              this.$root.getResponse();
          },
          template:
              '<div class="navbar events_nav">' +
              '<div class="navbar-inner">' +
              '<span class="brand">View By:</span>' +
              '<ul class="nav" id="event_sort" data-sort="topic" data-method="GET" :data-path="dataPath">' +
              '<li :class="{active: topic}" id="events__view-topic"><span @click="requestTopic">Topic</span></li>' +
              '<li :class="{active: type}" id="events__view-type"><span @click="requestType">Type</span></li>' +
              '</ul>' +
              '</div>' +
              '</div>',
      });
      
      Vue.component("all-events", {
          props: {
              eventsValue: "",
          },
          template:
              '<div class="row event-listing">' +
              '<div class="span3" v-for="(value, name) in eventsValue">' +
              '<h3>{{ name }}<event-icon :icon="name"></event-icon></h3>' +
              '<event-column :value="value"></event-column>' +
              '</div>' +
              '</div>',
      });
      
      
      Vue.component("event-icon", {
          props: {
              icon: String,
          },
          computed: {
              classIcon: function () {
      
                  let icon = '';
      
                  if (this.$props.icon == 'Database') {
                      icon = 'icon-hdd'
                  }
                  if (this.$props.icon == 'Cloud') {
                      icon = 'icon-cloud'
                  }
                  if (this.$props.icon == 'Mobile') {
                      icon = 'icon-mobile-phone'
                  }
                  if (this.$props.icon == 'Other Topics') {
                      icon = 'icon-calendar'
                  }
      
                  return icon;
              }
          },
          template:
              '<i :class="classIcon"></i>',
      });
      
      Vue.component("event-column", {
          props: {
              value: Array,
          },
          template:
              '<ul class="unstyled" >' +
              '<li class="event-list" v-for="item in this.$props.value">' +
              '<element-event :element="item"></element-event>' +
              '</li>' +
              '</ul>',
      });
      
      Vue.component("element-event", {
          props: {
              element: Object,
          },
          data() {
              return {
                  description: "",
                  eventdate: ""
              };
          },
          computed: {
              classIcon: function () {
      
                  let icon = '';
      
                  if (this.$props.element.topic == 'Database') {
                      icon = 'icon-hdd'
                  }
                  if (this.$props.element.topic == 'Cloud') {
                      icon = 'icon-cloud'
                  }
                  if (this.$props.element.topic == 'Mobile') {
                      icon = 'icon-mobile-phone'
                  }
                  if (this.$props.element.topic == 'Other Topics') {
                      icon = 'icon-calendar'
                  }
      
                  return icon;
              },
              selectTopic: function () {
                  let result = false;
                  if (this.$root.sortEvent == "type") {
                      result = true;
                  }
      
                  return result;
              }
      
          },
          methods: {
              formatDate() {
                  return new Date(this.$props.element.eventStartDate).toLocaleString('en-US', {
                      day: '2-digit',
                      month: 'long'
                  });
              },
          },
          template:
              '<div>' +
              '<i v-if="selectTopic" class="icon" v-bind:class="classIcon"></i>' +
              '<span class="date" type="date" v-html="formatDate()"></span>' +
              '<h4><a :href="element.titleLink" :rel="element.typeOfOpen" v-html="element.title"></a></h4>' +
              '<p class="event-description" v-html="element.description"></p>' +
              '</div>',
      
      })
      
      var app = new Vue({
          el: "#eventviewer-v2",
          data: {
              dataPath: "",
              sortEvent: "",
              events: "",
          },
      
          methods: {
              getResponse() {
                  this.requestByParam(this.sortEvent);
              },
              requestByParam: function (byParam) {
                  this.$http
                      .get(this.dataPath, {
                          params: { sortEvent: this.sortEvent },
                          headers: {
                              "Content-Type": "application/json",
                              Accept: "application/json",
                          },
                      })
                      .then((response) =>
                          response.json().then((data) => {
                              this.events = data;
                              this.emptyMessage = "";
                          })
                      );
              },
          },
      });
      

      【讨论】:

        【解决方案3】:

        要移除包裹元素...

        mounted () {
          this.$el.replaceWith(...this.$el.childNodes)
        }
        

        【讨论】:

          猜你喜欢
          • 2017-10-26
          • 2018-01-15
          • 2018-06-09
          • 2018-05-10
          • 2018-03-13
          • 1970-01-01
          • 2021-06-18
          • 2019-11-27
          • 1970-01-01
          相关资源
          最近更新 更多