【问题标题】:Vue JS - How to create dynamic input fields with models based on variable dataVue JS - 如何使用基于可变数据的模型创建动态输入字段
【发布时间】:2020-08-20 09:26:51
【问题描述】:

我有一个 Vue 组件,它根据 API 获取的数据创建许多输入。我通过一种方法运行 JSON 中的值,如果某个条件匹配,该方法又将此值转换为输入字段。这是我的组件的外观:

<template>
    <div>
        <div v-for="(val, index) in data">
            <span>{{val.key}}</span>
            <span :inner-html.prop="checkForEdit(val)"></span>
        </div>
        <b-button @click="submitData">Save</b-button>
    <div>
</template>

export default {
    name: "SomeComp",
    data() {
        return {
            dynamicVars: {}
        }
    },
    methods: {
        ...mapActions("api", ["getData"]),
        checkForEdit(value) {
            if(!value) return '';
            if(value.mustEdit) {
                this.dynamicVars[value.key] = '';
                return '<input type="text" value= "'+ value.text +'" :model='+ this.dynamicVars[value.key]+'>';
            } else {
                return value.text;
            }
        },
        submitData() {
            console.log(this.dynamicVars); //Only the key is present, no value updated
        }
    },
    created() {
        this.getData();
    },
    computed: {
        ...mapState("api", ["data"]),
    }
};

数据如下所示:

[
    {key: 'name', text: 'John', mustEdit: false},
    {key: 'age', text: '100', mustEdit: true}
]

这个数据可以是任何东西,字段不是固定的,只有格式是固定的。所以我想动态创建动态 vars 对象以发送到保存它的 API。

现在它只在dynamicVars 内创建变量,但是当我更改字段值时它似乎并没有真正做出反应。

【问题讨论】:

    标签: javascript vue.js vue-component templating v-model


    【解决方案1】:

    innerHTML 对 Vue 模板、绑定和响应性一无所知 - 如果您设置 domNode.innerHTML = '&lt;input v-model="variable"&gt;';,浏览器将简单地忽略属性 v-model,因为它不是标准的 HTML5 属性。

    您需要转换您的思维模型,而不是用命令式的方式思考,而是尝试以声明式的方式思考 - 只需在模板中写下您想要做的事情,Vue 就会为您施展魔法。有 Vue 为我们做事,而不是用旧的 jQuery 风格编写代码,真是太幸运了。

    <template>
        <div>
            <div v-for="(val, index) in data" :key="index">
                <label :for="'input_' + index">{{val.key}}</label>
                <input v-if="val.mustEdit" :id="'input_' + index" :model='val.text'>
                <span v-else>{{ val.text }}</span>
            </div>
            <b-button @click="submitData">Save</b-button>
        <div>
    </template>
    
    export default {
        name: "SomeComp",
        methods: {
            ...mapActions("api", ["getData"]),
            submitData() {
                console.log(this.data);
            }
        },
        created() {
            this.getData();
        },
        computed: {
            ...mapState("api", ["data"]),
        }
    };
    

    【讨论】:

    • 啊哈,我从来没有这样想过。让我试试这个!顺便说一句,我最终使用Vue.set 无济于事。
    • 但是,我必须创建一个带有已编辑字段、API 约束的单独对象。那我该怎么办?我正在尝试您的解决方案。
    • 您可以克隆您的原始对象,当您准备好保存更改时 - 您将逐个键迭代克隆的对象并将其 text 值与原始对象中的相应值进行比较,因此您会发现哪些字段已被实际编辑,然后仅将这些字段发送到 API。或者您可以处理 INPUT 的 @input 事件并将值标记为脏 - @input="val.modified = true" 然后您将发送到 API data.filter(obj =&gt; obj.modified) 元素
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 2012-05-25
    • 1970-01-01
    • 2019-04-15
    • 1970-01-01
    • 2021-12-15
    • 2021-05-09
    相关资源
    最近更新 更多