Vue听不到触发的深层道具

时间:2018-05-02 15:07:43

标签: vue.js vue-component

我必须按照一组组件来创建表

  • table - 使用标题(传递列)和行列表给出rowData&列

  • header - 利用传递的列并使用headerCell传递列属性

  • headerCell
  • row - 遍历给定列并显示数据

我的问题如下,我希望标题上的单击(例如可见性)使用visible true更新columnDefinition false并由行观察以相应地更新visiblity。 然而,无论我尝试了什么,观察者仍然没有触发。我究竟做错了什么?



/**** Table ***/
<template>
    <table>
    <HeaderRow :columns=computedColumns :groups=columnGroups v- 
        on:column:change=onColumnChange></HeaderRow>
    <tbody>
         <Row v-for="(row, index) in computedData" :key=index :data=row 
              :columns=computedColumns :rowIndex=index ></Row>
    </tbody>
    </table>
</template>
<script>
import Row from "./Row.vue";
import HeaderRow from "./HeaderRow.vue";
export default {
	computed: {
    /* If this.columns is set (columns is a prop) than map it to a new array, otherwise 
       try to identify the columns from the row data */
		computedColumns: function() {
      if (this.columns && this.columns.length) {
				return this.columns.map(col => {
                    return Object.assign({
                        title: '',
                        name: '',
                        description: undefined,
                        className: '',
                        style: '',
                        visible: true,
                        sort: false,
                        group: undefined,
                        defaultValue: undefined,
                    }, col)
                });
			} else {
				return (
					this.data &&
					this.data
						.map(function(row) {
							return Object.keys(row);
						})
						.reduce(function(arr, row) {
							return arr.concat(
								row.filter(function(value, index) {
									return arr.indexOf(value) == -1;
								})
							);
						}, [])
						.map(function(column) {
							return {
								title: column,
								name: column
							};
						})
				);
			}
		},
   }

/*** HeaderCell ***/ 
    <th @click=toggleColumn :class=className><span>{{column.title}}</span></th>
    ...
    ...
    toggleColumn: function(e) {
    		this.visible = !this.visible;
    		this.column.visible = this.visible;
    		this.$emit("column:change", {
    			column: this.column,
    			columnIndex: this.columnIndex
    		});
    	}

/***   Row  ****/
    <template>
    <tr>
      <td  v-for="(cell, index) in cells" :key=index :class=cell.className 
    :style=cell.style v-html=cell.value ></td>
    </tr>
    </template>
    <script>
    export default {
    props: {
        data: {
            default: []
        },
        columns: {
            default: "",
            type: Array
        },
        rowIndex: {
            default: -1
        }
    },
    watch: {
        columns: {
            handler: function () {
                console.log('change occurred')
            },
            deep: true
        }
    },
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

我注意到你的专栏道具正在使用computedColumns

很高兴看到这是什么,因为当您从该计算属性返回值时,它可能会失去反应性。

例如,如果您的父母中有以下内容:

computed: {
    computedColumns() {
        // return new set of columns
        return [
            {id: 1, visible: false},
            {id: 2, visible: false},
            {id: 3, visible: false}
        ]
    }
}

然后computedColumns属性将没有任何反应性。因此,您将无法观看它。

但是,如果您有一个例子:

data() {
    return {
        columns: [
            {id: 1, visible: false},
            {id: 2, visible: false},
            {id: 3, visible: false}
        ]
    }
},
computed: {
    computedColumns() {
        // return reactive data attribute
        return this.columns
    }
}

因为您正在引用原始数据属性,所以您将保持反应性。

因此,您可能需要重新考虑如何设置columns属性以保持反应性。

这是一个概述此示例的fiddle