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

新手上路,请多包涵

我是 vue.js 的新手,但我以前对 React 有一些经验。

我已经阅读了 vue 指南,我正在尝试通过 React 的概念来理解 vue。

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

所以我想做一些类似的事情……(代码在 React 中)

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

但据我所知,在 vue 中:

 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>

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

react this.state 和 vue this.data 不一样,对吧?对我来说,主要的困惑是从那一点开始的。

在视图中

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

在反应

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

是完全不同的概念吧?

原文由 Juneyoung Oh 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 459
2 个回答

您对问题的关注是没有必要的。你不需要担心 Vue 中的 set multi values at once

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

当 UI 应该更新时,React 和 Vue 有非常不同的跟踪方式。

React 使用对象不变性。 这就是为什么每次你 setState 时,你实际上是在创建一个全新的对象,并且整个组件都基于新的对象值重新渲染。

Vue 在数据对象上使用 getters/setters 来进行突变跟踪。 当您执行 this.key1 = 'value1'; 时,它将通过 setterkey1 。在 setter 中,有一个函数可以通知 watcher 并将此数据更改添加到队列中。

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

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

我想说的是,你的顾虑是没有必要的。在 Vue 中,您无需担心 set multi values at once 。 React 和 Vue 具有非常不同的反应系统。您可能想通读上面的链接以获得更好的理解。

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

原文由 Jacob Goh 发布,翻译遵循 CC BY-SA 4.0 许可协议

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

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

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

 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}

原文由 Vladislav Ladicky 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题