【问题标题】:how to send component data as json to server?如何将组件数据作为 json 发送到服务器?
【发布时间】:2017-07-07 20:34:50
【问题描述】:

这是我的设置:

<template>
    <div id="" style="min-height: 100px">
        <template v-for="(block, index) in blockList">
            <component :is="block"></component>
        </template>
    </div>
</template>

<script>
    import TextBlock from './blocks/TextBlock.vue'
    import ImageBlock from './blocks/ImageBlock.vue'

    export default {
        data: function data() {
            return {
                blockList: ['text-block', 'image-block', 'text-block']
            }
        },

        props: {
            blocks: {type: Array}
        },
        // afterMount () {
        //     this.blocks.push(['text-block']);
        // },
        components: {
            TextBlock,
            ImageBlock
        }
    }
</script>

<style lang="scss">

</style>

所以为了测试一切正常,我手动添加了一些组件:blockList: ['text-block', 'image-block', 'text-block']

页面上的一切都很好。但是,我不会手动添加组件,但我会让用户添加它们,并且用户将能够添加任意数量的组件。将有更多的组件,然后是我目前使用的 2 个。

当我向页面添加了 10 个不同的组件并且用户按下保存按钮时,我将如何将此数据发送到服务器?我不能只将 blockList 数组发送到服务器,因为它只是一个字符串数组。

我想要做的是跟踪所有已添加的组件,然后按下按钮将包含所有组件及其属性的 json 发送到服务器,就像我在文本组件中输入了任何文本一样,或者如果我已将图像上传到图像组件中,我还需要将所有数据发送到服务器,以便稍后重新加载页面以再次编辑时重新创建它。

那么我怎样才能做到这一点,因为 blockList: ['text-block', 'image-block', 'text-block'] 不会做?如何保留一组组件及其所有属性并通过按钮将其发送到服务器?

【问题讨论】:

    标签: vue.js vuejs2 vue-component


    【解决方案1】:

    构建您的组件以支持v-model。将您的 blockList 数据结构更改为如下所示:

    const blockList = [
      {
        component: "text-block",
        model: null,
        label: "Name"
      },
      {
        component: "text-block",
        model: null,
        label: "Address"
      }
    ]
    

    请注意,blockList 中的每个项目现在都有一个model,您可以使用它来从组件中收集数据。然后,使用v-model 将您的组件绑定到块模型。

    <component v-for="item in blockList" 
               :is="item.component"
               v-model="item.model"
               :label="item.label"
               :key="item">
    </component>
    

    这是一个示例组件实现:

    const TextBlock = {
      props:["value", "label"],
      template: `
        <div>
          {{label}}
          <input type="text" @input="$emit('input', $event.target.value)" :value="value">
        </div>
      `
    }
    

    现在,blockList 中的每个元素都将包含从该组件收集的数据。当您要保存该数据时,遍历blockList 并提取您要提交的数据。

    这是working example

    在这个例子中,我没有做提交数据的工作,你可以自己解决这个问题。我也没有实现 ImageBlock 组件;无论如何,我不确定您希望它如何工作。但是按照同样的模式,你应该可以在 ImageBlock 组件上支持v-model 并以同样的方式提交数据。

    【讨论】:

    • 哇,谢谢,这是一个很好的答案。您能否澄清运行 v-model="item.model" 时会发生什么?由于初始化时model = null,它什么时候变成其他东西然后为null?这还有什么作用:@input="$emit('input', $event.target.value)"?
    • @maxit v-model 是一个指令“表单输入元素或组件上的双向绑定”。请参阅documentation here。代码@input=... 将事件处理程序附加到input 元素的input 事件并发出输入元素的当前值。由于v-model 默认侦听input 事件,item.model 将使用输入元素的新值进行更新。
    • 好的,我现在明白了,模型将获得我输入到文本框中的值,这就是为什么:返回 this.blockList.map(b => b.model) 并结合此收集的数据: {{values}} 将我输入的值返回给我。但问题来了,我不仅要向服务器发送我输入的值,还要向服务器发送我的组件类型以及我可能在该组件中定义的任何其他设置,例如我可以让用户自定义该组件的一些设置,宽度,高度等。那么我将如何遍历一个blockList并提取每个组件及其数据?
    • 我想发送一个 json 到服务器,看起来像这样 "blocks": { 'textblock': {value="what ever was entered into textarea", setting1: "10px", setting2: “真”我该怎么做?
    • @maxit 你将如何区分文本块?
    猜你喜欢
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多