vuejs2 - 为什么 v-bind 是单向数据绑定(bind),而 v-for 可以更新 vue.js 中子组件的数据?

标签 vuejs2 vue-component

伙计们。我正在阅读 The Majesty Of Vue.js 2 这本书。我对书中的一个示例感到困惑。

我的问题是 - 为什么点赞按钮可以修改 pre 标签中显示的 Vue 实例的数据,而收藏按钮却不能?

据说,favorite 是通过 v-bind 指令绑定(bind)的,这是数据绑定(bind)的一种方式,意味着子级无法与父级同步数据。但故事是如何更新的呢?像 v-model 这样的双向数据绑定(bind)?

下面是代码示例:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Vue</title>
</head>
<body>
<div v-cloak id="app">
    <div class="container">
        <h1>Let's hear some stories!</h1>
        <ul class="list-group">
            <story v-for="story in stories" :story="story" :favorite="favorite"></story>
        </ul>
        <pre>{{ $data }}</pre>
    </div>
</div>
</body>
<template id="story-template">
    <li class="list-group-item">
        {{ story.writer }} said "{{ story.plot }}"
        Story upvotes {{ story.upvotes }}.
        <button v-show="!story.voted" @click="upvote" class="btn btn-default">Upvote</button>
        <button v-show="!isFavorite" @click="setFavorite" class="btn btn-primary">Favorite</button>

    </li>
</template>
<script src="../../vue.js"></script>
<script type="text/javascript">
    Vue.component('story', {
        template: "#story-template",

        props: ['story', 'favorite'],
        methods: {
            upvote: function () {
                this.story.upvotes += 1;
                this.story.voted = true;
            },
            setFavorite: function () {

                this.favorite = this.story;
            }
        },
        computed: {
            isFavorite: function () {
                return this.story === this.favorite
            }
        }
    });
    window.app = new Vue({
        el: '#app',
        data: {
            stories: [
                {
                    plot: 'My horse is amazing.',
                    writer: 'Mr. Weebl',
                    upvotes: 28,
                    voted: false
                },
                {
                    plot: 'Narwhals invented Shish Kebab.',
                    writer: 'Mr. Weebl',
                    upvotes: 8,
                    voted: false
                },
                {
                    plot: 'The dark side of the Force is stronger.',
                    writer: 'Darth Vader',
                    upvotes: 49,
                    voted: false
                },
                {
                    plot: 'One does not simply walk into Mordor',
                    writer: 'Boromir',
                    upvotes: 74,
                    voted: false
                }
            ],
            favorite: {}
        }
    })
</script>
</html>

最佳答案

这与对象在 Javascript 中的工作方式有关。当存储在变量中时,您就获得了对该对象的引用。因此,当您传递它时,实际上只是传递引用。这意味着改变一个对象(而不是覆盖!),改变是在所有地方。

您的示例中发生的情况是您修改了故事对象。您可以更改其键,但不会覆盖对象本身。看到应用程序对故事对象有相同的引用。显示更改。

然而,在最喜欢的情况下。您将获得最喜欢的对象的引用。但一旦你点击最喜欢的按钮。它交换变量以引用故事,但仅限于本地。该应用程序仍然保留旧的引用。这是因为您只传递引用本身,而不传递父对象。

这就是像 Vuex 这样的状态管理器发挥作用的地方。

关于vuejs2 - 为什么 v-bind 是单向数据绑定(bind),而 v-for 可以更新 vue.js 中子组件的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46148670/

相关文章:

javascript - 从父组件同步更改子组件检查状态失败

vue.js - 无法读取 null 的属性(读取 'find' )

vue.js - View : Migrating to vue3?

javascript - 继续在历史记录中前后添加行

vuejs2 - 我可以在 Vue 路由器中为特定路由设置多个别名吗?

vuejs2 - 如何使用 nuxtjs/pwa 实现后台同步?

vue.js - 是否可以从安装在 Vuejs 中发射?

javascript - v-for 按日期分组渲染项目

vuejs2 - 禁用基于 bool 值的nuxt链接

jquery - 在 vuejs 中使用列表框的数据绑定(bind)问题