vue.js:如何使用对象更新状态?

时间:2018-08-18 02:37:44

标签: javascript reactjs vuejs2

我是vue.js的新手,但是我以前有过使用React的经验。

我已经阅读了vue指南,并且试图通过React中的概念来理解vue。

我认为vue data与React state类似,因为当更新应用程序时,它将再次呈现页面。

所以我想做类似...(代码在React中)

this.setState(Object.assign({}, this.state, { key1: 'value1', key2 : 'value2'}))

但据我所知,是这样的:

this.key1 = 'value1';
this.key2 = 'value2';

对吗?我猜vue将渲染两次,因为它是2条语句。 如何一次设置多个值?

我已经尝试过...

// not working
this.$set(Object.assign({}, thisRef.data, { key1: 'value1', key2: 'value2' }))

// not working
this.data = { key1 : 'value1', key2: 'value2' };

在第二个数据中,数据已更改-我已经用console.log(this)-打印了值,但是不再显示。

仅供参考,vue模板中的完整代码在这里。代码审查和更正将非常受欢迎。

<script>
    export default {
        layout: 'reactQuickly'
        , data: function(){
            return {
                time: null
                , init: null
            }
        }
        , methods: {
            startTimer: function(time){
                clearInterval(this.init);
                let thisRef = this;
                let interval = setInterval(
                    function(){
                    console.log('2: Inside of interval', time)
                    let timeLeft = thisRef.time - 1;
                    if(timeLeft <= 0) clearInterval(interval);
                    thisRef.time = timeLeft;
                    // thisRef.$set(Object.assign({}, thisRef.data, { time: timeLeft }))
                    console.log('thisRef', thisRef, this);}
                , 1000);
                console.log('1: After interval');
                // this.data = { time : time, init: interval };
                this.time = time;
                this.init = interval;
                console.log('this.data', this.data);
                // this.$set(Object.assign({}, this.data, { time : time, init: interval}));
            }
        }
    }
</script>

============版本==========

反应this.state和vue this.data不一样,对吗? 对我来说,主要的困惑就是从这一点开始。

公开中

export default {
  data : function() {
    return {
      foo : 'bar'
    }
  }
}

反应中

constructor() {
  super()
  this.state = {
    foo : 'bar'
  }
}

是完全不同的概念,对吧?

3 个答案:

答案 0 :(得分:4)

您不必担心这个问题。您无需担心Vue中的set multi values at once

(我从这篇很棒的文章中学到了我要说的话=> Updating UIs: value comparison VS mutation tracking。)

React和Vue跟踪何时更新UI的方式大不相同。

React使用对象不变性。这就是为什么每次setState都在创建一个全新的对象,并根据新的对象值重新渲染整个组件的原因。

Vue uses getters/setters on the data object for mutation tracking.执行this.key1 = 'value1';时,它将通过setter的{​​{1}}。在设置器中,有一个通知key1并将此数据更改添加到队列的功能。

  

如果您尚未注意到,Vue会执行DOM更新   异步地。每当观察到数据更改时,它将打开一个   排队并缓冲同一事件中发生的所有数据更改   环。如果同一观察者被多次触发,它将是   仅一次进入队列。这种缓冲的重复数据删除是   对于避免不必要的计算和DOM操作很重要。   https://vuejs.org/v2/guide/reactivity.html#Async-Update-Queue

因此,当您执行watcher时,它不会呈现两次。 Vue会自动将数据更改排队,然后稍后将它们重新呈现。

我的意思是,您不必担心这个问题。您无需担心Vue中的this.key1 = 'value1'; this.key2 = 'value2';。 React和Vue具有非常不同的反应系统。您可能想阅读上面的链接以获得更好的理解。

(顺便说一句,Vue现在使用getter / setter,但将来将使用JS代理。https://github.com/vuejs/roadmap

答案 1 :(得分:1)

使用$ set方法,您只能添加一个属性:

this.$set(this.existingObject, 'newProperty', 'value')

如果您需要添加多个反应性,请使用分配方法:

this.existingObject = Object.assign({}, this.existingObject, {
  newProperty1: 'value',
  newProperty2: 22
}

当您只想更改对象中的某些属性而不触摸其余属性时,这也很有用。所以:

this.existingObject = Object.assign({}, this.existingObject, {
  existingProperty2: 'newValue',
  existingProperty6: 66
}

如果您使用的是Babel,并且我认为您在两种情况下都进行了添加或修改一些道具的操作,则可以使用最新的传播功能:

let newOrExistingProps = {
  newProperty: 'value',
  existingProperty: 66
}

this.existingObject = {...this.existingObject, ...newOrExistingProps}

答案 2 :(得分:0)

Vuex商店:store.js

 export default new Vuex.Store({
  state: {
    numCorrect: 0, 
    numIncorrect: 0
  }, 
  mutations: {
    increment (state,payload) {
        state.numCorrect = payload.correct;
        state.numIncorrect = payload.incorrect;
      }
  }
});

Vue文件:hello.vue

import store from '../store/store'

  new Vue({
  el: '#app',
  methods: {
    updateText() {
      store.commit("increment", {correct:4,incorrect: 6 })
    }
  }
});