vue父组件访问子组件的计算属性

Posted

技术标签:

【中文标题】vue父组件访问子组件的计算属性【英文标题】:Vue parent component access to child component's computed Property 【发布时间】:2020-09-30 09:06:21 【问题描述】:

在 Vue JS 中,当在数组元素(子)的计算属性中进行更改时,我无法观察数组的更改。

我已经在我编写的示例 JSFiddle 中将问题归结为问题,因此该示例在逻辑上可能没有意义,但它确实显示了我的问题。

https://jsfiddle.net/trush44/9dvL0jrw/latest/

我有一个包含颜色数组的父组件。每种颜色都使用子组件进行渲染。子组件有一个名为“IsSelected”的计算属性。当任何数组元素上的“IsSelected”计算属性发生变化时,我需要遍历整个数组以查看是否仍然选择了数组中的至少 1 个元素,然后相应地设置 IsAnyCheckboxChecked。

    你能帮我理解我是否在做我的计算和观察 正确吗? 在-parent组件的watch中,为什么this.colors[i].IsSelected 即使 IsSelected 在 DOM 中渲染得很好,也返回 undefined?
<div id="app">
  Is any Color Selected?...... IsAnyCheckboxChecked
  <the-parent inline-template :colors="ColorList">
    <div>
      <the-child inline-template :color="element" :key="index" v-for="(element, index) in colors">
        <div>
          color.Text
          <input type="checkbox" v-model="color.Answer" />
          IsChecked?......IsSelected
        </div>
      </the-child>
    </div>
  </the-parent>
</div>
Vue.component('the-child',         
    props: ['color'],
    computed: 
        IsSelected: function () 
            return this.color.Answer;
        
    
);

Vue.component('the-parent', 
    props: ['colors'],
    watch: 
        colors: 
            handler: function (colors) 
                var isAnyCheckboxChecked = false;

                for (var i in this.colors) 
                        // IsSelected is undefined even though it's a 'computed' Property in the-grandchild component
                    if (this.colors[i].IsSelected)  
                        isAnyCheckboxChecked = true;
                        break;
                    
                
                this.$parent.IsAnyCheckboxChecked = isAnyCheckboxChecked;
            ,
            deep: true
        
    
);

// the root view model
var app = new Vue(
    el: '#app',
    data: 
        'IsAnyCheckboxChecked': false,
        'ColorList': [
            
                'Text': 'Red',
                'Answer': true
            ,
            
                'Text': 'Blue',
                'Answer': false
            ,
            
                'Text': 'Green',
                'Answer': false
            
        ]
    
);

【问题讨论】:

【参考方案1】:

使用 $refs 直接访问孩子。在 v-for ref 内部变成和数组。因为你的 v-for 是基于 this.color.length 无论如何都使用相同的东西来循环 $ref var中的值。

https://jsfiddle.net/goofballtech/a6Lu4750/19/

<the-child ref="childThing" inline-template :color="element" :key="index" v-for="(element, index) in colors">

for (var i in this.colors) 

  if (this.$refs.childThing[i].IsSelected)  
    isAnyCheckboxChecked = true;
    break;
  

【讨论】:

谢谢 - 这很好用!我还在学习手表以及如何在组件之间传递值。如果您看到任何其他更好的方法来完成我的示例的其他部分,请告诉我! :) 您也可以查看 $emit。它也可以用于此目的。不过,无论哪种方式都可以正常工作。 会的。我刚刚意识到您的最新 JSFiddle 存在一个问题,即 IsAnyCheckboxChecked 默认情况下应该为真,但在我选中一个框之前它仍然是假的。知道为什么颜色处理程序手表没有在加载时触发吗? 在对该问题进行了一些研究之后,看起来我必须在父组件的“挂载”上手动触发相同的处理程序代码。这似乎可以解决它。 这是正确的。在值更改之前不会触发它。由于您的初始 var 集是以这种方式建立的并且没有“更改”,因此该函数不会在创建时运行。搞清楚这件事做得很好。

以上是关于vue父组件访问子组件的计算属性的主要内容,如果未能解决你的问题,请参考以下文章

Vue 全家桶,深入Vue 的世界

Vue.js - 如何访问子组件的计算属性(Vuetify 数据表)

如何在父组件调用子组件的方法

vue子组件怎么调用父组件的方法

子组件中修改props的正确方式

Vue组件实例间的直接访问