【问题标题】:VueJS: Altering prop directly vs. this.[prop] in v-ifVueJS:在 v-if 中直接改变 prop 与 this.[prop]
【发布时间】: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 调用中的新值更改初始道具?

【问题讨论】:

    标签: vue.js


    【解决方案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,效果很好。
    猜你喜欢
    • 2017-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-11
    • 1970-01-01
    • 2020-09-24
    • 2019-08-05
    • 2019-10-24
    相关资源
    最近更新 更多