javascript - 无法在 vee-validate 组件中重新渲染 html
问题描述
Vue.js v2.6.11 / vee-validate v3.2.2
我有一个按钮,可以在点击事件时将新元素推送到form.demand(vue 应用程序中的数据)。如果form.demand更新,v-for中的 html也应该更新。在我将它包装在 vee-validate component 之后,它就不起作用了。 form.demand会更新,但v-for不会。我尝试将相同的 html 放在测试组件中,当form.demand更新时,v-for也更新。我想不通为什么...
以下是我的代码:
HTML
<div id="content">
<test-component>
<div v-for="demand in form.demand">{{demand}}</div>
</test-component>
<validation-provider rule="" v-slot="v">
<div @click="addDemand">new</div>
<div v-for="(demand,index) in form.demand">
<div>{{demand.name}}</div>
<div>{{demand.count}}</div>
<input type="text" :name="'demand['+index+'][name]'" v-model="form.demand[index].name" hidden="hidden" />
<input type="text" :name="'demand['+index+'][count]'" v-model="form.demand[index].count" hidden="hidden" />
</div>
</validation-provider>
</div>
javascript
Vue.component('validation-provider', VeeValidate.ValidationProvider);
Vue.component('validation-observer', VeeValidate.ValidationObserver);
Vue.component('test-component',{
template: `
<div>
<slot></slot>
</div>
`
})
var app = new Vue({
el: "#content",
data: {
form: {
demand: [],
},
},
methods: {
addDemand(){
this.form.demand.push({
name : "demand name",
count: 1
})
}
})
------------尝试使用 computed & Add :key---------------- 还是不行。更改后我得到相同的结果。
HTML
<validation-provider rule="" v-slot="v">
<div @click="addDemand">new</div>
<div v-for="(demand,index) in computed_demand" :key="index">
<!--.........omitted.........-->
</validation-provider>
Javascript
var app = new Vue({
el: "#content",
// .......omitted
computed:{
computed_demand() {
return this.form.demand;
}
},
})
我想我发现了问题:从两个不同的来源导入 Vue。在 HTML 中,我从 cdn 导入 Vue。并导入 vee-validate 如下:
vee-validate.esm.js
import Vue from './vue.esm.browser.min.js';
/*omitted*/
验证器.js
import * as VeeValidate from './vee-validate.esm.js';
export { veeValidate };
main.js
// I didn't import Vue from vue in this file
import { veeValidate as VeeValidate } from './validator.js';
Vue.component('validation-provider', VeeValidate.ValidationProvider);
HTML
<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
<!-- at end of body -->
<script src="/static/javascripts/main.js" type="module"></script>
</body>
修复此问题后(从 cdn 导入 vee-validate,或通过 ES6 模块导入 Vue)。它可以工作,尽管 vee-validate 仍然存在无限循环问题。
抱歉,我没有注意到来自两个不同来源的 import vue。
解决方案
请在您的 v-for 中提供一个密钥。见下面的代码
<div v-for="(demand,index) in form.demand" :key="index">
<div>{{demand.name}}</div>
<div>{{demand.count}}</div>
<input type="text" :name="'demand['+index+'][name]'" v-model="form.demand[index].name" hidden="hidden" />
<input type="text" :name="'demand['+index+'][count]'" v-model="form.demand[index].count" hidden="hidden" />
</div>
或者,创建一个计算属性来保存您的 form.demands 数组,就像这个
computed: {
form_demands: function() {
return this.form.demand
}
}
然后在你的 v-for 中调用这个计算属性
<div v-for="(demand,index) in form_demands" :key="index">
<div>{{demand.name}}</div>
<div>{{demand.count}}</div>
<input type="text" :name="'demand['+index+'][name]'" v-model="form.demand[index].name" hidden="hidden" />
<input type="text" :name="'demand['+index+'][count]'" v-model="form.demand[index].count" hidden="hidden" />
</div>
或者,使用 vue forceUpdate 方法
import Vue from 'vue';
Vue.forceUpdate();
然后在你的组件中,添加需求后调用方法即可
this.$forceUpdate();
建议尽可能使用 v-for 提供一个键,除非迭代的 DOM 内容很简单,或者您有意依赖默认行为来提高性能。
推荐阅读
- caching - Lighthouse:使用高效的缓存策略服务静态资产
- java - zip4j可以用来解压tar文件吗?
- r - Shiny - 使用 for 循环插入 UI 会在每个输出中返回相同的元素
- azure - Azure 中 docker compose 的存储卷在哪里?
- javascript - Mongoose 虚拟填充返回 null
- javascript - 类型错误:balance.toNumber 不是函数
- android - 在升序和降序之间切换项目排序时如何为recyclerview内容更改设置动画
- json - Python3 // JSON 返回 API 上未编码的字符
- azure-devops - 通知策略绕过
- mysql - 为什么“SELECT ... WHERE id=1=0”会返回除 id=1 之外的所有行?