2017-07-17 32 views
3

使用VueJS,我尝试创建一个可以处理不同类型记录的通用组件。编辑列表中的记录,并用VueJS动态定义儿童属性

举例来说,假设我有用户记录:

var users = [ 
    { UserID: 1, username: "pan",email:"[email protected]" }, 
    { UserID: 2, username: "john",email:"[email protected]" } 
]; 

和组记录

var groups = [ 
    { GroupId: 1, groupName: "Users", description: "Lorem ipsum ..." }, 
    { GroupId: 2, groupName: "Admins", description: "Some people with super powers" } 
]; 

我想创建一个Vue的组件来编辑这些记录,因此它可以被定义为这样的:

<record-editor v-bind:record="user[0]" title="Edit user"> 
    <text-editor label="User name" property="username"></text-editor> 
    <text-editor label="Email" property="email"></text-editor> 
</record-editor> 

<!-- For the binding syntax, I am not sure what should 
    I use to bind to a record in the lists shown before --> 

<record-editor v-bind:record="groups[0]" title="Edit group"> 
    <text-editor label="groupName" property="groupName"></text-editor> 
    <text-editor label="Description" property="description"></text-editor> 
</record-editor> 

现在,我有什么是:

(function() { 
    var textEditor = Vue.component('text-editor', { 
     template: "#text-editor", 
     props: ['label', 'property'] 
    }); 

    var recordEditor= Vue.component('record-editor', { 
     template: '#model-editor', 
     props: ['title', 'record'] 
    }); 

    var vue = new Vue({ 
     el:"#someContainer", 
     data: { 
     users : users, 
     groups: groups 
     } 
    }) 
}()) 

<template id="text-editor"> 
    <div> 
     <label v-bind:for="property">{{label}}</label> 

     <!-- need help figuring what to put in v-bind:value --> 
     <input type="text" v-bind:name="property" 
          v-bind:id="property" 
          v-bind:value=""> 
    </div> 
</template> 

<template id="record-editor"> 
    <div> 
     <h2>{{title}}</h2> 
     <form> 
      <slot></slot> 
     </form> 
    </div> 
</template> 

所以基本上,我所缺少的是如何在列表中的元素,以编辑它们。

我该如何动态定义子组件(文本编辑器)的属性。

+0

你是否知道你正在编写'text-editor'作为[slot](https://vuejs.org/v2/guide/components.html#Single-Slot)而不是'record-editor'的子项'? –

+0

为了确保我理解这种差异,记录编辑器的一个孩子将被传递给记录编辑器的构造函数中的组件选项,同时将它构建为一个插槽允许它放在任何位置? – Martin

+0

如果''标签出现在'record-editor'的*模板*中,它将是一个孩子。在这里,它们出现在''标签之间,所以它们默认在外部范围内(根据Bert的回答,范围通过使用范围内的槽来改变)。 –

回答

3

你可以用scoped slotsv-model做你想做的。这是一个工作示例。

console.clear() 
 

 
var users = [ 
 
    { UserID: 1, username: "pan",email:"[email protected]" }, 
 
    { UserID: 2, username: "john",email:"[email protected]" } 
 
]; 
 

 
var groups = [ 
 
    { GroupId: 1, groupName: "Users", description: "Lorem ipsum ..." }, 
 
    { GroupId: 2, groupName: "Admins", description: "Some people with super powers" } 
 
]; 
 

 
var textEditor = Vue.component('text-editor', { 
 
    template: "#text-editor", 
 
    props: ['label', 'value'], 
 
    computed:{ 
 
    property:{ 
 
     get(){ return this.value}, 
 
     set(v){this.$emit("input", v)} 
 
    } 
 
    } 
 
}); 
 

 
var recordEditor= Vue.component('record-editor', { 
 
    template: '#record-editor', 
 
    props: ['title', 'record'] 
 
}); 
 

 
var vue = new Vue({ 
 
    el:"#app", 
 
    data: { 
 
    users : users, 
 
    groups: groups 
 
    } 
 
})
<script src="https://unpkg.com/[email protected]/dist/vue.js"></script> 
 
<div id="app"> 
 
    <record-editor v-bind:record="users[0]" title="Edit user"> 
 
    <template scope="{record}"> 
 
    <text-editor label="User name" v-model="record.username"></text-editor> 
 
    <text-editor label="Email" v-model="record.email"></text-editor> 
 
    </template> 
 
    </record-editor> 
 
    {{users}} 
 
</div> 
 

 
<template id="text-editor"> 
 
    <div> 
 
     <label>{{label}}</label> 
 
     <input type="text" v-model="property"> 
 
    </div> 
 
</template> 
 

 
<template id="record-editor"> 
 
    <div> 
 
     <h2>{{title}}</h2> 
 
     <form> 
 
      <slot :record="record"></slot> 
 
     </form> 
 
    </div> 
 
</template>

我删除了标签和ID绑定你在文本编辑器在做,主要是因为一个电子邮件地址是一个输入元素无效的ID。本质上,我更新了您的text-editor以与v-model一起工作,这将取代您的property绑定。由于您正在定义要在record-editor上编辑的模型,因此需要使用范围内的插槽。范围插槽允许您将数据从封闭范围传递到包含的组件。

+0

谢谢,明天我会在工作中试一试。 – Martin

+0

感谢您的解释,在一些摆弄和调整之后,我能够实现我正在寻找的东西。你的回答对我很有帮助。 – Martin