无法在 vee-validate 组件中重新渲染 html

Can't re-render html in vee-validate component

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
            })
        }
})

-------------尝试使用计算和添加:键---------------- 还是不行。此更改后我得到相同的结果。

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*/

validator.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 的无限循环问题。

抱歉,我没有注意到从两个不同的来源导入 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();

It is recommended to provide a key with v-for whenever possible, unless the iterated DOM content is simple, or you are intentionally relying on the default behavior for performance gains.