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中看到我的代码。
我有一个组件可以使用自定义输入。我正在将 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中看到我的代码。