【问题标题】:Update child component value on axios response using v-model使用 v-model 更新 axios 响应上的子组件值
【发布时间】:2021-10-05 04:20:03
【问题描述】:

Vue 3

我正在尝试从 Axios 响应中更新数据变量的值。如果我在父组件中打印值,它会被打印并更新响应,但变量的值不会在子组件中更新。

我能弄清楚的是我的子组件没有收到更新的值。但我不知道为什么会这样。

input-field 是一个全局组件。

Vue 3

父组件

    <template>
    <input-field title="First Name" :validation="true" v-model="firstName.value" :validationMessage="firstName.validationMessage"></input-field>
</template>
<script>
export default {
        data() {
            return {
                id: 0,
                firstName: {
                    value: '',
                    validationMessage: '',
                },
            }
        },
        created() {
            this.id = this.$route.params.id;
            this.$http.get('/users/' + this.id).then(response => {
                this.firstName.value = response.data.data.firstName;
            }).catch(error => {
                console.log(error);
            });
        },
    }
</script>

子组件

<template>
    <div class="form-group">
        <label :for="identifier">{{ title }}
            <span class="text-danger" v-if="validation">*</span>
        </label>
        <input :id="identifier" :type="type" class="form-control" :class="validationMessageClass" :placeholder="title" v-model="inputValue">
        <div class="invalid-feedback" v-if="validationMessage">{{ validationMessage }}</div>
    </div>
</template>

<script>
    export default {
        props: {
            title: {
                type: String,
                required: true,
            },
            validation: {
                type: Boolean,
                required: false,
                default: false,
            },
            type: {
                type: String,
                required: false,
                default: 'text',
            },
            validationMessage: {
                type: String,
                required: false,
                default: '',
            },
            modelValue: {
                required: false,
                default: '',
            }
        },
        emits: [
            'update:modelValue'
        ],
        data() {
            return {
                inputValue: this.modelValue,
            }
        },
        computed: {
            identifier() {
                return this.title.toLowerCase().replace(/ /g, '-').replace(/[^\w-]+/g, '');
            },
            validationMessageClass() {
                if (this.validationMessage) {
                    return 'is-invalid';
                }
                return false;
            }
        },
        watch: {
            inputValue() {
                this.$emit('update:modelValue', this.inputValue);
            },
        },
    }
</script>

【问题讨论】:

  • 如果我没记错的话,你应该在子组件中使用 value 而不是 modelValue 在我知道动作是 input 后发出,但认为它依赖于 vue 版本
  • 你在哪里调用你的子组件?在您的父组件中,我只看到一个输入字段
  • @khofaai 如果他使用的是 Vue 3 (v3.vuejs.org/guide/migration/v-model.html),则不会
  • @jkoestinger 哎呀,他没有指定版本,我以为是第 2 版...谢谢指出
  • @jkoestinger 谢谢,我想确认一下,谢谢

标签: vue.js vue-component


【解决方案1】:

您的孩子永远不会从您的父母那里收到更新的原因是,即使您更改了firstName.value,您的子组件也不会重新安装并实现该更改。 它绑定到它内部创建的属性 (inputValue) 并一直关注它,而不是从父级传递的 modelValue。 这是一个使用您的代码的example,它完全按照您的预期以及您期望的方式工作。 它接收一次值 (firstName.value),创建另一个属性 (inputValue) 并在发生更改时发出该值。 不管父级修改firstName.value属性多少次,子级都不在乎,子级的输入v-model看的不是这个属性。

你可以这样做

<template>
  <div class="form-group">
    <label :for="identifier"
      >{{ title }}
      <span class="text-danger" v-if="validation">*</span>
    </label>
    <input
      :id="identifier"
      :type="type"
      class="form-control"
      :class="validationMessageClass"
      :placeholder="title"
      v-model="localValue" // here we bind localValue as v-model to the input
    />
    <div class="invalid-feedback" v-if="validationMessage">
      {{ validationMessage }}
    </div>
  </div>
</template>

<script>
export default {
  ... // your code
  computed: {
    localValue: {
      get() {
        return this.modelValue;
      },
      set(value) {
        this.$emit("update:modelValue", value);
      },
    },
  },
};
</script>

我们删除了观察者,而是使用了一个计算属性,它将在它的 getter 中返回 modelValue(所以每当父级传递一个新值时,我们实际上使用 that 而不是 localValue)和一个 setter向父级发出更新事件。

这是另一个 codesandbox 示例,说明了上述解决方案。

【讨论】:

  • 感谢您的帮助。
猜你喜欢
  • 2020-06-09
  • 2019-02-14
  • 2018-04-28
  • 2021-02-21
  • 1970-01-01
  • 2021-07-23
  • 2018-12-03
  • 1970-01-01
  • 2021-11-09
相关资源
最近更新 更多