Как мутировать VueJS проп?

Привет у меня возникли проблемы с пониманием, как изменить значение проп в VUE JS. Я использую vue-chartjs для динамического рендеринга диаграммы с использованием chartjs. Поведение работает, но я получаю предупреждение о консольном сообщении, когда запускаю функцию updateValues ​​().

Vue warn]: избегайте прямого изменения свойства, так как значение будет перезаписываться при каждом повторном рендеринге родительского компонента. Вместо этого используйте данные или вычисляемое свойство, основанное на значении реквизита. Опора изменена: "myData"

Как правильно поменять опору?

// Parent Component
<bar-graph :myData="dataCollection" :height="250"></bar-graph>

data () {
  return {
    dataCollection: {
      labels: [2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
      datasets: [
        {
          label: 'Sample Lables',
          backgroundColor: 'red',
          data: [5000, 5000, 5000, 5000, 5500, 5500, 10000, 5500, 5500]
        }
      ]
    }
  }
},
methods: {

  updateValues () {
    this.dataCollection = {
      labels: [5000, 5000, 5000, 5000, 5500, 5500, 10000, 5500, 5500],

      datasets: [
        {
          label: 'Sample Lables',
          backgroundColor: 'red',
          data: [5000, 5000, 5000, 5000, 5500, 5500, 10000, 5500, 5500]
        }
      ]
    }
  }
}
      
      
//Child component bar graph

import { Bar } from 'vue-chartjs'

export default Bar.extend({

  props: ['myData'],

  mounted () {
    this.renderChart(this.myData, {responsive: true, maintainAspectRatio: false})
  },
  watch: {
    myData: function () {
      console.log('destroy')
      this._chart.destroy()
      this.renderChart(this.myData, {responsive: true, maintainAspectRatio: false})
    }
  }
})

1 ответ

Нет способа "правильно" мутировать проп, потому что это входные данные для компонента.

Я рекомендую импортировать данные, переданные через реквизит, в состояние компонента, а затем использовать соответственно. Используя эту локальную копию, вы не будете мутировать опору и получать это предупреждение.

export default Bar.extend({

  props: ['myData'],

  data() {
    return {
      passedData: null
    }
  }

  mounted() {
    // Import data from prop into component's state
    this.passedData == this.myData;
    // Use as desired
    this.renderChart(this.myData, {
      responsive: true,
      maintainAspectRatio: false
    })
  },
  watch: {
    myData: function() {
      console.log('destroy')
      this._chart.destroy()
      this.renderChart(this.myData, {
        responsive: true,
        maintainAspectRatio: false
      })
    }
  }
})

Используйте данные или вычисленное свойство, основанное на значении реквизита.

просто привяжите свою собственность к свойству данных

data() {
  return {
    myPropData: myData
  }
}

а затем использовать только myPropData

Комментарий / дополнение к ответу @TheCascadian: Если myData является Object, тогда this.passedDataбудет ссылкой на тот же объект, поэтому вы все равно получите это предупреждение. Вы можете подумать об использовании cloneDeep из lodash иметь реальную внутреннюю копию свойства и соответствующим образом использовать ее внутри.

Другие вопросы по тегам