Vue 组件在“手动”多次使用时不会呈现......但在循环重复时有效

Posted

技术标签:

【中文标题】Vue 组件在“手动”多次使用时不会呈现......但在循环重复时有效【英文标题】:Vue components are not rendered when used multiple times 'manually'... but works when repeated with the loop 【发布时间】:2021-08-09 15:16:20 【问题描述】:

我有如下代码。前 5 个组件正确渲染,但接下来的 3 个未正确渲染。只有这 3 个中的第一个被渲染:

const test = 
  data() 
    return 
      count: 0
    ;
  ,
  props: 
    text: 
      type: Number,
      required: true
    
  ,
  template: `
    <button @click="count++">
      [ text ] You clicked me  count  times.
    </button>
    `
;

const app = Vue.createApp();
app.component("test", test);
app.mount("#app");
<!DOCTYPE html>
<html>
  <body>
    <div id="app">
      <div v-for="i in 5">
        <test :text="i" />
      </div>

      <hr />

      <test :text="99" />
      <test :text="42" />
      <test :text="55" />
    </div>

    <script
      id="vue"
      src="https://unpkg.com/vue@3.0.11/dist/vue.global.prod.js"
    ></script>
  </body>
</html>

显然...我希望能够不仅在循环中使用组件。我错过了什么?

顺便说一句,我能够用最新的 vue 2.x 重现同样的行为(vue 应用程序初始化代码略有不同,ofc)

【问题讨论】:

【参考方案1】:

问题是由自闭合元素引起的。请参阅下面的更新演示...

为什么

在 HTML5 规范中,仅允许在“void”元素上使用自闭合标签(Void 元素是那些可能不包含任何内容的元素 - 如brimg 等) - 请参阅此 SO 问题 - @987654321 @

所以这里发生的情况是浏览器会解释您的无效 HTML(当页面加载时 - 甚至在 Vue 启动之前)(只需运行您的 sn-p,注释掉 app.mount() 并检查 HTML在开发工具中):

    <div id="app">
      <div v-for="i in 5">
        <test :text="i"></test>
      </div>

      <hr>

      <test :text="99">
        <test :text="42">
          <test :text="55">
          </test>
        </test>
      </test>
    </div>

现在很容易看出为什么v-for 可以正常工作,第一个组件渲染正常,但其余的不是(test 组件没有默认插槽)

请注意,只有在使用 DOM 内模板并且与字符串模板(template 选项)或 SFC 文件(Vue ESLint 规则和 Vue style guide 实际上推荐使用自闭合标签)时才能正常工作

const test = 
  data() 
    return 
      count: 0
    ;
  ,
  props: 
    text: 
      type: Number,
      required: true
    
  ,
  template: `
    <button @click="count++">
      [ text ] You clicked me  count  times.
    </button>
    `
;

const app = Vue.createApp();
app.component("test", test);
app.mount("#app");
<!DOCTYPE html>
<html>
  <body>
    <div id="app">
      <div v-for="i in 5">
        <test :text="i"></test>
      </div>

      <hr />

      <test :text="99" ></test>
      <test :text="42" ></test>
      <test :text="55" ></test>
    </div>

    <script
      id="vue"
      src="https://unpkg.com/vue@3.0.11/dist/vue.global.prod.js"
    ></script>
  </body>
</html>

【讨论】:

哇。谢谢。但下一个问题是:为什么!?!?为什么这在循环中起作用? 这里稍微解释一下:vuejs.org/v2/style-guide/…

以上是关于Vue 组件在“手动”多次使用时不会呈现......但在循环重复时有效的主要内容,如果未能解决你的问题,请参考以下文章

当我使用 <inertia-link> 标签时,Vue 组件不呈现

Vue 不会在我的组件的 mustache 模板 ( ) 中呈现内容

Vue不会在我的组件的胡子模板({{}})中呈现内容

Vue:props 不会自动分配;手动分配时 - 避免直接改变道具 - 错误

来自 Promise 的数据永远不会在组件中呈现

Vuejs 组件不会立即渲染