Vue2:数据已更新但html未更新?

时间:2018-06-22 15:13:15

标签: javascript vue.js vuejs2 vue-component

我是Vue的新手,并在S.O上的文档和Vue社区的帮助下。我在学习如何制作更复杂的组件方面一直取得进展。

此问题与自定义选择组件有关,其中所选选项的数据正确,但显示的HTML却不正确。我提供的是M.W.E.但是,只有当自定义选择组件嵌套在其他几个组件中时,这种情况才会发生。

我知道这是很多代码,所以M.W.E.是通过Code Sandbox提供的,其中每个组件都在其自己的文件中(使其更易于阅读)。

组件说明

enter image description here

该组件是一个高级数据过滤器,它接受模拟数据库的对象,例如每个键是其对应值(“记录”)的“ id”。然后,它允许筛选记录的键(属性/字段)。

因此,我们拥有最顶层的组件AdvancedFilterTable。该表允许用户动态添加和删除过滤器AdvancedFilterRows

一个过滤器行包含5个简单的组件:

  • 逻辑:是过滤器和/或(AdvancedFilterSelectLogic
  • 功能:应用于字段(AdvancedFilterSelectFunction)的内容
  • 属性:要在哪个字段上进行过滤(AdvancedFilterSelectProperty
  • 有条件的:对设置字段(AdvancedFilterSelectConditional之前的每个记录应用什么测试
  • value:要在条件(AdvancedFilterInput)中测试的值

例如

{logic: 'and', function: 'identity', property: 'x', conditional: 'gt', value: 5}

我添加的引入该错误的功能是AdvancedFilterSelectFunctionAdvancedFilterSelectConditional的动态选项,基于AdvancedFilterSelectProperty的类型。

例如如果所选属性是x,其中对应的值是数字数组,则AdvancedFilterSelectFunction中的选项应包含“均值”,“最大值”等,而AdvancedFilterSelectConditional应包含“包括”,“不包括”等。但是,如果选择了“均值”(将函数应用于属性将更改其类型),则条件条件应再次更改(这一次将“包括”和“不包括”删除)。

在提供的MWE中,我具有以下虚拟数据:

let records = {
  a: { x: 1, y: "a string", z: [1, 2, 3, 4] },
  b: { x: 2, y: "strange?", z: [1, 2, 4] },
  c: { x: 3, y: "starts w", z: [1, 2, 3, 4] },
  d: { x: 10, y: "some let", z: [1, 2, 4, 5, 6, 7, 8] },
  e: { x: 2, y: "? qwerty", z: [1, 40] }
};

其中x的类型是数字,y是字符串,z是数组编号。

如何产生错误

  1. 打开mwe Code Sandbox enter image description here

  2. 单击绿色加号图标以添加新的过滤器

enter image description here

  1. 单击属性选择,然后将x更改为z

enter image description here

检查组件,所有相应数据均已正确设置。 由于函数选择和条件选择具有动态更改,以包括特定于数组类型数据的选项,因此这一点得到了进一步强调。

尽管如此,选择仍然显示'x'。然后尝试选择“ x”来重置选择不起作用,因为它仍然被选择为x ...

自定义选择项均通过Vue2: handling multi-child prop synchronization with models中概述的不同封装组件传递数据 与答案的小提琴: https://jsfiddle.net/SumNeuron/ejq86c73/9/

解决方案:https://61qky5y6mr.codesandbox.io/

2 个答案:

答案 0 :(得分:2)

AdvancedFilterSelectProperty.vue中,您有一个道具selected。这随着用户更改选择而改变。但是,<select />元素本身的selected属性正在检查表达式key == value

value来自组件的data。当用户更改选择时,data不会更新,但是selected道具当然会更新。

因此,不要检查value中的data,而是检查selected属性。

<select @change='updateSelected($event)'>
    <option
        v-for='(val, key) in options'
        :value='key'
        :key="key"
        :selected='key == selected'
    >
        {{val.text}}
    </option>
</select>

这可以解决您的问题。

https://codesandbox.io/s/38vlwq4yx6上查看工作示例

答案 1 :(得分:1)

您的选择输入实际上没有任何与之关联的模型,因此该值从不显示,尽管会广播。但是,由于您使用道具从父级委托值变戏法,因此实际上需要一个计算属性来处理此问题,如下所示:

computed: {
  selectedVal: {
    get() {
      return this.selected
    },
    set(value) {
      this.$emit('updateSelected', value)
    }
  }
}

然后将其应用于您的选择(至少AdvancedFilterSelectProperty组件):

<select v-model="selectedVal">

这里不需要@input函数,因为当值更改时选择setter时,我们的$emitting是父级的<option>