Vue组件仅呈现模板DOM

时间:2017-12-16 17:20:22

标签: javascript vue.js

我的网站上的Vue循环中有一个Vue组件。这是JS文件:

Vue.component('fb-question-text', {
  props: ['question'],
  template:
    '<label>Prompt</label><input type="text" class="form-control" v-model="question.prompt"><a href="javascript:void" class="fb-remove">Remove</a>'
});

var questionList = new Vue({
  el: '#questions',
  data: {
    questions: [
      {
        type: 'text',
        id: 'question1',
        prompt: ''
      },
      {
        type: 'choice',
        id: 'question2',
        prompt: '',
        choices: ['', '']
      }
    ]
  }
});

这就是我的HTML文件:

<ul id="questions">
    <li v-for="(question, index) in questions">
        <h4>Question {{ index + 1 }}</h4>
        <fb-question-text v-if="question.type === 'text'" :question="question"></fb-question-text>
    </li>
</ul>

正如您所看到的,如果question.type是“text”类型,我正在尝试呈现fb-question-text组件。虽然<li>元素在页面中呈现,但组件模板不会完全呈现。仅渲染模板内的第一个DOM元素(在本例中为<label>元素)。由于某种原因,组件内部的输入框和<a>不会被渲染。当我删除标签时,输入框会被渲染但后面没有任何内容。

有人可以告诉我发生了什么事吗?

4 个答案:

答案 0 :(得分:2)

模板必须只有一个根元素。

<span>
  <label>Prompt</label>
  <input type="text" class="form-control" v-model="question.prompt">
  <a href="javascript:void" class="fb-remove">Remove</a>
</span>

答案 1 :(得分:0)

您的fb-question-text只允许有一个根元素。你需要将它包装在一个div中。

答案 2 :(得分:0)

<div> html

周围添加template

Vue.component('fb-question-text', {
    props: ['question'],
    template: '<div><label>Prompt</label><input type="text" class="form-control" v-model="question.prompt"><a href="javascript:void" class="fb-remove">Remove</a></div>'
});

var questionList = new Vue({
    el: '#questions',
    data: {
        questions: [
            {
                type: 'text',
                id: 'question1',
                prompt: ''
            },
            {
                type: 'choice',
                id: 'question2',
                prompt: '',
                choices: [ '' , '' ]
            }
        ]
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.11/vue.js"></script>
<ul id="questions">
    <li v-for="(question, index) in questions">
        <h4>Question {{ index + 1 }}</h4>
        <fb-question-text v-if="question.type === 'text'" :question="question"></fb-question-text>
    </li>
</ul>

答案 3 :(得分:0)

对于类似的问题,我打算提出另一个答案: Vue js error: Component template should contain exactly one root element

在此处复制粘贴:

如果出于任何原因,您不想添加包装器(在我的第一种情况下,该包装器用于<tr/>组件),则可以使用功能组件。

components/MyCompo.vue文件夹中只有几个文件,而不是一个components/MyCompo

  • components/MyCompo/index.js
  • components/MyCompo/File.vue
  • components/MyCompo/Avatar.vue

采用这种结构,您调用组件的方式不会改变。

components/MyCompo/index.js文件内容:

import File from './File';
import Avatar from './Avatar';   

const commonSort=(a,b)=>b-a;

export default {
  functional: true,
  name: 'MyCompo',
  props: [ 'someProp', 'plopProp' ],
  render(createElement, context) {
    return [
        createElement( File, { props: Object.assign({light: true, sort: commonSort},context.props) } ),
        createElement( Avatar, { props: Object.assign({light: false, sort: commonSort},context.props) } )
    ]; 
  }
};

如果两个模板中都使用了某些功能或数据,则将它们作为属性传递就可以了!

我让您想象使用此模式构建组件列表以及如此多的功能。