You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue组件中v-for无输出问题:页面仅显示<!---->

问题:Vue中v-for无法渲染骨架文本,仅显示<!---->

你的代码里skeleton-body组件的v-for没有生成预期的5行骨架文本,浏览器只输出注释节点,核心原因和修复方案如下:

问题根源

  1. 数据类型不匹配:父组件中lines="5"是字符串类型,Vue的v-for="n in lines"会把字符串当作字符序列遍历(仅循环1次),而非数字对应的5次循环。
  2. 无效的类绑定:skeleton-body里的:class="lines"将数字/字符串直接作为类名,无实际意义,还可能干扰渲染逻辑。
  3. Props修改违规:translation组件的计算属性中直接修改this.size,违反Vue props只读规则,会触发警告并可能导致逻辑异常。
  4. Vue版本过旧:2.3.2版本存在一些已修复的渲染bug,可能影响组件正常工作。

修复方案

1. 修改父组件传入的lines类型

将HTML中的lines="5"改为:lines="5",通过v-bind传入数字类型:

<div id="app">
  <translation :phrase="language.test" type="body" :lines="5"></translation>
</div>

2. 修正skeleton-body组件代码

移除无效的类绑定,确保v-for基于数字循环,并添加唯一key(Vue 2要求v-for必须有key):

Vue.component('skeleton-body', {
  props: ['lines'],
  template: `<div>
    <div v-for="n in lines" :key="n">
      <div class="Polaris-SkeletonBodyText"></div>
    </div>
  </div>`
});

3. 修复translation组件的props修改问题

不要直接修改props的size,改用计算属性处理后的值传递:

Vue.component('translation', {
  props: ['phrase', 'type', 'lines', 'size'],
  template: `<template v-if="!phrase">
    <component :is="getSkeletonComponent" :lines="lines" :size="formattedSize"></component>
  </template>
  <template v-else>
    <span>{{ phrase }}</span>
  </template>`,
  computed: {
    formattedSize() {
      if (this.type !== 'display') return this.size;
      switch (this.size) {
        case 'small':
          return 'Small';
        case 'large':
          return 'Large';
        case 'extraLarge':
          return 'ExtraLarge';
        default:
          return 'Medium';
      }
    },
    getSkeletonComponent() {
      if (this.type === 'body') {
        return 'skeleton-body';
      } else if (this.type === 'display') {
        return 'skeleton-display';
      }
    }
  }
});

4. 升级Vue版本(可选但推荐)

将Vue版本从2.3.2升级到稳定的2.6.14,避免旧版本的潜在bug:

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js"></script>

完整修改后代码

JS部分

Vue.component('skeleton-body', {
  props: ['lines'],
  template: `<div>
    <div v-for="n in lines" :key="n">
      <div class="Polaris-SkeletonBodyText"></div>
    </div>
  </div>`
});

Vue.component('skeleton-display', {
  props: ['size'],
  template: `<div :class="['Polaris-SkeletonDisplayText__DisplayText', 'Polaris-SkeletonDisplayText--size--' + size]"></div>`
});

Vue.component('translation', {
  props: ['phrase', 'type', 'lines', 'size'],
  template: `<template v-if="!phrase">
    <component :is="getSkeletonComponent" :lines="lines" :size="formattedSize"></component>
  </template>
  <template v-else>
    <span>{{ phrase }}</span>
  </template>`,
  computed: {
    formattedSize() {
      if (this.type !== 'display') return this.size;
      switch (this.size) {
        case 'small':
          return 'Small';
        case 'large':
          return 'Large';
        case 'extraLarge':
          return 'ExtraLarge';
        default:
          return 'Medium';
      }
    },
    getSkeletonComponent() {
      if (this.type === 'body') {
        return 'skeleton-body';
      } else if (this.type === 'display') {
        return 'skeleton-display';
      }
    }
  }
});

new Vue({
  el: '#app',
  data: {
    language: {}
  },
  methods: {}
})

HTML部分

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js"></script>
  <link type="text/css" rel="stylesheet" href="https://unpkg.com/@shopify/polaris@10.30.0/build/esm/styles.css">
</head>
<body>
  <div id="app">
    <translation :phrase="language.test" type="body" :lines="5"></translation>
  </div>
</body>

内容的提问来源于stack exchange,提问作者Asa Carter

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 03:07:13