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

Posted

技术标签:

【中文标题】在 vee-validate 中使用 axios 请求时,Vue 3 无法设置值【英文标题】:Vue 3 can't set value when using axios request in vee-validate 【发布时间】:2021-11-14 05:39:05 【问题描述】:

我有一个使用自定义输入的组件。我正在使用 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"
                />

我尝试了异步创建和正常创建的方法,但没有任何改变。

我的 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>

【问题讨论】:

【参考方案1】:

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

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

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

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

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

【讨论】:

谢谢你,救了我的命

以上是关于在 vee-validate 中使用 axios 请求时,Vue 3 无法设置值的主要内容,如果未能解决你的问题,请参考以下文章

(Vue) Axios 设置数据不适用于 2 个属性。我无法解释为啥

Vue-test-utils 在 nuxt 中使用 mixin 进行 vee-validate

使用vee-validate表单插件是如何设置中文提示?

vue项目中使用vee-validate表单验证

关于 vee-validate直接引用的方法

Vee-Validate 验证组