VueJS:在 v-if 中直接改变 prop 与 this.[prop]

Posted

技术标签:

【中文标题】VueJS:在 v-if 中直接改变 prop 与 this.[prop]【英文标题】:VueJS: Altering prop directly vs. this.[prop] in v-if 【发布时间】:2020-08-27 15:29:27 【问题描述】:

我构建了一个 vue 组件,它通过来自外部 laravel 刀片的 prop 获取一个数值,如下所示:

<my-custom-template :mynumber="$numbervalue" :list:$alist></my-custom-template>

在模板中我有一个 v-for 列表和道具:

props:
     list:Array,
     mynumber: Number,
    [..]

<template>
    <ul>
        <li v-for="item in list">item<span v-if="item.id == mynumber">active</span></li>
    </ul>
</template>

只要项目的 ID 与值 mynumber 相同,我希望显示“活动”标签/跨度。

现在在这个模板中,我还有一个发送 axios 请求的方法,成功后它会改变 prop "mynumber" 的值,因此应该重新呈现列表:

axios.post('/api/someurl', this.obj)
            .then(res => 
                this.mynumber= res.data[something]; // returns a new number from the db.
                        )
                .catch(error =>  [..]
                ;

问题:如果我在列表的 v-if 条件中使用 this.mynumber,则永远不会显示“活动”标签。如果我直接使用 == mynumber 那么它可以工作,但我不能用 axios 响应来改变它。 我应该如何正确处理这个问题? 如何使用 axios 调用中的新值更改初始道具?

【问题讨论】:

【参考方案1】:

不要直接改变 props。改用this.$emit(文档:https://vuejs.org/v2/guide/components-custom-events.html)来更改父级中的 myNumber。 myNumber 然后会在子组件中自动更新。

【讨论】:

我明白了,该方法向父级发出“更新”和 $updatedvalue 并且父级更改了道具值@update。那么在 laravel 刀片中会不会是这样: 我的自定义模板>? 老实说,我以前从未使用过 laravel,但这是一般的想法,是的。您不想在孩子中复制状态。不过是@update="$numbervalue = $event"。传递到顶部的道具总是 $event (在 Vue 中,不知道 laravel Blade 如何更改 $ 语法,抱歉!)。一旦你的父母改变了变量,孩子就会反映这些变化 不用担心,它还是很有帮助的 :) 我认为我走在正确的轨道上。【参考方案2】:

首先,你不应该直接修改 props,as mentioned in this prior Stack Overflow post。

[Vue 警告]:避免直接改变 prop,因为每当父组件重新渲染时,该值都会被覆盖。相反,使用基于道具值的数据或计算属性。正在变异的道具:“propRoomSelected”

第二,as seen in the Vue documentation for conditionals,你不要在模板中使用thisthis是推断出来的。

现在,要深入了解您的问题,在渲染时如何查看 道具或新值。这是我的做法。

<template>
  <ul>
      <li v-for="item in list">item<span v-if="isCurrent(item.id)">active</span></li>
  </ul>
</template>

<script>
export default 
  props: ['list', 'myNumber'],
  data() 
    return 
      myNewNumber: undefined
    
  ,

  methods: 
    isCurrent(itemId) 
      return itemId == (myNewNumber || myNumber)
    
  


</script>

编辑:

注意有区别

return itemId == (myNewNumber || myNumber)

return (itemId == myNewNumber) || (itemId == myNumber)

第一个“短路”与myNumber 的比较一旦myNewNumber 变得“真实”。 Read more here.

【讨论】:

有趣的解决方案。如果我检查 itemId == (myNewNumber || myNumber) 那么我不会在列表中有 2 个“活动”标签,一个具有初始值的标签和一个新标签?我只想将最近的一个设为“活动”。 不!如果myNewNumber 未定义,(myNewNumber || myNumber) 位将仅返回原始数字。阅读我上面的编辑 啊,好吧,对我来说听起来不错:) 但是现在我在控制台中得到“_vm.isCurrent 不是函数”。我在“计算:”中尝试了“isCurrent:function(itemId)”以及“isCurrent(itemId)”,但没有运气。在模板中,检查是:“ v-if="isCurrent(item.id)"" 啊!对不起,它应该是一种方法,而不是计算。上面固定。 是的!就是这样,谢谢@Lanny Bose,效果很好。

以上是关于VueJS:在 v-if 中直接改变 prop 与 this.[prop]的主要内容,如果未能解决你的问题,请参考以下文章

当从 vuejs 组件中的 props 解码回来时,Vuejs 改变了 json_encoded 数组的顺序

Vuejs1.0学习

element的prop校验与v-show/v-if结合不显示检验

在Vuejs中使用Transition在v-if上设置高度动画

Vue JS - 在插槽中改变传递的道具

vuejs中类似于v-if的自定义指令