Vue Js v-model不能使用在Laravel模型中创建的数组

时间:2017-08-10 09:50:05

标签: javascript php laravel vue.js vuejs2

我目前正在使用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?

谢谢大家,很高兴澄清任何事情。我假设我在反应性谜题中缺少一块。

干杯, 路易斯

3 个答案:

答案 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,我有重构要做但是为了这个线程的目的,这里是解决方案