首页 > 解决方案 > 修改了数组的对象属性,但在页面上没有更改

问题描述

我在使用vue + typescript写一个简单的demo时遇到了问题。

代码

<template>
    <div class="hello">
        <ul>
            <li v-for="user in users" v-on:click="clickUser(user)" class="user">
                {{user}}
            </li>
        </ul>
    </div>
</template>

<script lang="ts">
    import {Component, Prop, Vue} from 'vue-property-decorator';

    type User = {
        name: string,
        clicked?: boolean
    }

    @Component
    export default class HelloWorld extends Vue {
        @Prop() private users: Array<User> = [{name: "Mike"}, {name: "Ann"}];

        clickUser(user: User) {
            user.clicked = true
            alert("clicked on " + user.name + ": " + user.clicked)
        }
    }
</script>

它们显示在页面上:

* { "name": "Mike" }
* { "name": "Ann" }

当我点击 Ann 时,它会提示:

clicked on Ann: true

但是页面上没有任何变化。我希望该行* { "name": "Ann" }* { "name": "Ann", "clicked": true }

如何解决?

一个完整的小演示:https ://github.com/freewind-demos/vue-modify-array-object-demo

标签: typescriptvuejs2watch

解决方案


这里的问题是,当您将新的键/值对添加到响应式对象时,该对本身不是响应式的,因为 Vue 无法检测到添加到响应式对象的新属性。您需要使用Vue.set(target,key,value)此处的方法。所以改变你的方法中的user.clicked分配,clickUser()如下所示。它应该神奇地开始工作!

    clickUser(user: User) {
        Vue.set(user,'clicked',true)
        alert("clicked on " + user.name + ": " + user.clicked)
    }

更多在这里https://vuejs.org/v2/api/#Vue-set &在这里https://vuejs.org/v2/guide/reactivity.html

有时这确实看起来有点违反直觉,因为如果您不是修改用户,而是添加一个全新的用户,this.users.push({"name":"John"})它就可以工作。但是对于一个您正在创建一个新的反应对象,而对于另一个您正在修改一个现有的对象。


推荐阅读