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

Jun*_* Oh 3 javascript reactjs vuejs2

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

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

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

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

this.setState(Object.assign({}, this.state, { key1: 'value1', key2 : 'value2'}))
Run Code Online (Sandbox Code Playgroud)

但是据我所知,

this.key1 = 'value1';
this.key2 = 'value2';
Run Code Online (Sandbox Code Playgroud)

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

我已经尝试过...

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

// not working
this.data = { key1 : 'value1', key2: 'value2' };
Run Code Online (Sandbox Code Playgroud)

在第二个中,数据已更改-我已使用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>
Run Code Online (Sandbox Code Playgroud)

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

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

随时随地

export default {
  data : function() {
    return {
      foo : 'bar'
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在反应

constructor() {
  super()
  this.state = {
    foo : 'bar'
  }
}
Run Code Online (Sandbox Code Playgroud)

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

Jac*_*Goh 5

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

(我从这篇很棒的文章=> 更新UI中了解了我要说的内容:值比较VS变异跟踪。)

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

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

Vue使用数据对象上的getter / setter进行突变跟踪。当您执行this.key1 = 'value1';,它会通过setterkey1。在设置器中,有一个函数来通知watcher并将这些数据更改添加到队列中。

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

因此,当您执行时this.key1 = 'value1'; this.key2 = 'value2';它不会呈现两次。Vue会自动将数据更改排队,并在以后将它们重新呈现在一起。

我的意思是,您不必担心这个问题。您无需set multi values at once在Vue中担心。React和Vue具有非常不同的反应系统。您可能想阅读上面的链接以获得更好的理解。

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


Vla*_*cky 5

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

this.$set(this.existingObject, 'newProperty', 'value')
Run Code Online (Sandbox Code Playgroud)

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

this.existingObject = Object.assign({}, this.existingObject, {
  newProperty1: 'value',
  newProperty2: 22
}
Run Code Online (Sandbox Code Playgroud)

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

this.existingObject = Object.assign({}, this.existingObject, {
  existingProperty2: 'newValue',
  existingProperty6: 66
}
Run Code Online (Sandbox Code Playgroud)

如果你正在使用 Babel,我假设你在这两种情况下都这样做了,添加或修改一些道具,你可以使用最新的传播功能:

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

this.existingObject = {...this.existingObject, ...newOrExistingProps}
Run Code Online (Sandbox Code Playgroud)