Правильный способ повторной инициализации данных в VueJs 2.0

Я просматривал этот ответ на SO: vuejs">Есть ли правильный способ сброса исходных данных компонента в vuejs?

Однако текущий метод сейчас не разрешен, и VueJS запрещает изменять переменную $data.

Как вы можете видеть здесь, в этом https://github.com/vuejs/vue/issues/2873 ( $data не может быть изменен. )

Поэтому, если я попробую вышеуказанный метод, я получу предупреждение VueJS:

[Предупреждение Vue]: избегайте замены корня экземпляра $data. Вместо этого используйте вложенные свойства данных.

Вот мой JS-код,

function initialState () {
        return {
            h2: 0,
            ch4: 0,
            c2h6: 0,
            c2h4: 0,
            c2h2: 0,
            c3h8: 0,
            c3h6: 0,
            co: 0,
            co2: 0,
            o2: 0,
            n2: 0,
            selected: ''
        }
    }
    export default {
        name: 'something',
        data () {
            return initialState() // This is working fine 
        },
        computed: {
            tdcg: function () {
                // some logic here...
            }
        },
        methods: {
            resetFields: function () {
                this.$data = initialState() // --> This is what I want to achieve!
            }
        }
    }

Итак, каков правильный и самый простой способ повторной инициализации моих данных?


person Sankalp Singha    schedule 31.10.2016    source источник


Ответы (5)


Вы можете использовать Object.assign для повторения все свойства и назначьте их:

export default {
    data () {
        return {
            h2: 0,
            // other attributes...
        };
    },
    methods: {
        resetFields () {
            Object.assign(this.$data, this.$options.data.call(this));
        }
    }
}

Вот демонстрационная скрипта: https://jsfiddle.net/797yyvtz/


Примечание. Я использую this.$options.data для повторного вызова исходного метода data для получения новой копии данных. Нет необходимости в отдельной функции initialState. Метод data является функцией начального состояния.

person Joseph Silber    schedule 29.11.2016
comment
Внимание, это решение не привязывает контекст к data. Поэтому, если вы используете this в своем методе data, вы можете применить контекст с помощью: Object.assign(this.$data, this.$options.data.apply(this)) - person Ifnot; 16.06.2017
comment
Это решение будет применять контекст компонента, доступный во время вызова resetFields(), поэтому контекст доступен здесь. Или вы говорите, что использование this на data() плохой практике? (поскольку this — это экземпляр vue, вы можете использовать здесь $store и другие вещи, которые недоступны без apply(this)) - person Ifnot; 23.06.2017

Вы пытались перебрать объект initialState и установить его снова? Вот пример кода:

function initialState() {
    return {
        h2: 0,
        ch4: 0,
        // and so on... finally
        selected: ''
    }
}

export default {
    name: 'something',
    data: function() {
        return initialState()
    },
    computed: {
        // ...
    },
    methods: {
        resetFields: function() {
            // Fetch the initialState object locally, so we do not have to call the function again
            let initialData = initialState();
            // Iterate through the props
            for (let prop in initialData) {
                // Reset the prop locally.
                this[prop] = initialData[prop];
            }
        }
    }
}

В моих ограниченных локальных экспериментах это, кажется, работает. Дайте мне знать ваши мысли об этом методе.

person Mani    schedule 31.10.2016
comment
Да, он работает безупречно в моем локальном тестировании. Но немного странно делать this[prop], поскольку мы так привыкли видеть this.prop везде. Если мы присоединяемся к философии, что все является объектом в javascript, то это выглядит нормально. - person Mani; 31.10.2016
comment
Я знаю. Это работает, но это не похоже на оптимальное решение для меня. Проблема в том, что все учебники, которые я нашел в Интернете о Vue, имеют тенденцию использовать версию 1.0 или более раннюю. И так много изменений было сделано в 2.0. - person Sankalp Singha; 31.10.2016
comment
Я согласен. Давайте подождем лучшего ответа, может быть, кто-нибудь укажет нам на новый метод, который также кажется правильным. Даже я не доволен этим методом, я бы предпочел тщательно сбросить каждое отдельное свойство данных непосредственно в моем методе, вместо того, чтобы слепо перебирать доступные реквизиты и использовать странный this[prop] для установки данных. - person Mani; 31.10.2016
comment
Это не сработает, если вы также наблюдаете за модификацией модели. Это вызовет ответ, который может не дать модели начальное состояние. - person Stefano Borini; 28.04.2017

Оберните все данные в словарь с ключом под названием «данные» или чем-то еще. Затем вы можете повторно инициализировать все данные, установив this.data = {xx: yy}, или напрямую изменить один элемент данных, например this.data.h2 = 2.

function initialState () {
    return {
        h2: 0,
        ch4: 0,
        c2h6: 0,
        c2h4: 0,
        c2h2: 0,
        c3h8: 0,
        c3h6: 0,
        co: 0,
        co2: 0,
        o2: 0,
        n2: 0,
        selected: ''
    }
}
export default {
    name: 'something',
    data () {
        return {data: initialState()} // This is working fine 
    },
    computed: {
        tdcg: function () {
            // some logic here...
        }
    },
    methods: {
        resetFields: function () {
            this.data = initialState() // --> This is what I want to achieve!
        }
    }
}
person seaify - Freelancer    schedule 31.10.2016
comment
Вы хоть читали мой вопрос выше? Я не могу понять голову или решку из вашего ответа. Пожалуйста, внимательно прочитайте вопрос, прежде чем публиковать свои ответы. - person Sankalp Singha; 31.10.2016
comment
@SankalpSingha да, я внимательно прочитал ваш вопрос. Код, который я вставляю, представляет собой способ вложенных свойств данных. Изменение кода очень небольшое, и вы, кажется, не очень хорошо поняли vue, поэтому не поняли сути. - person seaify - Freelancer; 31.10.2016
comment
@SankalpSingha проверьте этот пример jsfiddle, jsfiddle.net/seaify/konv9h78, и попробуйте ввести и нажмите кнопку сброса кнопка - person seaify - Freelancer; 31.10.2016

Вы можете попробовать это:

  1. Инициализируйте свойства данных формы с обязательными полями. (Как видно из ШАГА 1)
  2. Создайте еще одно поле данных, которое будет использоваться для клонирования данных формы, которые вы хотите сбросить (как показано в ШАГЕ 2).
  3. Клонируйте необходимые данные формы (ШАГ 3)
  4. Напишите свой метод сброса (ШАГ 4)
  5. Используйте любое место, где вы предпочитаете (ШАГ 5)

export default {
  // Initialize your data
  data() {
    return {
      // Initialize the form field (STEP 1)
      formFields: {
        name: '',
        email: '',
        password: '',
        moreData: {
          field1: '',
          field2: [],
        },
      },
      // Create an object property used for cloning (STEP 2)
      formFieldsCopy: {},
    };
  },

  // When the DOM is mounted copy the
  // formField you want to a temporary field
  // You can use lodash ._clone or ES6 spread operator (STEP 3)
  mounted() {
    this.formFieldsCopy = { ...this.formFields
    };
  },
  methods: {
    // Write the function to reset the form (STEP 4)
    resetFormFields() {
      this.formFields = { ...this.formFieldsCopy
      };
    },
    submit() {
      // Do you normal Axios requests here
      // and call you reset function. (STEP 5).
      this.resetFormFields();
    },
  },
};

person Ikechi    schedule 26.02.2018
comment
Добавьте описание - person Mathews Sunny; 26.02.2018

Мое решение:

mounted(){
    this.saveData() // you can load if you need previous data
},
methods: {
    saveData(){
        localStorage.setItem(this.$options.name,JSON.stringify(this.$data));
    },
    loadData(){
        if (localStorage.getItem(this.$options.name) !== null) {
            let data= JSON.parse(localStorage.getItem(this.$options.name));
            Object.keys(data).forEach((key)=>{this[key] = data[key];});
        }
    }
}

Когда вам нужно, вы можете загрузить или сохранить их снова

person Mohsen    schedule 07.03.2018