【问题标题】:Vue 3 - Broadcast Property Changes Down TreeVue 3 - 广播属性沿树向下变化
【发布时间】:2021-05-21 15:16:31
【问题描述】:

我有一个结构如下的 Vue 3 应用程序:

+---------------------+
| Component           |
| +-----------------+ |
| | Child Component | |
| +-----------------+ |
+---------------------+

组件定义如下:

my-component.vue

<template>
  <button @click="addItem" />

  <child-component :items="items" />
</template>
<script>
  import Child from './my-child-component.vue';
  export default {
    components: { 'child-component' : Child },
    
    data() {
      items: {}   // NOTE: This is an object, not an array
    },

    methods: {
      addItem() {
        var count = Math.floor((Math.random() * 100) + 1);
        var name = 'item' + count;
        
        var children = [];
        for (var i=0; i<count; i++) {
          children.push(i+1);
        }

        this.items[name] = children;
      }
    }
  }
</script>

my-child-component.vue

<template>
  <div>Details of the Items</div>
</template>
<script>
  export default {
    props: {
      items: {
        type: Object,
        default: {}
      }
    }        

    watch: {
      items() {
        console.log('the items have changed');
      }
    }
  }
</script>

此代码动态地将属性添加到items 对象。不幸的是,child-component 没有看到 items 对象的变化。在 Vue 2 中,有一个 $vm.set 方法来解决这种情况。但是,我不确定如何在 Vue 3 中解决这个问题。

如何以子组件知道更改的方式动态更新对象?

谢谢!

【问题讨论】:

    标签: vue.js vuejs3


    【解决方案1】:

    当你使用 Vue3 的 setup() 函数时,属性作为第一个参数传递给它,保持它们的反应性。这是一个在每次属性更改时触发观察者的工作示例:

    const appConfig = {
      data() {
        return {
          items: {}
        }
      }
    };
    
    const app = Vue.createApp(appConfig);
    app.component('ChildComponent', {
      props: {
        items: {
          type: Object,
          default: {}
        }
      },
      template: 'items: {{items}}',
      setup(props) {
        Vue.watch(props.items, () => {
          console.log("items changed");
        });
    
        return {
          items: props.items
        }
      }
    });
    
    app.mount('#app');
    <script src="https://unpkg.com/vue@3.0.11/dist/vue.global.prod.js"></script>
    
    <div id="app">
      <button @click="items[Object.keys(items).length] = true">add</button>
      <p>
        <child-component :items="items" />
      </p>
    </div>

    【讨论】:

      【解决方案2】:

      由于被监视的属性是一个对象,你应该添加deep:true 选项:

          watch: {
            items: {
               handler(){
                console.log('the items have changed');
                 },
              deep:true
             
            }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-05-04
        • 1970-01-01
        • 2021-01-17
        • 2019-08-07
        • 1970-01-01
        • 2021-05-21
        • 1970-01-01
        相关资源
        最近更新 更多