从子组件中过滤数组数据表

Posted

技术标签:

【中文标题】从子组件中过滤数组数据表【英文标题】:Filtering a table of array data from a child component 【发布时间】:2019-02-15 08:06:49 【问题描述】:

我正在将我的一个旧 php/jquery 单页应用程序迁移到 VueJS/Webpack 以适应使用后者。这是一个简单的表,它从 JSON API 获取数据并使用过滤器控件(在它们自己的组件中)。除了我试图使用我的子组件中的控件过滤我的表格外,一切都在工作。我已经为我用作表格数据源的数组设置了一个道具。

我的App.vue 模板如下所示:

<template>
  <div>
      <fan-modals v-bind:fans="fans"></fan-modals>

      <div class="container">
          <filter-controls v-bind:fans="fans"></filter-controls>
          <fans v-bind:fans="fans"></fans>
      </div>  <!-- end #container -->
  </div>
</template>

<script>
  import FilterControls from './components/FilterControls.vue';
  import Fans from './components/Fans.vue';
  import FanModals from './components/FanModals.vue';


  export default 
    name: 'app',
    data: function() 
      return 
        fansUrl: 'example.com',
        fans: []
      
    ,
    components: 
      filterControls: FilterControls,
      fans: Fans,
      fanModals: FanModals
    ,
    methods: 
        getFans: function (data) 
            var self = this;
            $.getJSON(self.fansUrl, function(data)
                self.fans = data;
            );
        
    ,
    mounted() 
        this.getFans();
    

</script>

我正在尝试在我的 &lt;FilterControls&gt; 组件中的一个函数中重用我在旧应用程序中使用的重构 jquery 脚本。这是我的&lt;FilterControls&gt; 子组件的脚本部分:

<script>
    export default 
        data: function() 
            return                 
                voltageArray: [],
                rpmArray: [],
                noiseLevelArray: [],

                selectedVoltage: 'Voltage',
                selectedRPM: 'Max RPM',
                selectedNoiseLevel: 'Max dBA',

                selectedImpellerSize: '',
                selectedCageSize: '',
                selectedPhase: '',
                selectedFrequency: '',
                secondVoltage: ''
            
        ,
        props: 
            fans: 
                type: Array
            
        ,
        watch: 
            fans(value) 
                this.populateControls(value);
            
        ,
        methods: 
            populateControls(fans) 

                //create emtpy arrays for dropdowns
                var voltage = [];
                var rpm = [];
                var noiseLevel = [];

                //for each fan in fans, get voltages, rpm and noiseLevel values and add them to the empty arrays
                $.each(fans, function(index, value) 
                    voltage.push(fans[index].voltage);
                    rpm.push(fans[index].rpm);
                    noiseLevel.push(fans[index].noise_level);
                );

                //deduplicate and sort arrays
                this.voltageArray = $.unique(voltage).sort();
                this.rpmArray = $.unique(rpm).sort(function(a, b)return a-b);
                this.noiseLevelArray = $.unique(noiseLevel).sort();

            ,
             filterFans(fans) 
                var filtered = $.grep(fans, function(fan) 
                   if (this.selectedVoltage === "208-240++")  var secondVoltage = "230"; ;

                    return  (selectedImpellerSize === ''    || fan.diameter === selectedImpellerSize);// &&
                            (selectedCageSize === ''            || fan.cage_diameter === selectedCageSize) &&
                            (selectedPhase === ''               || fan.phases === selectedPhase) &&
                            (selectedFrequency === ''           || fan.frequency === selectedFrequency) &&
                            (selectedRPM === 'Max RPM'          || fan.rpm  <= parseInt(selectedRPM)) && 
                            (selectedNoiseLevel === 'Max dBA'   || fan.noise_level <= selectedNoiseLevel) &&
                            (selectedVoltage === 'Voltage'      || fan.voltage === selectedVoltage || fan.voltage === (jQuery.isEmptyObject(secondVoltage) ? selectedVoltage : secondVoltage));
                );

                fans = filtered;
            
        
    
</script>

populateControls() 方法用可能的值填充我的下拉列表以进行过滤。我正在尝试使用filterFans() 方法过滤用于填充我的表的fans 数组。当我将此方法附加到按钮单击时,我收到错误:

Uncaught TypeError: Cannot read property 'length' of undefined

它引用了以var filtered = $.grep(fans, function(fan) 开头的行,所以我猜它在遍历我的fans 数组时遇到了问题。

我知道有更好的方法可以做到这一点,但我对 VueJS 很陌生。我是否遗漏了一些非常明显的东西?

【问题讨论】:

在每次调用该变量时使用this.fans 【参考方案1】:

问题可能在于您使用按钮的事件处理程序绑定。例如,您可能有这样的:

<button @click="filterFans()">Filter fans</button>

问题在于缺少filterFans 所需的函数参数(即fans)。 $.grep 尝试读取 fans.length,导致您看到的错误。

您可以通过更新模板中的处理程序来解决此问题:

<button @click="filterFans(fans)">Filter fans</button>

或者更新filterFans直接读取this.fans

filterFans() 
  const filtered = $.grep(this.fans, /* ... */);

【讨论】:

以上是关于从子组件中过滤数组数据表的主要内容,如果未能解决你的问题,请参考以下文章

我可以从子组件获取计算数据到父组件吗?

如何在反应中将数组从子组件发送到父组件?

Vue2 使用 $ref 从子组件加载数据并放入父组件的数据

为啥父组件不能从子组件获取数据? 1

无法将数据从子功能组件传递到反应父组件(React.js)[重复]

如何在Angular中将表单数据从子组件传输到父组件