我目前正在使用Laravel和Vue JS构建CMS,它根据Laravel模型中创建的数据数组动态构建表单。这是一个例子:
class TheBuilding extends Model
{
protected $fillable = [...];
public function formFields(){
$fields = [
[
'label' => 'Title',
'name' => 'title',
'component' => 'input_text'
],
[
'label' => 'Content',
'name' => 'content',
'component' => 'input_textarea'
],
[
'label' => 'Main Image',
'name' => 'main_image',
'component' => 'input_single_upload'
],
[
'label' => 'Gallery',
'name' => 'gallery',
'component' => 'input_multiple_upload',
'meta' => [
[
'type' => 'text',
'name' => 'caption',
'label' => 'Caption'
]
]
],
];
return $fields;
}
}
基本上,这个数组被传递到Vue JS并进行解析,以相应地动态显示Vue JS表单组件。这一直很有效但我在Gallery多重上传组件中遇到了一个有趣的问题,需要能够为图像指定字幕。
为了快进一点,我在我有一系列上传文件的地方重复浏览并显示在页面上,然后我有下面标题的输入文本字段。
这是我的组件(编辑后显示相关位):
<template>
<div class="row">
<div v-for="(file, i) in files">
<img :src="file.file" >
<div v-for="meta in file.meta">
<input v-if="meta.type == 'text'" type="text" v-model="meta.value">
</div>
</div>
</div>
</template>
<script>
export default{
computed:{
files(){
let uploads = [];
/*this.uploaded is just an array of filenames*/
this.uploaded.forEach((file, i) => {
let createdMeta = [
{
name:"caption",
type:"text",
value:''
}
];
uploads.push({file,meta:createdMeta});
});
return uploads;
}
},
props:{ ... },
mounted(){
//CODE THAT HANDLES DROPZONE UPLOAD
},
name: 'InputMultipleUpload',
data(){
return {
showUploadProgress:true,
}
}
}
</script>
我关注的是:
let createdMeta = [{
name:"caption",
type:"text",
value:''
}];
您已经注意到我已经静态创建了该数组。如果我这样做,当我输入标题文本框时,一切正常,标题值会按预期由v-model动态更新。基本上,我得到了理想的结果,一切都很好。
但是,如果我尝试从创建的模型动态设置它,即:
let createdMeta = formFields;
其中formFields是对模型数组的引用,当我输入文本框时,它会更新所创建的files数组中的所有其他文本框和值。 V-Model似乎不再与特定文本框相关。
所以我想我问的问题是:
a)当我传入引用的数组
时,为什么它会这样b)如果我只是手动创建该数组,为什么它可以正常工作?
c)我怎样才能让A表现得像B?
谢谢大家,很高兴澄清任何事情。我假设我在反应性谜题中缺少一块。
干杯, 路易斯
答案 0 :(得分:0)
有了这个:
fieldname: Shortconfig.configa
在循环中,您实际上只是将引用传递给相同的let createdMeta = formFields;
uploads.push({file,meta:createdMeta});
数组对象,然后将所有输入绑定到它。
如果为每个输入传递一个新的数组副本,这可能会正常工作。你可以这样轻松地做到:
formFields
答案 1 :(得分:0)
您应该使用data
而不是computed
。
尝试这样的事情:
<script>
export default {
props: {...},
mounted () {
//CODE THAT HANDLES DROPZONE UPLOAD
// 2. handlers should call `onUpload`
},
name: 'InputMultipleUpload',
data () {
return {
files: [], // 1. declaring `files` here makes it reactive
showUploadProgress: true,
}
},
methods: {
onUpload (file) {
const meta = createdMeta = [{
name: "caption",
type: "text",
value: ''
}]
this.files.push({file, meta}); // 3. push the new data onto the stack and the component will update
}
}
}
</script>
答案 2 :(得分:0)
let createdMeta = JSON.parse(JSON.stringify(formFields))
感谢Slack中的Rick和Dave Steward,我有重构要做但是为了这个线程的目的,这里是解决方案