Vue JS - Как создать динамические c поля ввода с моделями на основе переменных данных - PullRequest
0 голосов
/ 05 мая 2020

У меня есть компонент 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}
]

Эти данные могут быть любыми, поля не фиксированы, только формат. Итак, я хочу создать объект динамических c vars на лету для отправки в API, который его сохраняет.

Прямо сейчас он создает только переменную внутри dynamicVars, однако не похоже, что он на самом деле реагирует когда я меняю значение поля.

1 Ответ

1 голос
/ 05 мая 2020

innerHTML не имеет представления о шаблонах Vue, привязках и реактивности - если вы установите domNode.innerHTML = '<input v-model="variable">';, браузер просто проигнорирует атрибут v-model, поскольку это не стандартный атрибут HTML5.

Вам нужно изменить свою ментальную модель и вместо того, чтобы думать в императивных терминах, попробуйте мыслить декларативно - просто напишите в своем шаблоне, что вы хотите сделать, и Vue сделает все за вас c. Это такое благословение, что у нас есть 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"]),
    }
};
...