Чи є правильний спосіб скинути початкові дані компонента у vuejs?


93

У мене є компонент із певним набором вихідних даних:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', // possible values: 'getUserInput', 'confirmGeocodedValue'
        submitButtonText: 'Lookup', // possible values 'Lookup', 'Yes'
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        }
}

Це дані для модального вікна, тому, коли воно відображається, я хочу, щоб воно починалося з цих даних. Якщо користувач скасує вікно, я хочу скинути всі дані до цього.

Я знаю, що можу створити метод скидання даних і просто вручну повернути всі властивості даних до початкових:

reset: function (){
    this.modalBodyDisplay = 'getUserInput';
    this.submitButtonText = 'Lookup';
    this.addressToConfirm = null;
    this.bestViewedByTheseBounds = null;
    this.location = {
        name: null,
        address: null,
        position: null
    };
}

Але це здається справді недбалим. Це означає, що якщо я коли-небудь внесу зміни до властивостей даних компонента, мені потрібно буде переконатися, що я пам’ятаю оновити структуру методу скидання. Це не зовсім жахливо, оскільки це невеликий модульний компонент, але це викликає крик оптимізації мого мозку.

Рішенням, яке, на мою думку, буде працювати, було б захопити початкові властивості даних у readyметоді, а потім використати ці збережені дані для скидання компонентів:

data: function (){
    return {
        modalBodyDisplay: 'getUserInput', 
        submitButtonText: 'Lookup', 
        addressToConfirm: null,
        bestViewedByTheseBounds: null,
        location:{
            name: null,
            address: null,
            position: null
        },
        // new property for holding the initial component configuration
        initialDataConfiguration: null
    }
},
ready: function (){
    // grabbing this here so that we can reset the data when we close the window.
    this.initialDataConfiguration = this.$data;
},
methods:{
    resetWindow: function (){
        // set the data for the component back to the original configuration
        this.$data = this.initialDataConfiguration;
    }
}

Але initialDataConfigurationоб'єкт змінюється разом із даними (що має сенс, оскільки в методі читання ми initialDataConfigurationотримуємо область дії функції даних.

Чи є спосіб отримати вихідні дані конфігурації без успадкування області дії?

Я надмірно над цим замислююсь, і є кращий / простіший спосіб зробити це?

Чи є єдиним варіантом жорстке кодування вихідних даних?


Ви використовуєте v-show або v-if для відображення модальних?
Rwd

Я використовую bootstrap для css, тому використовую вбудований модальний, який використовує jquery для показу та приховування. Отже, по суті віконна частина компонента завжди є, просто прихована.
Chris Schmitz

Відповіді:


125
  1. витягнути початкові дані у функцію поза компонентом
  2. використовуйте цю функцію для встановлення вихідних даних у компоненті
  3. повторно використати цю функцію для скидання стану за необхідності.

// outside of the component:
function initialState (){
  return {
    modalBodyDisplay: 'getUserInput', 
    submitButtonText: 'Lookup', 
    addressToConfirm: null,
    bestViewedByTheseBounds: null,
    location:{
      name: null,
      address: null,
      position: null
    }
  }
}

//inside of the component:
data: function (){
    return initialState();
} 


methods:{
    resetWindow: function (){
        Object.assign(this.$data, initialState());
    }
}


5
Це вдалося. Дякую! Я зробив невелике редагування відповіді, але лише тому, що компонент vue вимагає функції, повернутої для даних, а не просто об’єкта. Ваша концепція відповідей безумовно працює і є правильною, редагування полягає лише в тому, щоб врахувати, як vuejs обробляє компоненти.
Chris Schmitz

3
Ви маєте рацію щодо функції властивості data, якою я був неакуратним. Дякуємо за редагування.
Лінус Борг,

13
Тепер воно видає помилку:[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.
Sankalp Singha

34
@SankalpSingha Vue 2.0 більше не дозволяє вам цього робити. Ви можете використовувати Object.assignзамість цього. Ось робочий код: codepen.io/CodinCat/pen/ameraP?editors=1010
CodinCat

3
Для цього випуску - [попередження Vue]: уникайте заміни кореневих даних екземпляра $. Замість цього використовуйте властивості вкладених даних, спробуйте це. $ Data.propName = "нове значення";
Станіслав Остапенко

33

Щоб скинути компонент dataу поточному екземплярі компонента, ви можете спробувати це:

Object.assign(this.$data, this.$options.data())

Приватно у мене є абстрактний модальний компонент, який використовує слоти для заповнення різних частин діалогу. Коли налаштовані модальні обтікання, які абстрагують модальні дані, зазначені в слотах, належать до області батьківського компонента . Ось варіант абстрактного модалу, який скидає дані кожного разу, коли відображається налаштований модаль (код ES2015):

watch: {
    show (value) { // this is prop's watch
      if(value) {
        Object.assign(this.$parent.$data, this.$parent.$options.data())
      }
    }
}

Ви можете точно налаштувати свою модальну реалізацію, звичайно - вище також може бути виконано в якомусь cancelгачку.

Майте на увазі, що мутація $parentопцій з боку дочірнього не рекомендується, однак, я думаю, це може бути виправдано, якщо батьківський компонент просто налаштовує абстрактний модальний спосіб і не більше того.


1
Тепер ця техніка дає попередження VueJS; див. stackoverflow.com/questions/40340561/…
Ківі Шапіро,

7
Обережно, це не пов’язує контекст data. Отже, якщо ви використовуєте thisу своєму dataметоді, ви можете застосувати контекст за допомогою:Object.assign(this.$data, this.$options.data.apply(this))
Якщо не

У чому перевага цього способу в порівнянні з location.reload ()?
Карлос

30

Обережно, Object.assign(this.$data, this.$options.data())не прив'язує контекст до даних ().

Тож використовуйте це:

Object.assign(this.$data, this.$options.data.apply(this))

cc ця відповідь спочатку була тут


3

Якщо вас дратують попередження, це інший спосіб:

const initialData = () => ({})

export default {
  data() {
    return initialData();
  },
  methods: {
    resetData(){
      const data = initialData()
      Object.keys(data).forEach(k => this[k] = data[k])
    }
  }
}

Не потрібно возитися з даними $.


2

Мені довелося скинути дані до початкового стану всередині дочірнього компонента, ось що мені вдалося:

Батьківський компонент, що викликає метод дочірнього компонента:

     <button @click="$refs.childComponent.clearAllData()">Clear All</button >

     <child-component ref='childComponent></child-component>

Дочірній компонент:

  1. визначення даних у зовнішній функції,
  2. присвоєння об'єкту даних функції та зовні
  3. визначення методу clearallData (), який повинен викликати батьківський компонент

    function initialState() {
       return { 
         someDataParameters : '',
         someMoreDataParameters: ''
              }
      }
    
    export default {
       data() {
        return initialState();
      },
        methods: {
      clearAllData() {
      Object.assign(this.$data, initialState());
    },
    
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.