Vue 3 在 vee-validate 中使用 axios 请求时无法设置值

Vue 3 can't set value when using axios request in vee-validate

我有一个组件可以使用自定义输入。我正在将 veevalidate 与它一起使用,它运行良好。

但是今天我意识到在使用 axios 请求时我无法设置值。

仅设置字符串或预定义数据(如 this.a = '1' :value="this.a"

时有效
                  <CustomInput
                type="text"
                name="surname"
                placeholder="surname"
                :value="'testparam'" // or :value="this.a"
                inputClass="form-control form-control-solid h-auto mb-1 mt-2"
                />

但是当尝试将值(来自后端)设置为组件时,没有任何显示。

像这样

data () {
    return {
      userInfo: {
        name: '',
        surname: '',
        phone: ''
      }
    }
  },

    async created () {
        await this.axios.get(this.$store.state.baseUrl + 'user/personalInfo').then((response) => {
          this.userInfo = response.data
          console.log(this.userInfo)
        })
      }

并设置

<CustomInput
                type="text"
                name="surname"
                placeholder="surname"
                :value="this.userInfo.name" // doing nothing
                inputClass="form-control form-control-solid h-auto mb-1 mt-2"
                />

我尝试使用 methots 创建异步创建和正常创建,但没有任何改变。

我的CustomInput.vue

    <template>
  <input
    :name="name"
    :id="name"
    :type="type"
    :value="inputValue"
    :inputmode="type"
    :placeholder="$t(placeholder)"
    :class="[inputClass, { 'has-error': !!errorMessage, success: meta.valid }, notRequired ? 'notreq' : '']"
    @input="handleChange"
    @blur="handleBlur"
    maxlength="255"
  />
  <p class="help-message" v-show="errorMessage">
    {{ errorMessage }}
  </p>
</template>

<script>
import { useField } from 'vee-validate'

export default {
  props: {
    type: {
      type: String,
      default: 'text'
    },
    value: {
      type: String,
      default: ''
    },
    name: {
      type: String,
      required: true
    },
    placeholder: {
      type: String,
      default: ''
    },
    inputClass: {
      type: String,
      default: ''
    },
    notRequired: {
      type: Boolean,
      default: false
    }
  },
  setup (props) {
    const {
      value: inputValue,
      errorMessage,
      meta,
      handleBlur,
      handleChange
    } = useField(props.name, undefined, {
      initialValue: props.value
    })
    return {
      errorMessage,
      inputValue,
      meta,
      handleBlur,
      handleChange
    }
  }
}
</script>

<style scoped>

input {
  background-color: #f3f6f9;
  color: #3f4254;
  padding: 12px;
  border-radius: 0.42rem;
  width: 100%;
  border: none;
}

input::placeholder {
  color: #c9c9d4;
  font-weight: 400;
}

input:focus-visible {
  outline: none;
}

input:focus {
  background-color: #ebedf3;
  color: #3f4254;
}

.help-message {
  margin: 0;
  color: #fd6a57;
  font-size: 0.9rem;
  font-weight: 400;
  width: 100%;
  text-align: center;
}

.has-error {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23F64E60' viewBox='0 0 12 12'%3e%3ccircle cx='6' cy='6' r='4.5'/%3e%3cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3e%3ccircle cx='6' cy='8.2' r='.6' fill='%23F64E60' stroke='none'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.325rem) center;
  background-size: calc(0.75em + 0.65rem) calc(0.75em + 0.65rem);
}

.success {
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8' viewBox='0 0 8 8'%3e%3cpath fill='%231BC5BD' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3e%3c/svg%3e");
  background-repeat: no-repeat;
  background-position: right calc(0.375em + 0.325rem) center;
  background-size: calc(0.75em + 0.65rem) calc(0.75em + 0.65rem);
}

.notreq {
  background-image: none !important;
}

.newsletter {
  border-top-right-radius: 0;
  border-bottom-right-radius: 0;
}
</style>

我认为这个问题是因为你的 axios 请求。在 axios 请求完成之前,CustomInput 组件使用默认道具渲染,useForm 组合 API 用空值初始化。

我的解决方案: 您可以在 CustomInput 组件设置方法中 watch 值道具。然后每次它的值改变时,更新值:

watch(
    () => props.value,
    (newValue, oldValue) => {
       console.log("value props changed: ", newValue);
       inputValue.value = newValue;
    }
);

此外,您在 CustomInput 道具中遇到了问题。尝试在模板部分发送 userInfo.name 而不是 this.userInfo.name

你可以在this codesandbox project中看到我的代码。