首页 > 解决方案 > Vue JS - 如何使用基于可变数据的模型创建动态输入字段

问题描述

我有一个 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但是当我更改字段值时它似乎并没有真正做出反应。

标签: javascriptvue.jsvue-componenttemplatingv-model

解决方案


innerHTML对 Vue 模板、绑定和反应性一无所知 - 如果您设置domNode.innerHTML = '<input v-model="variable">';浏览器将简单地忽略该属性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"]),
    }
};

推荐阅读