当 ref 的值发生变化时,Vue 不会更新模板 Vue 3
Posted
技术标签:
【中文标题】当 ref 的值发生变化时,Vue 不会更新模板 Vue 3【英文标题】:Vue doesn't update the template when the value of ref changes Vue 3 【发布时间】:2021-11-21 19:03:51 【问题描述】:上下文:我希望在注册操作运行后显示进度条。但是返回 isLoading 中的计算函数并没有反映 DOM 中的变化
问题:我正在尝试在发出返回请求时模拟加载。而且我的变量(isLoading)在模板或 DOM 中没有改变。
<template>
<div class="p-fluid p-card custom-login-box">
<div class="p-card-header p-py-2">
<div class="p-card-title p-text-center">t('login_signUp')</div>
<div class="p-card-subtitle p-text-center">t('sign_up_subtitle')</div>
</div>
isLoading
<div v-show="isLoading">
<ProgressBar mode="indeterminate" style="height: .2em" />
</div>
<div class="p-card-body">
<form>
<div class="p-field p-mb-3">
<div class="p-col-12">
<span class="p-float-label p-input-icon-left">
<i class="pi pi-id-card"></i>
<InputText
id="fullName"
v-model="fullName"
type="text"
name="fullName"
autocomplete="fullName"
:class=" 'p-invalid': errors.fullName "
/>
<label for="fullName">t('sign_up_full_name')</label>
</span>
<div class="p-error p-ml-5"> errors.fullName </div>
</div>
</div>
....
</template>
<script lang="ts">
import defineComponent, computed, ref from 'vue'
import useI18n from 'vue-i18n'
import * as yup from 'yup'
import useField, useForm from 'vee-validate'
import msg from '@/plugins/toast'
export default defineComponent(
setup ()
const t = useI18n()
const state = ref(false)
const validationSchema = computed(() =>
return yup.object(
fullName: yup.string().required(t('required')),
email: yup.string().required(t('required')).email(t('emai_invalid')),
password: yup.string().required(t('required')).matches(/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.8,)/, t('must_comply_suggestion')),
confirmPassword: yup.string().oneOf([yup.ref('password'), null], t('matches_password')).required()
)
)
const errors, meta = useForm( validationSchema )
const value: fullName = useField<string>('fullName')
const value: email = useField<string>('email')
const value: password, meta: metaPassword = useField<string>('password')
const value: confirmPassword = useField<string>('confirmPassword')
const register = async () =>
console.log('valor inicial en loading', state.value)
console.log('entro a la funcion')
state.value = true
console.log('el valor que le asigno a loading', state.value)
await setTimeout(() =>
const res:number = Math.round((Math.random() * (2 - 1) + 1))
if (res === 1)
msg.showSuccess()
else
msg.showError(t('exist_email'))
, 2000)
state.value = false
console.log('despues que termina la funcion', state.value)
return t, fullName, email, password, confirmPassword, errors, meta, metaPassword, register, isLoading: computed(() => state.value)
</script>
【问题讨论】:
您是否使用 Vue 开发工具确认isLoading
不会更改状态? v-show 是出了名的敏感,通常它没有在 DOM 中更新的原因不是状态没有改变(根据我的经验)。不过,这里无法确定可能出了什么问题。
你为什么还要在那里使用计算,而不是直接调用 ref isLoading 并直接使用它?
【参考方案1】:
问题是await 是基于 Promise 的(只能与 Promise 一起使用)并且 setTimeout 不返回 Promise
因此,当register
方法执行时,它首先将state.value
设置为true
,然后安排超时并立即 将state.value
设置为false
。要使其工作,请将state.value = false
移动到setTimeout
回调中。
由于您仅使用 setTimeout
来模拟异步调用,因此当您将 setTimeout
替换为基于 Promise 的真实异步调用(例如 fetch
)时,代码将按预期工作...
【讨论】:
以上是关于当 ref 的值发生变化时,Vue 不会更新模板 Vue 3的主要内容,如果未能解决你的问题,请参考以下文章