Vue2:数据更新但html没有?

Posted

技术标签:

【中文标题】Vue2:数据更新但html没有?【英文标题】:Vue2: data updated but html not? 【发布时间】:2018-12-02 02:39:35 【问题描述】:

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

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

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

组件说明

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

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

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

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

例如

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

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

例如如果选择的属性是x,其对应的值是一个数字数组,那么AdvancedFilterSelectFunction中的选项应该包括“mean”、“max”等,AdvancedFilterSelectConditional应该包括“includes”、“not包括”等。但是,如果选择了“均值”(将函数应用于属性会更改其类型),则条件应再次更改(这次删除“包括”和“不包括”)。

在提供的 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 是数组数字。

如何产生错误

    打开mwe Code Sandbox

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

    单击属性选择并将x更改为z

检查组件,所有对应数据设置正确。 随着函数选择和条件选择动态变化以包含特定于数组类型数据的选项,这一点得到了进一步强调。

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

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

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

【问题讨论】:

【参考方案1】:

您的选择输入实际上并没有与它们关联的任何模型,因此该值永远不会显示,但它是广播的。但是,由于您使用 props 来委派来自父级的值,因此您实际上需要一个计算属性来处理此问题,如下所示:

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

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

<select v-model="selectedVal">

这里不需要@input函数,因为当我们选择&lt;option&gt;时,我们的setter对于我们的父级是$emitting,因为值正在变化

【讨论】:

如果不是太多工作,我可以要求您将示例分叉并放入吗?我对它的确切位置和使用方式有点困惑。在 Vue 文档中,他们建议通过 model: prop: &lt;prop&gt;, event:&lt;event&gt; 指定自定义模型,但我不确定为什么要获得对嵌套组件值的***访问权限必须做这么多工作。我认为使用 .sync 修饰符是可行的,但我无法让它工作,他们的事件名称为 'update:title' 的示例对我不起作用:/ 有更好的方法吗? (数据同步和组件组织)。我是 Vue 的新手,我认为这是正确的组件委托,但也许我弄错了?【参考方案2】:

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

value 来自组件的datadata 不会在用户更改选择时更新,但 selected 属性肯定会更新。

因此,不要检查 data 中的 value,而是检查 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,但也许更好的解决方案是更新 updateSelect 函数以包含 this.value = event.target.value; 不确定,为什么有两个属性表示同一件事。值并被选中。只保留一个事实来源,更容易推理。 另外,请检查vuejs.org/v2/guide/components.html#Using-v-model-on-Components。我没有完成你的整个设置。所以不确定这是否适用于你。但是每当我制作像 AdvancedFilterSelectProperty.vue 这样的组件时,我也会在这些组件上使用 v-model。 我希望只有一个,但在我的上一个问题 ***.com/questions/50853417/… 我了解到 Vue 不喜欢组件突变的 prop 对于组件上的 v-model,我确实阅读了它,因此按照文档中的建议自定义了 @input 函数 updateSelect

以上是关于Vue2:数据更新但html没有?的主要内容,如果未能解决你的问题,请参考以下文章

vuex中更新对象或数组的值页面不更新的问题

vue 2.0 和 vue-router 2.0 构建 SPA,router-view 没有更新

javascript vue2异步更新原理

vue2源码简单实现stage3

vue2.0项目实战--使用axios发送请求

vue2.x路由更新问题相关处理方式